vscode-solidity icon indicating copy to clipboard operation
vscode-solidity copied to clipboard

Foundry out of box support

Open chitalian opened this issue 3 years ago • 16 comments

Steps to reproduce

forge init solidity-tutorial
code .

in the test file image

references: https://chainstack.com/foundry-a-fast-solidity-contract-development-toolkit/

chitalian avatar Apr 07 '22 05:04 chitalian

I ran into the same problem today.

Workarounds

I found the following both work:

  • Open just the Foundry project (eg packages/contracts) in VS Code, instead of the monorepo. Not ideal.
  • Set "solidity.packageDefaultDependenciesDirectory": "packages/contracts/lib", "solidity.packageDefaultDependenciesContractsDirectory": "src".

Transitive dependencies are still broken. So forge-std works since it's in lib/forge-std, but ds-test does not work, since it's in lib/forge-std/lib/ds-test.

Real fix

I think we could solve for monorepos (foundry or otherwise) in one of a few ways.

One might be to add a "solidity root" setting. But this extension has a lot of knobs already, and the new user experience of trying to Google how to set them to make your project compile is not very pleasant.

An alternative would be to go in the direction of removing knobs. Is there a dependency resolution strategy that would reduce the need for packageDefaultDependencies... and remappings.txt?

If there's rough consensus on how to do this, I'm happy to contribute a PR.

dcposch avatar Jul 08 '22 06:07 dcposch

Hi anyone have updates on this?

0xdeployer avatar Sep 29 '22 20:09 0xdeployer

Just want to add a bit more context/another requirement: a monorepo may have more than one contracts directory/package (foundry project), and would be good to be able to resolve the package-local remappings.txt (rather than a global singleton config).

We're working with a large monorepo where two of the inner projects/packages are foundry projects (each with their own remapping.txt):

monorepo/
  packages/
    project-a/
      foundry.toml
      remappings.txt
    project-b/
      foundry.toml
      remappings.txt

frolic avatar Dec 21 '22 21:12 frolic

Just revisiting this again now that I have seen this from a couple of different angles.

When working in a monorepo that has hoisted dependencies (e.g. yarn), it was easy enough to override remappings globally (.vscode/settings.json) and map the imports to the monorepo root's node_modules.

However, in pnpm (most of my projects now) it's not possible to do this because each package has its own dependencies symlinked from a central pnpm store (which is where pnpm gets its speed). So it's impossible for me to do a monorepo-wide remapping for this plugin because each package should refer to its own node_modules rather than the monorepo root's node_modules.

I might be able to work around this for now by remapping to the central pnpm store, but that feels brittle because each package directory is named with its version number, so I'll have to be very careful to keep all versions of imported packages consistent.

And this probably doesn't help for e.g. forge installed libs (submodules within a project's lib dir).

@juanfranblanco Any idea how big a lift it would be to support the "nearest" remappings.txt rather than the workspace root?

frolic avatar Apr 12 '23 16:04 frolic

For a little more context, here's my workaround for a pnpm monorepo that uses only pnpm-managed dependencies (no foundry deps): https://github.com/latticexyz/mud/commit/f238f67834c2062fdaf672003e6466b6e33488a0

Confusingly, one dependency we use that isn't specified in these remappings still works fine out-of-the-box. Maybe because it's just used by one package and not multiple, so there's no remapping conflicts? https://github.com/latticexyz/mud/blob/main/packages/solecs/src/Ownable.sol#L4-L5

frolic avatar Apr 12 '23 16:04 frolic

@holic thank you, I'll have a look ! So your pmnp issue will be solved by using the nearest remapping file correct? As you are mainly using symlinks. The remappings file is the key for this as we need a common file to validate what is the start of a project, could be the foundry file with the remappings internally too.

juanfranblanco avatar Apr 13 '23 06:04 juanfranblanco

I believe "nearest remapping" will do the trick, yep! That should help with both the pnpm use case and with foundry libs, and still "bubble up" to the project root's remapping for compatibility with existing projects.

Ideally both remappings.txt and foundry.toml would be supported (unclear which would take precedence if both are found). I personally tend to use remappings.txt since I think it's more portable (not just a foundry thing)?

frolic avatar Apr 13 '23 06:04 frolic

I think the idea of having a common project file is not going to happen anytime, so remappings it is and specific framework type.

juanfranblanco avatar Apr 13 '23 06:04 juanfranblanco

solidity-multiroot-support some updates

juanfranblanco avatar Apr 13 '23 17:04 juanfranblanco

Awesome! Just saw the commit to main.

A few questions:

  • is this opt-in because it has to do a directory search and that can be slow to resolve?
  • how often does the search happen?
  • if a foundry.toml is encountered but that foundry.toml doesn't have remappings, does it fall back to remappings.txt? (we use both foundry.toml and remappings.txt in our projects)

frolic avatar Apr 13 '23 17:04 frolic

@holic i have added foundry remappings too, let me know how it goes. This has to be enabled as it might add confusion. Let me know how it goes.. it is out on 151

juanfranblanco avatar Apr 13 '23 17:04 juanfranblanco

@holic foundry takes preference over remappings if found, they are not merged, but they could be merged instead and have both. The opt-in is for users as i mentioned above, but yes they get searched all the time as it is going to be relative to the current document, I will need to add some optimization to search it only once when the current document does not change

juanfranblanco avatar Apr 13 '23 17:04 juanfranblanco

I'm not sure what you mean by "merging". I'm also not sure what foundry's default behavior is if you have them specified in both places, but I assume they pick one or the other.

Since remappings.txt is sort of single-use, I think the easiest solution would be to prioritize using that as source-of-truth if it exists and if not, fall back to remappings defined in various tool configs (foundry.toml, hardhad.config.js, etc.). Then you won't need to read both files to determine which to use or how to merge or whatever.

frolic avatar Apr 13 '23 17:04 frolic

Yes this is what is currently doing at the moment, so foundry if it has the remappings settings will take preference over the remappings.txt. And yes you are right better don't mess around with that, as it will create anti-patterns on projects. I guess best is to stick to one.

juanfranblanco avatar Apr 13 '23 18:04 juanfranblanco

Sounds great!

I just found this btw, which might help your file search: https://github.com/sindresorhus/find-up

const nearestFile = await findUp(projectFilesAtRoot);

frolic avatar Apr 13 '23 18:04 frolic

Oh I crafted my own :)

juanfranblanco avatar Apr 13 '23 21:04 juanfranblanco