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.
This commit is contained in:
Ed Page 2023-06-13 12:38:07 -05:00
parent 2c70983e8d
commit 575b9ac934
10 changed files with 115 additions and 278 deletions

35
Cargo.lock generated
View file

@ -99,24 +99,12 @@ version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
[[package]]
name = "arrayref"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.5.2" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "arrayvec"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c"
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -199,20 +187,6 @@ dependencies = [
"typenum", "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]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.10.4" version = "0.10.4"
@ -292,7 +266,6 @@ version = "0.73.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64", "base64",
"blake3",
"bytesize", "bytesize",
"cargo-platform 0.1.3", "cargo-platform 0.1.3",
"cargo-test-macro", "cargo-test-macro",
@ -555,12 +528,6 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913"
[[package]]
name = "constant_time_eq"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6"
[[package]] [[package]]
name = "content_inspector" name = "content_inspector"
version = "0.2.4" version = "0.2.4"
@ -3513,7 +3480,7 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983"
dependencies = [ dependencies = [
"arrayvec 0.5.2", "arrayvec",
"utf8parse", "utf8parse",
"vte_generate_state_changes", "vte_generate_state_changes",
] ]

View file

@ -13,7 +13,6 @@ exclude = [
[workspace.dependencies] [workspace.dependencies]
anyhow = "1.0.47" anyhow = "1.0.47"
base64 = "0.21.0" base64 = "0.21.0"
blake3 = "1.3.3"
bytesize = "1.0" bytesize = "1.0"
cargo = { path = "" } cargo = { path = "" }
cargo-credential = { version = "0.2.0", path = "credential/cargo-credential" } cargo-credential = { version = "0.2.0", path = "credential/cargo-credential" }
@ -115,7 +114,6 @@ path = "src/cargo/lib.rs"
[dependencies] [dependencies]
anyhow.workspace = true anyhow.workspace = true
base64.workspace = true base64.workspace = true
blake3.workspace = true
bytesize.workspace = true bytesize.workspace = true
cargo-platform.workspace = true cargo-platform.workspace = true
cargo-util.workspace = true cargo-util.workspace = true

View file

@ -106,7 +106,6 @@ allow = [
"MIT-0", "MIT-0",
"Apache-2.0", "Apache-2.0",
"BSD-3-Clause", "BSD-3-Clause",
"BSD-2-Clause",
"MPL-2.0", "MPL-2.0",
"Unicode-DFS-2016", "Unicode-DFS-2016",
"CC0-1.0", "CC0-1.0",

View file

@ -5,6 +5,7 @@ use std::path::Path;
use crate::command_prelude::*; use crate::command_prelude::*;
use crate::util::restricted_names::is_glob_pattern; use crate::util::restricted_names::is_glob_pattern;
use cargo::core::Verbosity; use cargo::core::Verbosity;
use cargo::core::Workspace;
use cargo::ops::{self, CompileFilter, Packages}; use cargo::ops::{self, CompileFilter, Packages};
use cargo_util::ProcessError; 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 manifest_path = crate::util::try_canonicalize(manifest_path)?;
let script = cargo::util::toml::embedded::parse_from(&manifest_path)?; let mut ws = Workspace::new(&manifest_path, config)?;
let ws = cargo::util::toml::embedded::to_workspace(&script, config)?; if config.cli_unstable().avoid_dev_deps {
ws.set_require_optional_deps(false);
}
let mut compile_opts = let mut compile_opts =
cargo::ops::CompileOptions::new(config, cargo::core::compiler::CompileMode::Build)?; cargo::ops::CompileOptions::new(config, cargo::core::compiler::CompileMode::Build)?;

View file

@ -64,6 +64,7 @@ pub struct Manifest {
metabuild: Option<Vec<String>>, metabuild: Option<Vec<String>>,
resolve_behavior: Option<ResolveBehavior>, resolve_behavior: Option<ResolveBehavior>,
lint_rustflags: Vec<String>, lint_rustflags: Vec<String>,
embedded: bool,
} }
/// When parsing `Cargo.toml`, some warnings should silenced /// When parsing `Cargo.toml`, some warnings should silenced
@ -407,6 +408,7 @@ impl Manifest {
metabuild: Option<Vec<String>>, metabuild: Option<Vec<String>>,
resolve_behavior: Option<ResolveBehavior>, resolve_behavior: Option<ResolveBehavior>,
lint_rustflags: Vec<String>, lint_rustflags: Vec<String>,
embedded: bool,
) -> Manifest { ) -> Manifest {
Manifest { Manifest {
summary, summary,
@ -433,6 +435,7 @@ impl Manifest {
metabuild, metabuild,
resolve_behavior, resolve_behavior,
lint_rustflags, lint_rustflags,
embedded,
} }
} }
@ -500,6 +503,9 @@ impl Manifest {
pub fn links(&self) -> Option<&str> { pub fn links(&self) -> Option<&str> {
self.links.as_deref() self.links.as_deref()
} }
pub fn is_embedded(&self) -> bool {
self.embedded
}
pub fn workspace_config(&self) -> &WorkspaceConfig { pub fn workspace_config(&self) -> &WorkspaceConfig {
&self.workspace &self.workspace

View file

@ -726,6 +726,10 @@ impl<'cfg> Workspace<'cfg> {
if self.members.contains(&manifest_path) { if self.members.contains(&manifest_path) {
return Ok(()); return Ok(());
} }
if is_path_dep && self.root_maybe().is_embedded() {
// Embedded manifests cannot have workspace members
return Ok(());
}
if is_path_dep if is_path_dep
&& !manifest_path.parent().unwrap().starts_with(self.root()) && !manifest_path.parent().unwrap().starts_with(self.root())
&& self.find_root(&manifest_path)? != self.root_manifest && self.find_root(&manifest_path)? != self.root_manifest
@ -1580,6 +1584,13 @@ impl MaybePackage {
MaybePackage::Virtual(ref vm) => vm.workspace_config(), 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 { impl WorkspaceRootConfig {

View file

@ -393,7 +393,7 @@ fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
let package_root = orig_pkg.root(); let package_root = orig_pkg.root();
let source_id = orig_pkg.package_id().source_id(); let source_id = orig_pkg.package_id().source_id();
let (manifest, _nested_paths) = 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()); let new_pkg = Package::new(manifest, orig_pkg.manifest_path());
// Regenerate Cargo.lock using the old one as a guide. // Regenerate Cargo.lock using the old one as a guide.

View file

@ -1,6 +1,5 @@
use anyhow::Context as _; use anyhow::Context as _;
use crate::core::Workspace;
use crate::util::restricted_names; use crate::util::restricted_names;
use crate::CargoResult; use crate::CargoResult;
use crate::Config; use crate::Config;
@ -10,21 +9,13 @@ const DEFAULT_EDITION: crate::core::features::Edition =
const DEFAULT_VERSION: &str = "0.0.0"; const DEFAULT_VERSION: &str = "0.0.0";
const DEFAULT_PUBLISH: bool = false; const DEFAULT_PUBLISH: bool = false;
pub struct RawScript { pub fn expand_manifest(
manifest: String, content: &str,
body: String, path: &std::path::Path,
path: std::path::PathBuf, config: &Config,
} ) -> CargoResult<String> {
let comment = match extract_comment(content) {
pub fn parse_from(path: &std::path::Path) -> CargoResult<RawScript> { Ok(comment) => Some(comment),
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<RawScript> {
let comment = match extract_comment(body) {
Ok(manifest) => Some(manifest),
Err(err) => { Err(err) => {
log::trace!("failed to extract doc comment: {err}"); log::trace!("failed to extract doc comment: {err}");
None None
@ -39,82 +30,18 @@ fn parse(body: &str, path: &std::path::Path) -> CargoResult<RawScript> {
} }
} }
.unwrap_or_default(); .unwrap_or_default();
let body = body.to_owned(); let manifest = expand_manifest_(&manifest, path, config)
let path = path.to_owned(); .with_context(|| format!("failed to parse manifest at {}", path.display()))?;
Ok(RawScript {
manifest,
body,
path,
})
}
pub fn to_workspace<'cfg>(
script: &RawScript,
config: &'cfg Config,
) -> CargoResult<Workspace<'cfg>> {
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<std::path::PathBuf> {
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<String> {
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 = toml::to_string_pretty(&manifest)?; let manifest = toml::to_string_pretty(&manifest)?;
Ok(manifest) Ok(manifest)
} }
fn expand_manifest_(script: &RawScript, config: &Config) -> CargoResult<toml::Table> { fn expand_manifest_(
let mut manifest: toml::Table = toml::from_str(&script.manifest)?; manifest: &str,
path: &std::path::Path,
config: &Config,
) -> CargoResult<toml::Table> {
let mut manifest: toml::Table = toml::from_str(&manifest)?;
for key in ["workspace", "lib", "bin", "example", "test", "bench"] { for key in ["workspace", "lib", "bin", "example", "test", "bench"] {
if manifest.contains_key(key) { if manifest.contains_key(key) {
@ -135,8 +62,11 @@ fn expand_manifest_(script: &RawScript, config: &Config) -> CargoResult<toml::Ta
anyhow::bail!("`package.{key}` is not allowed in embedded manifests") anyhow::bail!("`package.{key}` is not allowed in embedded manifests")
} }
} }
let file_stem = script let file_name = path
.path .file_name()
.ok_or_else(|| anyhow::format_err!("no file name"))?
.to_string_lossy();
let file_stem = path
.file_stem() .file_stem()
.ok_or_else(|| anyhow::format_err!("no file name"))? .ok_or_else(|| anyhow::format_err!("no file name"))?
.to_string_lossy(); .to_string_lossy();
@ -163,13 +93,7 @@ fn expand_manifest_(script: &RawScript, config: &Config) -> CargoResult<toml::Ta
bin.insert("name".to_owned(), toml::Value::String(bin_name)); bin.insert("name".to_owned(), toml::Value::String(bin_name));
bin.insert( bin.insert(
"path".to_owned(), "path".to_owned(),
toml::Value::String( toml::Value::String(file_name.into_owned()),
script
.path
.to_str()
.ok_or_else(|| anyhow::format_err!("path is not valid UTF-8"))?
.into(),
),
); );
manifest.insert( manifest.insert(
"bin".to_owned(), "bin".to_owned(),
@ -223,28 +147,6 @@ fn sanitize_name(name: &str) -> String {
name name
} }
fn hash(script: &RawScript) -> blake3::Hash {
blake3::hash(script.body.as_bytes())
}
fn default_target_dir() -> CargoResult<std::path::PathBuf> {
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. /// Locates a "code block manifest" in Rust source.
fn extract_comment(input: &str) -> CargoResult<String> { fn extract_comment(input: &str) -> CargoResult<String> {
let re_crate_comment = regex::Regex::new( let re_crate_comment = regex::Regex::new(
@ -444,10 +346,12 @@ mod test_expand {
macro_rules! si { macro_rules! si {
($i:expr) => {{ ($i:expr) => {{
let script = parse($i, std::path::Path::new("/home/me/test.rs")) expand_manifest(
.unwrap_or_else(|err| panic!("{}", err)); $i,
expand_manifest(&script, &Config::default().unwrap()) std::path::Path::new("/home/me/test.rs"),
.unwrap_or_else(|err| panic!("{}", err)) &Config::default().unwrap(),
)
.unwrap_or_else(|err| panic!("{}", err))
}}; }};
} }
@ -456,7 +360,7 @@ mod test_expand {
snapbox::assert_eq( snapbox::assert_eq(
r#"[[bin]] r#"[[bin]]
name = "test-" name = "test-"
path = "/home/me/test.rs" path = "test.rs"
[package] [package]
edition = "2021" edition = "2021"
@ -478,7 +382,7 @@ strip = true
snapbox::assert_eq( snapbox::assert_eq(
r#"[[bin]] r#"[[bin]]
name = "test-" name = "test-"
path = "/home/me/test.rs" path = "test.rs"
[dependencies] [dependencies]
time = "0.1.25" 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<toml::value::Table> {
// 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<F>(
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)] #[cfg(test)]
mod test_manifest { mod test_manifest {
use super::*; use super::*;

View file

@ -1,4 +1,5 @@
use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::ffi::OsStr;
use std::fmt::{self, Display, Write}; use std::fmt::{self, Display, Write};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -55,13 +56,29 @@ pub fn read_manifest(
path.display(), path.display(),
source_id 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())) .with_context(|| format!("failed to parse manifest at `{}`", path.display()))
.map_err(|err| ManifestError::new(err, path.into())) .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. /// Parse an already-loaded `Cargo.toml` as a Cargo manifest.
/// ///
/// This could result in a real or virtual manifest being returned. /// This could result in a real or virtual manifest being returned.
@ -73,6 +90,7 @@ pub fn read_manifest(
fn read_manifest_from_str( fn read_manifest_from_str(
contents: &str, contents: &str,
manifest_file: &Path, manifest_file: &Path,
embedded: bool,
source_id: SourceId, source_id: SourceId,
config: &Config, config: &Config,
) -> CargoResult<(EitherManifest, Vec<PathBuf>)> { ) -> CargoResult<(EitherManifest, Vec<PathBuf>)> {
@ -128,7 +146,7 @@ fn read_manifest_from_str(
} }
return if manifest.project.is_some() || manifest.package.is_some() { return if manifest.project.is_some() || manifest.package.is_some() {
let (mut manifest, paths) = 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()); add_unused(manifest.warnings_mut());
if manifest.targets().iter().all(|t| t.is_custom_build()) { if manifest.targets().iter().all(|t| t.is_custom_build()) {
bail!( bail!(
@ -1976,6 +1994,7 @@ impl TomlManifest {
pub fn to_real_manifest( pub fn to_real_manifest(
me: &Rc<TomlManifest>, me: &Rc<TomlManifest>,
embedded: bool,
source_id: SourceId, source_id: SourceId,
package_root: &Path, package_root: &Path,
config: &Config, config: &Config,
@ -2644,6 +2663,7 @@ impl TomlManifest {
package.metabuild.clone().map(|sov| sov.0), package.metabuild.clone().map(|sov| sov.0),
resolve_behavior, resolve_behavior,
rustflags, rustflags,
embedded,
); );
if package.license_file.is_some() && package.license.is_some() { if package.license_file.is_some() && package.license.is_some() {
manifest.warnings_mut().add_warning( manifest.warnings_mut().add_warning(

View file

@ -26,16 +26,16 @@ fn basic_rs() {
p.cargo("-Zscript echo.rs") p.cargo("-Zscript echo.rs")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/echo[EXE]
args: [] args: []
"#, "#,
) )
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -50,16 +50,16 @@ fn basic_path() {
p.cargo("-Zscript ./echo") p.cargo("-Zscript ./echo")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/echo[EXE]
args: [] args: []
"#, "#,
) )
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -104,16 +104,16 @@ fn manifest_precedence_over_plugins() {
.env("PATH", &path) .env("PATH", &path)
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/echo[EXE]
args: [] args: []
"#, "#,
) )
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -203,9 +203,9 @@ fn main() {
) )
.with_stderr( .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 [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(); .run();
@ -235,9 +235,9 @@ fn main() {
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -264,9 +264,9 @@ fn main() {
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -282,7 +282,7 @@ fn main() {
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [WARNING] `package.edition` is unspecifiead, defaulting to `2021`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s [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(); .run();
@ -298,9 +298,9 @@ fn main() {
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -327,9 +327,9 @@ fn main() {
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -345,16 +345,16 @@ fn test_escaped_hyphen_arg() {
p.cargo("-Zscript -- script.rs -NotAnArg") p.cargo("-Zscript -- script.rs -NotAnArg")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/script[EXE]
args: ["-NotAnArg"] args: ["-NotAnArg"]
"#, "#,
) )
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -370,16 +370,16 @@ fn test_unescaped_hyphen_arg() {
p.cargo("-Zscript script.rs -NotAnArg") p.cargo("-Zscript script.rs -NotAnArg")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/script[EXE]
args: ["-NotAnArg"] args: ["-NotAnArg"]
"#, "#,
) )
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -395,16 +395,16 @@ fn test_same_flags() {
p.cargo("-Zscript script.rs --help") p.cargo("-Zscript script.rs --help")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/script[EXE]
args: ["--help"] args: ["--help"]
"#, "#,
) )
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [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 [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(); .run();
@ -420,15 +420,15 @@ fn test_name_has_weird_chars() {
p.cargo("-Zscript s-h.w§c!.rs") p.cargo("-Zscript s-h.w§c!.rs")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_stdout(
r#"bin: [ROOT]/home/.cargo/eval/target/eval/[..] r#"bin: [..]/debug/s-h-w-c-[EXE]
args: [] args: []
"#, "#,
) )
.with_stderr( .with_stderr(
r#"[WARNING] `package.edition` is unspecifiead, defaulting to `2021` 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 [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(); .run();
@ -464,9 +464,9 @@ fn main() {
[DOWNLOADING] crates ... [DOWNLOADING] crates ...
[DOWNLOADED] script v1.0.0 (registry `dummy-registry`) [DOWNLOADED] script v1.0.0 (registry `dummy-registry`)
[COMPILING] script v1.0.0 [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 [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(); .run();
@ -501,9 +501,9 @@ fn main() {
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [WARNING] `package.edition` is unspecifiead, defaulting to `2021`
[COMPILING] bar v0.0.1 ([ROOT]/foo/bar) [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 [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(); .run();
@ -523,16 +523,12 @@ fn main() {
p.cargo("-Zscript script.rs --help") p.cargo("-Zscript script.rs --help")
.masquerade_as_nightly_cargo(&["script"]) .masquerade_as_nightly_cargo(&["script"])
.with_stdout( .with_status(101)
r#"Hello world!
"#,
)
.with_stderr( .with_stderr(
"\ "\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021` [WARNING] `package.edition` is unspecifiead, defaulting to `2021`
[COMPILING] script v0.0.0 ([ROOT]/home/.cargo/eval/target/eval/[..]/script) [ERROR] `cargo run` could not determine which binary to run. Use the `--bin` option to specify a binary, or the `default-run` manifest key.
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s available binaries: not-script, script
[RUNNING] `[ROOT]/home/.cargo/eval/target/eval/[..]/script/target/debug/script[EXE] --help`
", ",
) )
.run(); .run();