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(build): add option to build specific dir #8149

Merged
merged 3 commits into from
Jun 14, 2024

Conversation

grandizzy
Copy link
Collaborator

@grandizzy grandizzy commented Jun 13, 2024

Motivation

Closes #8071

Not too familiar with build but at a quick look seemed to be a low hanging fruit with big impact for other tools integration, so here it is, hope it makes sense 😄

  • Adds capabilities to build specific directories and file (no toml config) by specifying --paths switch to forge build e.g.
forge build --paths test/regressions/ test/invariant/Invariant.sol
  • builds child dirs within specified dirs
  • works in conjunction with --skip as well

Solution

@grandizzy grandizzy requested a review from klkvr June 13, 2024 10:03
@grandizzy grandizzy marked this pull request as ready for review June 13, 2024 10:03
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.

iirc a lot of folks are also requesting this, and this actually looks simple to add. because this is opt-in I belive this is fine

ptal @klkvr

Comment on lines 85 to 96
let mut files = vec![];
if let Some(dirs) = self.args.dirs {
for dir in dirs {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_file() {
files.push(entry.path());
}
}
}
}
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

@klkvr klkvr Jun 13, 2024

Choose a reason for hiding this comment

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

Right, similarly to this

test_sources.extend(source_files_iter(
project.paths.sources,
MultiCompilerLanguage::FILE_EXTENSIONS,
));

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

nice, changed it in 6da9a55

/// Child directories are not accounted and should be explicitly added.
#[arg(long, num_args(1..))]
#[serde(skip)]
pub dirs: Option<Vec<PathBuf>>,
Copy link
Member

Choose a reason for hiding this comment

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

should we also support individual files?
maybe we do files:?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, since now it supports single files I renamed it to paths

@DaniPopes
Copy link
Member

DaniPopes commented Jun 13, 2024

Can't we just pass these as a list of 0.. positional arguments?

@klkvr
Copy link
Member

klkvr commented Jun 13, 2024

perhaps we also want a config key for this? similar to skip from #8061

- use source_files_iter helper, build single files and child dirs as well
- rename arg to paths, use 0.. pos arg
@grandizzy
Copy link
Collaborator Author

Can't we just pass these as a list of 0.. positional arguments?

hope I get this comment right, pls check 6da9a55#diff-f3c6bdb4ebdb62f63412254e4c9154aff947fc45daf6aaff880aaf6470182d8aR129-R132

@grandizzy
Copy link
Collaborator Author

grandizzy commented Jun 13, 2024

perhaps we also want a config key for this? similar to skip from #8061

I think that would be cool, a difference from skip is that the arg is named paths in BuildArgs but probably the config key should be meaningful named build-paths? Also not sure but would this imply a change in MultiCompiler, I could be wrong but does forge build command uses only solc compiler?

LE: on a 2nd thought, since this cannot be shared with other commands and kind of valid only in build context, do we want to move it as a config key?

@klkvr
Copy link
Member

klkvr commented Jun 13, 2024

I think that would be cool, a difference from skip is that the arg is named paths in BuildArgs but probably the config key should be meaningful named build-paths? Also not sure but would this imply a change in MultiCompiler, I could be wrong but does forge build command uses only solc compiler?

This wouldn't require a change in compilers, should be doable by only using sparse output filters

LE: on a 2nd thought, since this cannot be shared with other commands and kind of valid only in build context, do we want to move it as a config key?

yeah I meant making it valid in all context if specified in config. Since #8061 we respect skip for all context by converting it into sparse output filter directly in Config::create_project:

if !self.skip.is_empty() {
let filter = SkipBuildFilters::new(self.skip.clone(), self.root.0.clone());
builder = builder.sparse_output(filter);

@grandizzy
Copy link
Collaborator Author

yeah I meant making it valid in all context if specified in config. Since #8061 we respect skip for all context by converting it into sparse output filter directly in Config::create_project:

if !self.skip.is_empty() {
let filter = SkipBuildFilters::new(self.skip.clone(), self.root.0.clone());
builder = builder.sparse_output(filter);

I think I got it now, but wouldn't this be an issue with the sparse output filter when we want to include files (instead excluding them?
Let's say I specify file test/Bar.sol is Test as path to build, then I create a FileFilter and implement is_match function that would return true if test/Bar.sol is a match (but false for Test), is there a way to figure out all other deps to build (as rn I don't see the test.sol generated in out dir, while for forge build --paths test/Bar.sol I get them both)

@klkvr
Copy link
Member

klkvr commented Jun 13, 2024

I think I got it now, but wouldn't this be an issue with the sparse output filter when we want to include files (instead excluding them?
Let's say I specify file test/Bar.sol is Test as path to build, then I create a FileFilter and implement is_match function that would return true if test/Bar.sol is a match (but false for Test), is there a way to figure out all other deps to build (as rn I don't see the test.sol generated in out dir, while for forge build --paths test/Bar.sol I get them both)

Right, the way sparse output works is that it only requests artifacts for matched sources, excluding everything else. Such approach reduces compile time but might be a bit unexpected if people are expecting artifacts for imported sources to also be produced.

However another issue is if we approach this by just using sparse output filters then this wouldn't give users a way to compile files which are not under src/ as they won't be included into input sources set.

Let's keep the config option for a future follow-up

@@ -18,6 +18,9 @@ use watchexec::config::{InitConfig, RuntimeConfig};

foundry_config::merge_impl_figment_convert!(BuildArgs, args);

// Extensions accepted by `forge build`
const BUILD_EXTENSIONS: &[&str] = &["sol", "yul", "vy", "vyi"];
Copy link
Member

@klkvr klkvr Jun 13, 2024

Choose a reason for hiding this comment

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

can we use MultiCompilerLanguage::FILE_EXTENSIONS here? It would require including Language trait from compilers

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yep, changed in 0e71ca5

@klkvr klkvr merged commit c2e5297 into foundry-rs:master Jun 14, 2024
19 checks passed
@klkvr
Copy link
Member

klkvr commented Jun 14, 2024

Can't we just pass these as a list of 0.. positional arguments?

hope I get this comment right, pls check 6da9a55#diff-f3c6bdb4ebdb62f63412254e4c9154aff947fc45daf6aaff880aaf6470182d8aR129-R132
#8158

@grandizzy sorry missed this, I think Dani meant changing it to positional args to allow forge build file.sol commands. Created small follow-up #8158, just moves paths to BuildArgs basically

@grandizzy
Copy link
Collaborator Author

Can't we just pass these as a list of 0.. positional arguments?

hope I get this comment right, pls check 6da9a55#diff-f3c6bdb4ebdb62f63412254e4c9154aff947fc45daf6aaff880aaf6470182d8aR129-R132
#8158

@grandizzy sorry missed this, I think Dani meant changing it to positional args to allow forge build file.sol commands. Created small follow-up #8158, just moves paths to BuildArgs basically

Ah, I see, thank you for following up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compile a subdirectory
4 participants