From 05a8127c10a3b0878c5d71411d21384a19452116 Mon Sep 17 00:00:00 2001 From: Steven Joruk Date: Thu, 5 Nov 2020 22:24:34 +0000 Subject: [PATCH] Skip extracting .cargo-ok files from packages This fixes the case where a package contained an empty .cargo-ok file and was mounted in a read only file system. This lead to attempting to download the package again, which failed due to write permissions. --- src/cargo/sources/registry/mod.rs | 16 ++++++----- tests/testsuite/registry.rs | 45 ++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index c9ab7ff4ecd..76a5da0089a 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -471,13 +471,6 @@ impl<'cfg> RegistrySource<'cfg> { return Ok(unpack_dir.to_path_buf()); } } - let mut ok = OpenOptions::new() - .create(true) - .read(true) - .write(true) - .open(&path) - .chain_err(|| format!("failed to open `{}`", path.display()))?; - let gz = GzDecoder::new(tarball); let mut tar = Archive::new(gz); let prefix = unpack_dir.file_name().unwrap(); @@ -517,6 +510,15 @@ impl<'cfg> RegistrySource<'cfg> { result.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?; } + // The lock file is created after unpacking so we overwrite a lock file + // which may have been extracted from the package. + let mut ok = OpenOptions::new() + .create(true) + .read(true) + .write(true) + .open(&path) + .chain_err(|| format!("failed to open `{}`", path.display()))?; + // Write to the lock file to indicate that unpacking was successful. write!(ok, "ok")?; diff --git a/tests/testsuite/registry.rs b/tests/testsuite/registry.rs index d1e1886ba5a..acba4a2c413 100644 --- a/tests/testsuite/registry.rs +++ b/tests/testsuite/registry.rs @@ -1,11 +1,11 @@ //! Tests for normal registry dependencies. -use cargo::util::paths::remove_dir_all; -use cargo_test_support::cargo_process; -use cargo_test_support::git; +use cargo::{core::SourceId, util::paths::remove_dir_all}; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::registry::{self, registry_path, Dependency, Package}; -use cargo_test_support::{basic_manifest, project, t}; +use cargo_test_support::{basic_manifest, project}; +use cargo_test_support::{cargo_process, registry::registry_url}; +use cargo_test_support::{git, install::cargo_home, t}; use std::fs::{self, File}; use std::path::Path; @@ -2133,3 +2133,40 @@ Use `[source]` replacement to alter the default index for crates.io. ) .run(); } + +#[cargo_test] +fn package_lock_inside_package_is_overwritten() { + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = ">= 0.0.0" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + Package::new("bar", "0.0.1") + .file("src/lib.rs", "") + .file(".cargo-ok", "") + .publish(); + + p.cargo("build").run(); + + let id = SourceId::for_registry(®istry_url()).unwrap(); + let hash = cargo::util::hex::short_hash(&id); + let ok = cargo_home() + .join("registry") + .join("src") + .join(format!("-{}", hash)) + .join("bar-0.0.1") + .join(".cargo-ok"); + + assert_eq!(ok.metadata().unwrap().len(), 2); +}