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

fix(embedded): Don't pollute script dir with lockfile #12284

Merged
merged 2 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1599,7 +1599,8 @@ impl MaybePackage {
}
}

fn is_embedded(&self) -> bool {
/// Has an embedded manifest (single-file package)
pub fn is_embedded(&self) -> bool {
match self {
MaybePackage::Package(p) => p.manifest().is_embedded(),
MaybePackage::Virtual(_) => false,
Expand Down
35 changes: 24 additions & 11 deletions src/cargo/ops/lockfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ use crate::util::Filesystem;
use anyhow::Context as _;

pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult<Option<Resolve>> {
if !ws.root().join("Cargo.lock").exists() {
let lock_root = lock_root(ws);
if !lock_root.as_path_unlocked().join("Cargo.lock").exists() {
return Ok(None);
}

let root = Filesystem::new(ws.root().to_path_buf());
let mut f = root.open_ro("Cargo.lock", ws.config(), "Cargo.lock file")?;
let mut f = lock_root.open_ro("Cargo.lock", ws.config(), "Cargo.lock file")?;

let mut s = String::new();
f.read_to_string(&mut s)
Expand All @@ -30,12 +30,12 @@ pub fn load_pkg_lockfile(ws: &Workspace<'_>) -> CargoResult<Option<Resolve>> {

/// Generate a toml String of Cargo.lock from a Resolve.
pub fn resolve_to_string(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoResult<String> {
let (_orig, out, _ws_root) = resolve_to_string_orig(ws, resolve);
let (_orig, out, _lock_root) = resolve_to_string_orig(ws, resolve);
Ok(out)
}

pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoResult<()> {
let (orig, mut out, ws_root) = resolve_to_string_orig(ws, resolve);
let (orig, mut out, lock_root) = resolve_to_string_orig(ws, resolve);

// If the lock file contents haven't changed so don't rewrite it. This is
// helpful on read-only filesystems.
Expand All @@ -55,7 +55,7 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoRes
"the lock file {} needs to be updated but {} was passed to prevent this\n\
If you want to try to generate the lock file without accessing the network, \
remove the {} flag and use --offline instead.",
ws.root().to_path_buf().join("Cargo.lock").display(),
lock_root.as_path_unlocked().join("Cargo.lock").display(),
flag,
flag
);
Expand All @@ -80,14 +80,19 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoRes
}

// Ok, if that didn't work just write it out
ws_root
lock_root
.open_rw("Cargo.lock", ws.config(), "Cargo.lock file")
.and_then(|mut f| {
f.file().set_len(0)?;
f.write_all(out.as_bytes())?;
Ok(())
})
.with_context(|| format!("failed to write {}", ws.root().join("Cargo.lock").display()))?;
.with_context(|| {
format!(
"failed to write {}",
lock_root.as_path_unlocked().join("Cargo.lock").display()
)
})?;
Ok(())
}

Expand All @@ -96,15 +101,15 @@ fn resolve_to_string_orig(
resolve: &mut Resolve,
) -> (Option<String>, String, Filesystem) {
// Load the original lock file if it exists.
let ws_root = Filesystem::new(ws.root().to_path_buf());
let orig = ws_root.open_ro("Cargo.lock", ws.config(), "Cargo.lock file");
let lock_root = lock_root(ws);
let orig = lock_root.open_ro("Cargo.lock", ws.config(), "Cargo.lock file");
let orig = orig.and_then(|mut f| {
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
});
let out = serialize_resolve(resolve, orig.as_deref().ok());
(orig.ok(), out, ws_root)
(orig.ok(), out, lock_root)
}

fn serialize_resolve(resolve: &Resolve, orig: Option<&str>) -> String {
Expand Down Expand Up @@ -235,3 +240,11 @@ fn emit_package(dep: &toml::Table, out: &mut String) {
out.push_str(&format!("replace = {}\n\n", &dep["replace"]));
}
}

fn lock_root(ws: &Workspace<'_>) -> Filesystem {
if ws.root_maybe().is_embedded() {
ws.target_dir()
} else {
Filesystem::new(ws.root().to_owned())
}
}
30 changes: 30 additions & 0 deletions tests/testsuite/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,3 +591,33 @@ args: []
)
.run();
}

#[cargo_test]
fn no_local_lockfile() {
let script = ECHO_SCRIPT;
let p = cargo_test_support::project()
.file("script.rs", script)
.build();
let local_lockfile_path = p.root().join("Cargo.lock");

assert!(!local_lockfile_path.exists());

p.cargo("-Zscript script.rs")
.masquerade_as_nightly_cargo(&["script"])
.with_stdout(
r#"bin: [ROOT]/home/.cargo/target/[..]/debug/script[EXE]
args: []
"#,
)
.with_stderr(
"\
[WARNING] `package.edition` is unspecifiead, defaulting to `2021`
[COMPILING] script v0.0.0 ([ROOT]/foo)
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]s
[RUNNING] `[ROOT]/home/.cargo/target/[..]/debug/script[EXE]`
",
)
.run();

assert!(!local_lockfile_path.exists());
}