-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(forge): add
compiler
subcommand (#7909)
* feat(forge): add solc subcommand and utilities * style: improve formatting in solc.rs file * fix: merge * add json compatible output * add basic tests * add basic tests * clean up * finish tests * add skip flag * add vyper for unit tests * move tests, pin compiler version, use forgetest! * update CI test location for target Python / Vyper * update foundry-compilers crate * Update crates/forge/bin/cmd/compiler.rs Co-authored-by: DaniPopes <[email protected]> * `compiler` command is sync, remove conditions on CI for Vyper / Python installs * is_jsonlines -> is_json --------- Co-authored-by: zerosnacks <[email protected]> Co-authored-by: zerosnacks <[email protected]> Co-authored-by: DaniPopes <[email protected]>
- Loading branch information
1 parent
3786b27
commit adb6aba
Showing
9 changed files
with
386 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
use clap::{ArgAction, Parser, Subcommand, ValueHint}; | ||
use eyre::Result; | ||
use foundry_compilers::Graph; | ||
use foundry_config::Config; | ||
use semver::Version; | ||
use std::{collections::BTreeMap, path::PathBuf}; | ||
|
||
/// CLI arguments for `forge compiler`. | ||
#[derive(Debug, Parser)] | ||
pub struct CompilerArgs { | ||
#[command(subcommand)] | ||
pub sub: CompilerSubcommands, | ||
} | ||
|
||
impl CompilerArgs { | ||
pub fn run(self) -> Result<()> { | ||
match self.sub { | ||
CompilerSubcommands::Resolve(args) => args.run(), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Subcommand)] | ||
pub enum CompilerSubcommands { | ||
/// Retrieves the resolved version(s) of the compiler within the project. | ||
#[command(visible_alias = "r")] | ||
Resolve(ResolveArgs), | ||
} | ||
|
||
/// CLI arguments for `forge compiler resolve`. | ||
#[derive(Debug, Parser)] | ||
pub struct ResolveArgs { | ||
/// The root directory | ||
#[arg(long, short, value_hint = ValueHint::DirPath, value_name = "PATH")] | ||
root: Option<PathBuf>, | ||
|
||
/// Skip files that match the given regex pattern. | ||
#[arg(long, short, value_name = "REGEX")] | ||
skip: Option<regex::Regex>, | ||
|
||
/// Verbosity of the output. | ||
/// | ||
/// Pass multiple times to increase the verbosity (e.g. -v, -vv, -vvv). | ||
/// | ||
/// Verbosity levels: | ||
/// - 2: Print source paths. | ||
#[arg(long, short, verbatim_doc_comment, action = ArgAction::Count, help_heading = "Display options")] | ||
pub verbosity: u8, | ||
|
||
/// Print as JSON. | ||
#[arg(long, short, help_heading = "Display options")] | ||
json: bool, | ||
} | ||
|
||
impl ResolveArgs { | ||
pub fn run(self) -> Result<()> { | ||
let Self { root, skip, verbosity, json } = self; | ||
|
||
let root = root.unwrap_or_else(|| PathBuf::from(".")); | ||
let config = Config::load_with_root(&root); | ||
let project = config.project()?; | ||
|
||
let graph = Graph::resolve(&project.paths)?; | ||
let (sources, _) = graph.into_sources_by_version( | ||
project.offline, | ||
&project.locked_versions, | ||
&project.compiler, | ||
)?; | ||
|
||
let mut output: BTreeMap<String, Vec<(Version, Vec<String>)>> = BTreeMap::new(); | ||
|
||
for (language, sources) in sources { | ||
let mut versions_with_paths: Vec<(Version, Vec<String>)> = sources | ||
.iter() | ||
.map(|(version, sources)| { | ||
let paths: Vec<String> = sources | ||
.iter() | ||
.filter_map(|(path_file, _)| { | ||
let path_str = path_file | ||
.strip_prefix(&project.paths.root) | ||
.unwrap_or(path_file) | ||
.to_path_buf() | ||
.display() | ||
.to_string(); | ||
|
||
// Skip files that match the given regex pattern. | ||
if let Some(ref regex) = skip { | ||
if regex.is_match(&path_str) { | ||
return None; | ||
} | ||
} | ||
|
||
Some(path_str) | ||
}) | ||
.collect(); | ||
|
||
(version.clone(), paths) | ||
}) | ||
.filter(|(_, paths)| !paths.is_empty()) | ||
.collect(); | ||
|
||
// Sort by SemVer version. | ||
versions_with_paths.sort_by(|(v1, _), (v2, _)| Version::cmp(v1, v2)); | ||
|
||
// Skip language if no paths are found after filtering. | ||
if !versions_with_paths.is_empty() { | ||
output.insert(language.to_string(), versions_with_paths); | ||
} | ||
} | ||
|
||
if json { | ||
println!("{}", serde_json::to_string(&output)?); | ||
return Ok(()); | ||
} | ||
|
||
for (language, versions) in &output { | ||
if verbosity < 1 { | ||
println!("{language}:"); | ||
} else { | ||
println!("{language}:\n"); | ||
} | ||
|
||
for (version, paths) in versions { | ||
if verbosity >= 1 { | ||
println!("{version}:"); | ||
for (idx, path) in paths.iter().enumerate() { | ||
if idx == paths.len() - 1 { | ||
println!("└── {path}\n"); | ||
} else { | ||
println!("├── {path}"); | ||
} | ||
} | ||
} else { | ||
println!("- {version}"); | ||
} | ||
} | ||
|
||
if verbosity < 1 { | ||
println!(); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.