From 4fe39e88c29e879ecc8a3a3cb291fcf8e26c0c6d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 15 Jun 2023 12:04:26 -0500 Subject: [PATCH 1/6] refactor(embedded): Be accurate in variable name --- src/cargo/util/toml/embedded.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cargo/util/toml/embedded.rs b/src/cargo/util/toml/embedded.rs index 2200c53f5da..c61cb66e468 100644 --- a/src/cargo/util/toml/embedded.rs +++ b/src/cargo/util/toml/embedded.rs @@ -75,12 +75,12 @@ fn write( let hash = hash(script).to_string(); assert_eq!(hash.len(), 64); - let file_name = script + let file_stem = script .path .file_stem() .ok_or_else(|| anyhow::format_err!("no file name"))? .to_string_lossy(); - let name = sanitize_name(file_name.as_ref()); + let name = sanitize_name(file_stem.as_ref()); let mut workspace_root = target_dir.to_owned(); workspace_root.push("eval"); @@ -135,12 +135,12 @@ fn expand_manifest_(script: &RawScript, config: &Config) -> CargoResult Date: Tue, 13 Jun 2023 12:17:20 -0500 Subject: [PATCH 2/6] fix(toml)!: Prevent people parsing manifests from strings --- src/cargo/util/toml/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index a9bcb46926e..386c8872291 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -70,7 +70,7 @@ pub fn read_manifest( /// within the manifest. For virtual manifests, these paths can only /// come from patched or replaced dependencies. These paths are not /// canonicalized. -pub fn read_manifest_from_str( +fn read_manifest_from_str( contents: &str, manifest_file: &Path, source_id: SourceId, From 2c70983e8db088332e2ae61fcf1afe3fdbf74ba0 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 14 Jun 2023 12:14:00 -0500 Subject: [PATCH 3/6] test(embedded): Verify no autobin behavior is running --- tests/testsuite/script.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index 8e131b293df..690fd13ec0b 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -508,3 +508,32 @@ fn main() { ) .run(); } + +#[cargo_test] +fn test_no_autobins() { + let script = r#"#!/usr/bin/env cargo + +fn main() { + println!("Hello world!"); +}"#; + let p = cargo_test_support::project() + .file("script.rs", script) + .file("src/bin/not-script/main.rs", "fn main() {}") + .build(); + + p.cargo("-Zscript script.rs --help") + .masquerade_as_nightly_cargo(&["script"]) + .with_stdout( + r#"Hello world! +"#, + ) + .with_stderr( + "\ +[WARNING] `package.edition` is unspecifiead, defaulting to `2021` +[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s +[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] --help` +", + ) + .run(); +} From 575b9ac9348dac43ae79f2aac1d8d57574695531 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 13 Jun 2023 12:38:07 -0500 Subject: [PATCH 4/6] fix(embedded): Don't create an intermediate manifest To parse the manifest, we have to write it out so our regular manifest loading code could handle it. This updates the manifest parsing code to handle it. This doesn't mean this will work everywhere in all cases though. For example, ephemeral workspaces parses a manifest from the SourceId and these won't have valid SourceIds. As a consequence, `Cargo.lock` and `CARGO_TARGET_DIR` are changing from being next to the temp manifest to being next to the script. This still isn't the desired behavior but stepping stones. This also exposes the fact that we didn't disable `autobins` like the documentation says we should. --- Cargo.lock | 35 +---- Cargo.toml | 2 - deny.toml | 1 - src/bin/cargo/commands/run.rs | 7 +- src/cargo/core/manifest.rs | 6 + src/cargo/core/workspace.rs | 11 ++ src/cargo/ops/cargo_package.rs | 2 +- src/cargo/util/toml/embedded.rs | 221 +++++--------------------------- src/cargo/util/toml/mod.rs | 26 +++- tests/testsuite/script.rs | 82 ++++++------ 10 files changed, 115 insertions(+), 278 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e90f95b99be..d685eff8256 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,24 +99,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - [[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "arrayvec" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" - [[package]] name = "atty" version = "0.2.14" @@ -199,20 +187,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "blake3" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b71f35bd3fa1a4c86b85d32c8b9069ea7fe14f7a53cfabb65f62d4265b888" -dependencies = [ - "arrayref", - "arrayvec 0.7.3", - "cc", - "cfg-if", - "constant_time_eq", - "digest", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -292,7 +266,6 @@ version = "0.73.0" dependencies = [ "anyhow", "base64", - "blake3", "bytesize", "cargo-platform 0.1.3", "cargo-test-macro", @@ -555,12 +528,6 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -[[package]] -name = "constant_time_eq" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" - [[package]] name = "content_inspector" version = "0.2.4" @@ -3513,7 +3480,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" dependencies = [ - "arrayvec 0.5.2", + "arrayvec", "utf8parse", "vte_generate_state_changes", ] diff --git a/Cargo.toml b/Cargo.toml index d6d7e76d669..e927c43530a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ exclude = [ [workspace.dependencies] anyhow = "1.0.47" base64 = "0.21.0" -blake3 = "1.3.3" bytesize = "1.0" cargo = { path = "" } cargo-credential = { version = "0.2.0", path = "credential/cargo-credential" } @@ -115,7 +114,6 @@ path = "src/cargo/lib.rs" [dependencies] anyhow.workspace = true base64.workspace = true -blake3.workspace = true bytesize.workspace = true cargo-platform.workspace = true cargo-util.workspace = true diff --git a/deny.toml b/deny.toml index 71d74cb5b8a..89d08eacc8f 100644 --- a/deny.toml +++ b/deny.toml @@ -106,7 +106,6 @@ allow = [ "MIT-0", "Apache-2.0", "BSD-3-Clause", - "BSD-2-Clause", "MPL-2.0", "Unicode-DFS-2016", "CC0-1.0", diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index ce9f6d0d87b..45521b5f05f 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -5,6 +5,7 @@ use std::path::Path; use crate::command_prelude::*; use crate::util::restricted_names::is_glob_pattern; use cargo::core::Verbosity; +use cargo::core::Workspace; use cargo::ops::{self, CompileFilter, Packages}; use cargo_util::ProcessError; @@ -101,8 +102,10 @@ pub fn exec_manifest_command(config: &Config, cmd: &str, args: &[OsString]) -> C ); } let manifest_path = crate::util::try_canonicalize(manifest_path)?; - let script = cargo::util::toml::embedded::parse_from(&manifest_path)?; - let ws = cargo::util::toml::embedded::to_workspace(&script, config)?; + let mut ws = Workspace::new(&manifest_path, config)?; + if config.cli_unstable().avoid_dev_deps { + ws.set_require_optional_deps(false); + } let mut compile_opts = cargo::ops::CompileOptions::new(config, cargo::core::compiler::CompileMode::Build)?; diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 98498ead884..5d46a7e06fa 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -64,6 +64,7 @@ pub struct Manifest { metabuild: Option>, resolve_behavior: Option, lint_rustflags: Vec, + embedded: bool, } /// When parsing `Cargo.toml`, some warnings should silenced @@ -407,6 +408,7 @@ impl Manifest { metabuild: Option>, resolve_behavior: Option, lint_rustflags: Vec, + embedded: bool, ) -> Manifest { Manifest { summary, @@ -433,6 +435,7 @@ impl Manifest { metabuild, resolve_behavior, lint_rustflags, + embedded, } } @@ -500,6 +503,9 @@ impl Manifest { pub fn links(&self) -> Option<&str> { self.links.as_deref() } + pub fn is_embedded(&self) -> bool { + self.embedded + } pub fn workspace_config(&self) -> &WorkspaceConfig { &self.workspace diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index 702c1929a69..7f7114131fe 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -726,6 +726,10 @@ impl<'cfg> Workspace<'cfg> { if self.members.contains(&manifest_path) { return Ok(()); } + if is_path_dep && self.root_maybe().is_embedded() { + // Embedded manifests cannot have workspace members + return Ok(()); + } if is_path_dep && !manifest_path.parent().unwrap().starts_with(self.root()) && self.find_root(&manifest_path)? != self.root_manifest @@ -1580,6 +1584,13 @@ impl MaybePackage { MaybePackage::Virtual(ref vm) => vm.workspace_config(), } } + + fn is_embedded(&self) -> bool { + match self { + MaybePackage::Package(p) => p.manifest().is_embedded(), + MaybePackage::Virtual(_) => false, + } + } } impl WorkspaceRootConfig { diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index fdd43d2ced4..a322afbb341 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -393,7 +393,7 @@ fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult { let package_root = orig_pkg.root(); let source_id = orig_pkg.package_id().source_id(); let (manifest, _nested_paths) = - TomlManifest::to_real_manifest(&toml_manifest, source_id, package_root, config)?; + TomlManifest::to_real_manifest(&toml_manifest, false, source_id, package_root, config)?; let new_pkg = Package::new(manifest, orig_pkg.manifest_path()); // Regenerate Cargo.lock using the old one as a guide. diff --git a/src/cargo/util/toml/embedded.rs b/src/cargo/util/toml/embedded.rs index c61cb66e468..c86beaad759 100644 --- a/src/cargo/util/toml/embedded.rs +++ b/src/cargo/util/toml/embedded.rs @@ -1,6 +1,5 @@ use anyhow::Context as _; -use crate::core::Workspace; use crate::util::restricted_names; use crate::CargoResult; use crate::Config; @@ -10,21 +9,13 @@ const DEFAULT_EDITION: crate::core::features::Edition = const DEFAULT_VERSION: &str = "0.0.0"; const DEFAULT_PUBLISH: bool = false; -pub struct RawScript { - manifest: String, - body: String, - path: std::path::PathBuf, -} - -pub fn parse_from(path: &std::path::Path) -> CargoResult { - let body = std::fs::read_to_string(path) - .with_context(|| format!("failed to script at {}", path.display()))?; - parse(&body, path) -} - -fn parse(body: &str, path: &std::path::Path) -> CargoResult { - let comment = match extract_comment(body) { - Ok(manifest) => Some(manifest), +pub fn expand_manifest( + content: &str, + path: &std::path::Path, + config: &Config, +) -> CargoResult { + let comment = match extract_comment(content) { + Ok(comment) => Some(comment), Err(err) => { log::trace!("failed to extract doc comment: {err}"); None @@ -39,82 +30,18 @@ fn parse(body: &str, path: &std::path::Path) -> CargoResult { } } .unwrap_or_default(); - let body = body.to_owned(); - let path = path.to_owned(); - Ok(RawScript { - manifest, - body, - path, - }) -} - -pub fn to_workspace<'cfg>( - script: &RawScript, - config: &'cfg Config, -) -> CargoResult> { - let target_dir = config - .target_dir() - .transpose() - .unwrap_or_else(|| default_target_dir().map(crate::util::Filesystem::new))?; - // HACK: without cargo knowing about embedded manifests, the only way to create a - // `Workspace` is either - // - Create a temporary one on disk - // - Create an "ephemeral" workspace **but** compilation re-loads ephemeral workspaces - // from the registry rather than what we already have on memory, causing it to fail - // because the registry doesn't know about embedded manifests. - let manifest_path = write(script, config, target_dir.as_path_unlocked())?; - let workspace = Workspace::new(&manifest_path, config)?; - Ok(workspace) -} - -fn write( - script: &RawScript, - config: &Config, - target_dir: &std::path::Path, -) -> CargoResult { - let hash = hash(script).to_string(); - assert_eq!(hash.len(), 64); - - let file_stem = script - .path - .file_stem() - .ok_or_else(|| anyhow::format_err!("no file name"))? - .to_string_lossy(); - let name = sanitize_name(file_stem.as_ref()); - - let mut workspace_root = target_dir.to_owned(); - workspace_root.push("eval"); - workspace_root.push(&hash[0..2]); - workspace_root.push(&hash[2..4]); - workspace_root.push(&hash[4..]); - workspace_root.push(name); - std::fs::create_dir_all(&workspace_root).with_context(|| { - format!( - "failed to create temporary workspace at {}", - workspace_root.display() - ) - })?; - let manifest_path = workspace_root.join("Cargo.toml"); - let manifest = expand_manifest(script, config)?; - write_if_changed(&manifest_path, &manifest)?; - Ok(manifest_path) -} - -fn expand_manifest(script: &RawScript, config: &Config) -> CargoResult { - let manifest = expand_manifest_(script, config) - .with_context(|| format!("failed to parse manifest at {}", script.path.display()))?; - let manifest = remap_paths( - manifest, - script.path.parent().ok_or_else(|| { - anyhow::format_err!("no parent directory for {}", script.path.display()) - })?, - )?; + let manifest = expand_manifest_(&manifest, path, config) + .with_context(|| format!("failed to parse manifest at {}", path.display()))?; let manifest = toml::to_string_pretty(&manifest)?; Ok(manifest) } -fn expand_manifest_(script: &RawScript, config: &Config) -> CargoResult { - let mut manifest: toml::Table = toml::from_str(&script.manifest)?; +fn expand_manifest_( + manifest: &str, + path: &std::path::Path, + config: &Config, +) -> CargoResult { + let mut manifest: toml::Table = toml::from_str(&manifest)?; for key in ["workspace", "lib", "bin", "example", "test", "bench"] { if manifest.contains_key(key) { @@ -135,8 +62,11 @@ fn expand_manifest_(script: &RawScript, config: &Config) -> CargoResult CargoResult String { name } -fn hash(script: &RawScript) -> blake3::Hash { - blake3::hash(script.body.as_bytes()) -} - -fn default_target_dir() -> CargoResult { - let mut cargo_home = home::cargo_home()?; - cargo_home.push("eval"); - cargo_home.push("target"); - Ok(cargo_home) -} - -fn write_if_changed(path: &std::path::Path, new: &str) -> CargoResult<()> { - let write_needed = match std::fs::read_to_string(path) { - Ok(current) => current != new, - Err(_) => true, - }; - if write_needed { - std::fs::write(path, new).with_context(|| format!("failed to write {}", path.display()))?; - } - Ok(()) -} - /// Locates a "code block manifest" in Rust source. fn extract_comment(input: &str) -> CargoResult { let re_crate_comment = regex::Regex::new( @@ -444,10 +346,12 @@ mod test_expand { macro_rules! si { ($i:expr) => {{ - let script = parse($i, std::path::Path::new("/home/me/test.rs")) - .unwrap_or_else(|err| panic!("{}", err)); - expand_manifest(&script, &Config::default().unwrap()) - .unwrap_or_else(|err| panic!("{}", err)) + expand_manifest( + $i, + std::path::Path::new("/home/me/test.rs"), + &Config::default().unwrap(), + ) + .unwrap_or_else(|err| panic!("{}", err)) }}; } @@ -456,7 +360,7 @@ mod test_expand { snapbox::assert_eq( r#"[[bin]] name = "test-" -path = "/home/me/test.rs" +path = "test.rs" [package] edition = "2021" @@ -478,7 +382,7 @@ strip = true snapbox::assert_eq( r#"[[bin]] name = "test-" -path = "/home/me/test.rs" +path = "test.rs" [dependencies] time = "0.1.25" @@ -699,73 +603,6 @@ fn main() {} } } -/// Given a Cargo manifest, attempts to rewrite relative file paths to absolute ones, allowing the manifest to be relocated. -fn remap_paths( - mani: toml::Table, - package_root: &std::path::Path, -) -> anyhow::Result { - // Values that need to be rewritten: - let paths: &[&[&str]] = &[ - &["build-dependencies", "*", "path"], - &["dependencies", "*", "path"], - &["dev-dependencies", "*", "path"], - &["package", "build"], - &["target", "*", "dependencies", "*", "path"], - ]; - - let mut mani = toml::Value::Table(mani); - - for path in paths { - iterate_toml_mut_path(&mut mani, path, &mut |v| { - if let toml::Value::String(s) = v { - if std::path::Path::new(s).is_relative() { - let p = package_root.join(&*s); - if let Some(p) = p.to_str() { - *s = p.into() - } - } - } - Ok(()) - })? - } - - match mani { - toml::Value::Table(mani) => Ok(mani), - _ => unreachable!(), - } -} - -/// Iterates over the specified TOML values via a path specification. -fn iterate_toml_mut_path( - base: &mut toml::Value, - path: &[&str], - on_each: &mut F, -) -> anyhow::Result<()> -where - F: FnMut(&mut toml::Value) -> anyhow::Result<()>, -{ - if path.is_empty() { - return on_each(base); - } - - let cur = path[0]; - let tail = &path[1..]; - - if cur == "*" { - if let toml::Value::Table(tab) = base { - for (_, v) in tab { - iterate_toml_mut_path(v, tail, on_each)?; - } - } - } else if let toml::Value::Table(tab) = base { - if let Some(v) = tab.get_mut(cur) { - iterate_toml_mut_path(v, tail, on_each)?; - } - } - - Ok(()) -} - #[cfg(test)] mod test_manifest { use super::*; diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 386c8872291..1cc32dee8f0 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -1,4 +1,5 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::ffi::OsStr; use std::fmt::{self, Display, Write}; use std::marker::PhantomData; use std::path::{Path, PathBuf}; @@ -55,13 +56,29 @@ pub fn read_manifest( path.display(), source_id ); - let contents = paths::read(path).map_err(|err| ManifestError::new(err, path.into()))?; + let mut contents = paths::read(path).map_err(|err| ManifestError::new(err, path.into()))?; + let embedded = is_embedded(path); + if embedded { + if !config.cli_unstable().script { + return Err(ManifestError::new( + anyhow::anyhow!("parsing `{}` requires `-Zscript`", path.display()), + path.into(), + )); + } + contents = embedded::expand_manifest(&contents, path, config) + .map_err(|err| ManifestError::new(err, path.into()))?; + } - read_manifest_from_str(&contents, path, source_id, config) + read_manifest_from_str(&contents, path, embedded, source_id, config) .with_context(|| format!("failed to parse manifest at `{}`", path.display())) .map_err(|err| ManifestError::new(err, path.into())) } +fn is_embedded(path: &Path) -> bool { + let ext = path.extension(); + ext.is_none() || ext == Some(OsStr::new("rs")) +} + /// Parse an already-loaded `Cargo.toml` as a Cargo manifest. /// /// This could result in a real or virtual manifest being returned. @@ -73,6 +90,7 @@ pub fn read_manifest( fn read_manifest_from_str( contents: &str, manifest_file: &Path, + embedded: bool, source_id: SourceId, config: &Config, ) -> CargoResult<(EitherManifest, Vec)> { @@ -128,7 +146,7 @@ fn read_manifest_from_str( } return if manifest.project.is_some() || manifest.package.is_some() { let (mut manifest, paths) = - TomlManifest::to_real_manifest(&manifest, source_id, package_root, config)?; + TomlManifest::to_real_manifest(&manifest, embedded, source_id, package_root, config)?; add_unused(manifest.warnings_mut()); if manifest.targets().iter().all(|t| t.is_custom_build()) { bail!( @@ -1976,6 +1994,7 @@ impl TomlManifest { pub fn to_real_manifest( me: &Rc, + embedded: bool, source_id: SourceId, package_root: &Path, config: &Config, @@ -2644,6 +2663,7 @@ impl TomlManifest { package.metabuild.clone().map(|sov| sov.0), resolve_behavior, rustflags, + embedded, ); if package.license_file.is_some() && package.license.is_some() { manifest.warnings_mut().add_warning( diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index 690fd13ec0b..6eca0796858 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -26,16 +26,16 @@ fn basic_rs() { p.cargo("-Zscript echo.rs") .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/echo[EXE] args: [] "#, ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] echo v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/echo) +[COMPILING] echo v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/echo/target/debug/echo[EXE]` +[RUNNING] `[..]debug/echo[EXE]` ", ) .run(); @@ -50,16 +50,16 @@ fn basic_path() { p.cargo("-Zscript ./echo") .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/echo[EXE] args: [] "#, ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] echo v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/echo) +[COMPILING] echo v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/echo/target/debug/echo[EXE]` +[RUNNING] `[..]/debug/echo[EXE]` ", ) .run(); @@ -104,16 +104,16 @@ fn manifest_precedence_over_plugins() { .env("PATH", &path) .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/echo[EXE] args: [] "#, ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] echo v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/echo) +[COMPILING] echo v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/echo/target/debug/echo[EXE]` +[RUNNING] `[..]/debug/echo[EXE]` ", ) .run(); @@ -203,9 +203,9 @@ fn main() { ) .with_stderr( "\ -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE]` +[RUNNING] `[..]/debug/script[EXE]` ", ) .run(); @@ -235,9 +235,9 @@ fn main() { .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE]` +[RUNNING] `[..]/debug/script[EXE]` ", ) .run(); @@ -264,9 +264,9 @@ fn main() { .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE]` +[RUNNING] `[..]/debug/script[EXE]` ", ) .run(); @@ -282,7 +282,7 @@ fn main() { "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE]` +[RUNNING] `[..]/debug/script[EXE]` ", ) .run(); @@ -298,9 +298,9 @@ fn main() { .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE]` +[RUNNING] `[..]/debug/script[EXE]` ", ) .run(); @@ -327,9 +327,9 @@ fn main() { .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE]` +[RUNNING] `[..]/debug/script[EXE]` ", ) .run(); @@ -345,16 +345,16 @@ fn test_escaped_hyphen_arg() { p.cargo("-Zscript -- script.rs -NotAnArg") .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/script[EXE] args: ["-NotAnArg"] "#, ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] -NotAnArg` +[RUNNING] `[..]/debug/script[EXE] -NotAnArg` ", ) .run(); @@ -370,16 +370,16 @@ fn test_unescaped_hyphen_arg() { p.cargo("-Zscript script.rs -NotAnArg") .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/script[EXE] args: ["-NotAnArg"] "#, ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] -NotAnArg` +[RUNNING] `[..]/debug/script[EXE] -NotAnArg` ", ) .run(); @@ -395,16 +395,16 @@ fn test_same_flags() { p.cargo("-Zscript script.rs --help") .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/script[EXE] args: ["--help"] "#, ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] --help` +[RUNNING] `[..]/debug/script[EXE] --help` ", ) .run(); @@ -420,15 +420,15 @@ fn test_name_has_weird_chars() { p.cargo("-Zscript s-h.w§c!.rs") .masquerade_as_nightly_cargo(&["script"]) .with_stdout( - r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] + r#"bin: [..]/debug/s-h-w-c-[EXE] args: [] "#, ) .with_stderr( r#"[WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] s-h-w-c- v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/s-h-w-c-) +[COMPILING] s-h-w-c- v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/s-h-w-c-/target/debug/s-h-w-c-[EXE]` +[RUNNING] `[..]/debug/s-h-w-c-[EXE]` "#, ) .run(); @@ -464,9 +464,9 @@ fn main() { [DOWNLOADING] crates ... [DOWNLOADED] script v1.0.0 (registry `dummy-registry`) [COMPILING] script v1.0.0 -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] --help` +[RUNNING] `[..]/debug/script[EXE] --help` ", ) .run(); @@ -501,9 +501,9 @@ fn main() { "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` [COMPILING] bar v0.0.1 ([ROOT]/foo/bar) -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) +[COMPILING] script v0.0.0 ([ROOT]/foo) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] --help` +[RUNNING] `[..]/debug/script[EXE] --help` ", ) .run(); @@ -523,16 +523,12 @@ fn main() { p.cargo("-Zscript script.rs --help") .masquerade_as_nightly_cargo(&["script"]) - .with_stdout( - r#"Hello world! -"#, - ) + .with_status(101) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s -[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] --help` +[ERROR] `cargo run` could not determine which binary to run. Use the `--bin` option to specify a binary, or the `default-run` manifest key. +available binaries: not-script, script ", ) .run(); From 5ed07925cc24f1c0fa289d0f65f38ed47435391d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 14 Jun 2023 12:07:48 -0500 Subject: [PATCH 5/6] fix(embedded): Ensure we don't auto-discover any targets --- src/cargo/util/toml/embedded.rs | 21 +++++++++++++++++++-- tests/testsuite/script.rs | 10 +++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/cargo/util/toml/embedded.rs b/src/cargo/util/toml/embedded.rs index c86beaad759..3d9e22940d1 100644 --- a/src/cargo/util/toml/embedded.rs +++ b/src/cargo/util/toml/embedded.rs @@ -8,6 +8,7 @@ const DEFAULT_EDITION: crate::core::features::Edition = crate::core::features::Edition::LATEST_STABLE; const DEFAULT_VERSION: &str = "0.0.0"; const DEFAULT_PUBLISH: bool = false; +const AUTO_FIELDS: &[&str] = &["autobins", "autoexamples", "autotests", "autobenches"]; pub fn expand_manifest( content: &str, @@ -57,8 +58,11 @@ fn expand_manifest_( .or_insert_with(|| toml::Table::new().into()) .as_table_mut() .ok_or_else(|| anyhow::format_err!("`package` must be a table"))?; - for key in ["workspace", "build", "links"] { - if package.contains_key(key) { + for key in ["workspace", "build", "links"] + .iter() + .chain(AUTO_FIELDS.iter()) + { + if package.contains_key(*key) { anyhow::bail!("`package.{key}` is not allowed in embedded manifests") } } @@ -88,6 +92,11 @@ fn expand_manifest_( package .entry("publish".to_owned()) .or_insert_with(|| toml::Value::Boolean(DEFAULT_PUBLISH)); + for field in AUTO_FIELDS { + package + .entry(field.to_owned()) + .or_insert_with(|| toml::Value::Boolean(false)); + } let mut bin = toml::Table::new(); bin.insert("name".to_owned(), toml::Value::String(bin_name)); @@ -363,6 +372,10 @@ name = "test-" path = "test.rs" [package] +autobenches = false +autobins = false +autoexamples = false +autotests = false edition = "2021" name = "test-" publish = false @@ -388,6 +401,10 @@ path = "test.rs" time = "0.1.25" [package] +autobenches = false +autobins = false +autoexamples = false +autotests = false edition = "2021" name = "test-" publish = false diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index 6eca0796858..d4f343be644 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -523,12 +523,16 @@ fn main() { p.cargo("-Zscript script.rs --help") .masquerade_as_nightly_cargo(&["script"]) - .with_status(101) + .with_stdout( + r#"Hello world! +"#, + ) .with_stderr( "\ [WARNING] `package.edition` is unspecifiead, defaulting to `2021` -[ERROR] `cargo run` could not determine which binary to run. Use the `--bin` option to specify a binary, or the `default-run` manifest key. -available binaries: not-script, script +[COMPILING] script v0.0.0 ([ROOT]/foo) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s +[RUNNING] `[..]/debug/script[EXE] --help` ", ) .run(); From 224d2e688d430b2215e8f4007027d88ed6b44973 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 15 Jun 2023 16:28:54 -0500 Subject: [PATCH 6/6] fix(cli): Make 'cargo foo.rs' behave like --manifest-path This mirrors the logic `ArgMatchesExt::root_manifest` --- src/bin/cargo/commands/run.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index 45521b5f05f..8ee7d3f9aa9 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -96,12 +96,15 @@ pub fn exec_manifest_command(config: &Config, cmd: &str, args: &[OsString]) -> C } let manifest_path = Path::new(cmd); + let manifest_path = config.cwd().join(manifest_path); + let manifest_path = cargo_util::paths::normalize_path(&manifest_path); if !manifest_path.exists() { - return Err( - anyhow::anyhow!("manifest `{}` does not exist", manifest_path.display()).into(), - ); + return Err(anyhow::format_err!( + "manifest path `{}` does not exist", + manifest_path.display() + ) + .into()); } - let manifest_path = crate::util::try_canonicalize(manifest_path)?; let mut ws = Workspace::new(&manifest_path, config)?; if config.cli_unstable().avoid_dev_deps { ws.set_require_optional_deps(false);