Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remapping contexts #5397

Merged
merged 10 commits into from
Jul 17, 2023
Merged

feat: remapping contexts #5397

merged 10 commits into from
Jul 17, 2023

Conversation

onbjerg
Copy link
Member

@onbjerg onbjerg commented Jul 14, 2023

Motivation

Dependencies in projects using Foundry can mess with how imports are resolved through the project because remappings from dependencies are just merged with remappings defined in the root folder.

To solve this, we make use of solc's remapping contexts.

Solution

This PR adds support for specifying remapping contexts if necessary, but ideally it should never be. Instead, this PR also automatically scopes each remapping defined in dependencies to files in the dependency itself.

Global remappings (context: None) are still automatically generated for each installed dependency, making it possible to import them as usual.

This PR in other words just makes the following user-facing change: remappings defined in dependencies/libraries can no longer override remappings defined in foundry.toml/remappings.txt, and it should no longer be necessary to copy over remappings from dependencies to foundry.toml/remappings.txt for dependencies with weird remappings.

This PR also adds a --pretty flag to forge remappings that groups remappings by context. Global remappings apply to every file (including dependencies), and remappings with a context only apply to the paths defined by the context. The default is to not pretty print since a common use case of forge remappings is to pipe the output to a file or other command.

Todo

  • Add tests
  • Merge ethers PR
  • Remove patch

Closes #3440, closes #1855

Depends on gakonst/ethers-rs#2509

@onbjerg onbjerg changed the title Onbjerg/remapping context feat: remapping contexts Jul 14, 2023
@onbjerg onbjerg added T-feature Type: feature C-forge Command: forge Cmd-forge-build Command: forge build labels Jul 14, 2023
@onbjerg onbjerg marked this pull request as ready for review July 15, 2023 01:03
@Evalir Evalir requested review from mattsse and Evalir July 15, 2023 01:27
@gakonst
Copy link
Member

gakonst commented Jul 15, 2023

Ethers 2.0.8 is out with the fix.

@aathan
Copy link
Contributor

aathan commented Jul 17, 2023

Some comments/questions:
(1) How does this actually operate? are the remappings loaded from dependencies internally contextualized (with context:) for a given forge run, or are you re-writing the remappings files written to the lib/ projects when those are deposited? I assume the former.
(2) is there an opinion as to whether there should be an option to also scope the top level/global remappings so that they can optionally only apply to the "main" project files, and never to any libs that may have some import that happens to match? E.g., is it possible for a dependent project to itself depend on the same other project you also depend on, and in that case, could the global remappings end up affecting the dependency's imports?
(3) does someone know definitively, to tell me, whether the way solc resolves type names may cause structs of the same name, declared at the file-scope in various dependencies and/or the root project, to collide? If the solc devs need a poke about that, I can go open a feature request.

Copy link
Member

@Evalir Evalir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this seems to work well, and considering this will fix master i'm leaning to merging soon—some comments:

}
impl_figment_convert_basic!(RemappingArgs);

impl Cmd for RemappingArgs {
type Output = ();

// TODO: Do people use `forge remappings >> file`?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are we planning to test this? Wasn't this what you tweeted the other day?

@@ -83,11 +90,13 @@ impl<'a> RemappingsProvider<'a> {
new_remappings.extend(remappings);

// scan all library dirs and autodetect remappings
// todo: if a lib specifies contexts for remappings manually, we need to figure out how to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we plan to do this now or later?

.into_iter()
.map(Remapping::from)
.map(|mut r| {
// todo: windows/mac/linux
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😄

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool, this looks less invasive than I expected, and since context is optional, this should work as before

smol nit re deps, otherwise lgtm

Cargo.toml Outdated
Comment on lines 64 to 73
ethers = { version = "2.0.8", default-features = false }
ethers-addressbook = { version = "2.0.8", default-features = false }
ethers-core = { version = "2.0.8", default-features = false }
ethers-contract = { version = "2.0.8", default-features = false }
ethers-contract-abigen = { version = "2.0.8", default-features = false }
ethers-providers = { version = "2.0.8", default-features = false }
ethers-signers = { version = "2.0.8", default-features = false }
ethers-middleware = { version = "2.0.8", default-features = false }
ethers-etherscan = { version = "2.0.8", default-features = false }
ethers-solc = { version = "2.0.8", default-features = false }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now this is on ethers master, we should continue using git deps

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in d92bd23 — we can switch to master deps whenever we plan on publishing crates 😄

}
impl_figment_convert_basic!(RemappingArgs);

impl Cmd for RemappingArgs {
type Output = ();

// TODO: Do people use `forge remappings >> file`?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they definitely do,
I also used this a few times at least

match mappings.entry(key) {
/// grouped by remapping context
fn insert_closest(
mappings: &mut HashMap<Option<String>, HashMap<String, PathBuf>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should work,
so the previous hashmap is now just the None key

and this also supports remappings with context extracted from nested deps

@Evalir Evalir merged commit 8e365be into master Jul 17, 2023
@Evalir Evalir deleted the onbjerg/remapping-context branch July 17, 2023 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-forge Command: forge Cmd-forge-build Command: forge build T-feature Type: feature
Projects
None yet
5 participants