diff --git a/cspell.json b/cspell.json index de712fb0a04..c7ad22afa96 100644 --- a/cspell.json +++ b/cspell.json @@ -93,6 +93,7 @@ "envrc", "EXPONENTIATE", "Flamegraph", + "flamegraphs", "flate", "fmtstr", "foldl", @@ -120,6 +121,7 @@ "impls", "indexmap", "injective", + "interners", "Inlines", "instrumenter", "interner", @@ -227,6 +229,7 @@ "tempdir", "tempfile", "termcolor", + "termion", "thiserror", "tslog", "turbofish", diff --git a/tooling/lsp/src/lib.rs b/tooling/lsp/src/lib.rs index f8a4bd6b74a..c722bfdfd3e 100644 --- a/tooling/lsp/src/lib.rs +++ b/tooling/lsp/src/lib.rs @@ -316,6 +316,7 @@ pub(crate) fn resolve_workspace_for_source_path(file_path: &Path) -> Result, pub members: Vec, // If `Some()`, the `selected_package_index` is used to select the only `Package` when iterating a Workspace pub selected_package_index: Option, @@ -34,7 +36,7 @@ impl Workspace { } pub fn target_directory_path(&self) -> PathBuf { - self.root_dir.join(TARGET_DIR) + self.target_dir.as_ref().cloned().unwrap_or_else(|| self.root_dir.join(TARGET_DIR)) } pub fn export_directory_path(&self) -> PathBuf { diff --git a/tooling/nargo_cli/benches/criterion.rs b/tooling/nargo_cli/benches/criterion.rs index e43e498ea06..0722e957833 100644 --- a/tooling/nargo_cli/benches/criterion.rs +++ b/tooling/nargo_cli/benches/criterion.rs @@ -156,7 +156,7 @@ fn criterion_test_execution(c: &mut Criterion, test_program_dir: &Path, force_br }); } -/// Go through all the selected tests and executem with and without Brillig. +/// Go through all the selected tests and execute them with and without Brillig. fn criterion_selected_tests_execution(c: &mut Criterion) { for test_program_dir in get_selected_tests() { for force_brillig in [false, true] { diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index efc6a351e33..1d59fdb806f 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -56,8 +56,12 @@ struct NargoCli { #[derive(Args, Clone, Debug)] pub(crate) struct NargoConfig { // REMINDER: Also change this flag in the LSP test lens if renamed - #[arg(long, hide = true, global = true, default_value = "./")] + #[arg(long, hide = true, global = true, default_value = "./", value_parser = parse_path)] program_dir: PathBuf, + + /// Override the default target directory. + #[arg(long, hide = true, global = true, value_parser = parse_path)] + target_dir: Option, } /// Options for commands that work on either workspace or package scope. @@ -130,14 +134,7 @@ enum LockType { #[cfg(not(feature = "codegen-docs"))] #[tracing::instrument(level = "trace")] pub(crate) fn start_cli() -> eyre::Result<()> { - use fm::NormalizePath; - - let NargoCli { command, mut config } = NargoCli::parse(); - - // If the provided `program_dir` is relative, make it absolute by joining it to the current directory. - if !config.program_dir.is_absolute() { - config.program_dir = std::env::current_dir().unwrap().join(config.program_dir).normalize(); - } + let NargoCli { command, config } = NargoCli::parse(); match command { NargoCommand::New(args) => new_cmd::run(args, config), @@ -194,14 +191,17 @@ where // or a specific package; if that's the case then parse the package name to select it in the workspace. let selection = match cmd.package_selection() { PackageSelection::DefaultOrAll if workspace_dir != package_dir => { - let workspace = read_workspace(&package_dir, PackageSelection::DefaultOrAll)?; - let package = workspace.into_iter().next().expect("there should be exactly 1 package"); + let package = read_workspace(&package_dir, PackageSelection::DefaultOrAll)?; + let package = package.into_iter().next().expect("there should be exactly 1 package"); PackageSelection::Selected(package.name.clone()) } other => other, }; // Parse the top level workspace with the member selected. - let workspace = read_workspace(&workspace_dir, selection)?; + let mut workspace = read_workspace(&workspace_dir, selection)?; + // Optionally override the target directory. It's only done here because most commands like the LSP and DAP + // don't read or write artifacts, so they don't use the target directory. + workspace.target_dir = config.target_dir.clone(); // Lock manifests if the command needs it. let _locks = match cmd.lock_type() { LockType::None => None, @@ -249,13 +249,25 @@ fn lock_workspace(workspace: &Workspace, exclusive: bool) -> Result Result { + use fm::NormalizePath; + let mut path: PathBuf = path.parse().map_err(|e| format!("failed to parse path: {e}"))?; + if !path.is_absolute() { + path = std::env::current_dir().unwrap().join(path).normalize(); + } + Ok(path) +} + #[cfg(test)] mod tests { + use super::NargoCli; use clap::Parser; + #[test] fn test_parse_invalid_expression_width() { let cmd = "nargo --program-dir . compile --expression-width 1"; - let res = super::NargoCli::try_parse_from(cmd.split_ascii_whitespace()); + let res = NargoCli::try_parse_from(cmd.split_ascii_whitespace()); let err = res.expect_err("should fail because of invalid width"); assert!(err.to_string().contains("expression-width")); @@ -263,4 +275,18 @@ mod tests { .to_string() .contains(acvm::compiler::MIN_EXPRESSION_WIDTH.to_string().as_str())); } + + #[test] + fn test_parse_target_dir() { + let cmd = "nargo --program-dir . --target-dir ../foo/bar execute"; + let cli = NargoCli::try_parse_from(cmd.split_ascii_whitespace()).expect("should parse"); + + let target_dir = cli.config.target_dir.expect("should parse target dir"); + assert!(target_dir.is_absolute(), "should be made absolute"); + assert!(target_dir.ends_with("foo/bar")); + + let cmd = "nargo --program-dir . execute"; + let cli = NargoCli::try_parse_from(cmd.split_ascii_whitespace()).expect("should parse"); + assert!(cli.config.target_dir.is_none()); + } } diff --git a/tooling/nargo_toml/src/lib.rs b/tooling/nargo_toml/src/lib.rs index 59bee569430..edf26411cf5 100644 --- a/tooling/nargo_toml/src/lib.rs +++ b/tooling/nargo_toml/src/lib.rs @@ -396,6 +396,7 @@ fn toml_to_workspace( selected_package_index: Some(0), members: vec![member], is_assumed: false, + target_dir: None, }, } } @@ -448,6 +449,7 @@ fn toml_to_workspace( members, selected_package_index, is_assumed: false, + target_dir: None, } } }; @@ -514,6 +516,8 @@ pub enum PackageSelection { } /// Resolves a Nargo.toml file into a `Workspace` struct as defined by our `nargo` core. +/// +/// As a side effect it downloads project dependencies as well. pub fn resolve_workspace_from_toml( toml_path: &Path, package_selection: PackageSelection, @@ -521,7 +525,6 @@ pub fn resolve_workspace_from_toml( ) -> Result { let nargo_toml = read_toml(toml_path)?; let workspace = toml_to_workspace(nargo_toml, package_selection)?; - if let Some(current_compiler_version) = current_compiler_version { semver::semver_check_workspace(&workspace, current_compiler_version)?; }