Skip to content
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
4 changes: 4 additions & 0 deletions src/cargo/sources/registry/http_remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,10 @@ impl<'gctx> RegistryData for HttpRegistry<'gctx> {
&self.index_path
}

fn cache_path(&self) -> &Filesystem {
&self.cache_path
}

fn assert_index_locked<'a>(&self, path: &'a Filesystem) -> &'a Path {
self.gctx
.assert_package_cache_locked(CacheLockMode::DownloadExclusive, path)
Expand Down
4 changes: 4 additions & 0 deletions src/cargo/sources/registry/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ impl<'gctx> RegistryData for LocalRegistry<'gctx> {
&self.index_path
}

fn cache_path(&self) -> &Filesystem {
&self.root
}

fn assert_index_locked<'a>(&self, path: &'a Filesystem) -> &'a Path {
// Note that the `*_unlocked` variant is used here since we're not
// modifying the index and it's required to be externally synchronized.
Expand Down
22 changes: 14 additions & 8 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,6 @@ pub struct RegistrySource<'gctx> {
source_id: SourceId,
/// The path where crate files are extracted (`$CARGO_HOME/registry/src/$REG-HASH`).
src_path: Filesystem,
/// Path to the cache of `.crate` files (`$CARGO_HOME/registry/cache/$REG-HASH`).
cache_path: Filesystem,
/// Local reference to [`GlobalContext`] for convenience.
gctx: &'gctx GlobalContext,
/// Abstraction for interfacing to the different registry kinds.
Expand Down Expand Up @@ -355,6 +353,12 @@ pub trait RegistryData {
/// (remote = git, http & local = files).
fn index_path(&self) -> &Filesystem;

/// Returns the path of the directory that stores the cache of `.crate` files.
///
/// The directory is currently expected to contain a flat list of all `.crate` files,
/// named `<package-name>-<version>.crate`.
fn cache_path(&self) -> &Filesystem;

/// Loads the JSON for a specific named package from the index.
///
/// * `root` is the root path to the index.
Expand Down Expand Up @@ -534,7 +538,6 @@ impl<'gctx> RegistrySource<'gctx> {
RegistrySource {
name: name.into(),
src_path: gctx.registry_source_path().join(name),
cache_path: gctx.registry_cache_path().join(name),
gctx,
source_id,
index: index::RegistryIndex::new(source_id, ops.index_path(), gctx),
Expand Down Expand Up @@ -665,17 +668,20 @@ impl<'gctx> RegistrySource<'gctx> {
/// Returns the path to the crate tarball directory,
/// which is always `<unpack_dir>/<pkg>-<version>`.
///
/// This holds an assumption that the associated tarball already exists.
/// This holds some assumptions
///
/// * The associated tarball already exists
/// * If this is a local registry,
/// the package cache lock must be externally synchronized.
/// Cargo does not take care of it being locked or not.
pub fn unpack_package_in(
&self,
pkg: &PackageId,
unpack_dir: &Path,
include: &dyn Fn(&Path) -> bool,
) -> CargoResult<PathBuf> {
let path = self.cache_path.join(pkg.tarball_name());
let path = self
.gctx
.assert_package_cache_locked(CacheLockMode::DownloadExclusive, &path);
let path = self.ops.cache_path().join(pkg.tarball_name());
let path = self.ops.assert_index_locked(&path);
let dst = unpack_dir.join(format!("{}-{}", pkg.name(), pkg.version()));
let tarball =
File::open(path).with_context(|| format!("failed to open {}", path.display()))?;
Expand Down
4 changes: 4 additions & 0 deletions src/cargo/sources/registry/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ impl<'gctx> RegistryData for RemoteRegistry<'gctx> {
&self.index_path
}

fn cache_path(&self) -> &Filesystem {
&self.cache_path
}

fn assert_index_locked<'a>(&self, path: &'a Filesystem) -> &'a Path {
self.gctx
.assert_package_cache_locked(CacheLockMode::DownloadExclusive, path)
Expand Down
67 changes: 67 additions & 0 deletions tests/testsuite/vendor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,73 @@ fn vendor_rename_fallback() {
assert!(p.root().join("vendor/log/Cargo.toml").exists());
}

#[cargo_test]
fn vendor_local_registry() {
// A regression test for rust-lang/cargo#16412
let root = paths::root();
fs::create_dir(root.join(".cargo")).unwrap();
fs::write(
root.join(".cargo/config.toml"),
r#"
[source.crates-io]
registry = 'https://wut'
replace-with = 'my-awesome-local-registry'

[source.my-awesome-local-registry]
local-registry = 'registry'
"#,
)
.unwrap();

Package::new("bar", "0.0.0")
.local(true)
.file("src/lib.rs", "pub fn bar() {}")
.publish();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
edition = "2021"

[dependencies]
bar = "0.0.0"
"#,
)
.file("src/lib.rs", "pub fn foo() { bar::bar(); }")
.build();

p.cargo("vendor --respect-source-config")
.with_stderr_data(str![[r#"
[LOCKING] 1 package to latest compatible version
[UNPACKING] bar v0.0.0 (registry `[ROOT]/registry`)
Vendoring bar v0.0.0 ([ROOT]/home/.cargo/registry/src/-[HASH]/bar-0.0.0) to vendor/bar
To use vendored sources, add this to your .cargo/config.toml for this project:


"#]])
.run();

assert_e2e().eq(
p.read_file("vendor/bar/Cargo.toml"),
str![[r#"

[package]
name = "bar"
version = "0.0.0"
authors = []

"#]],
);

assert_e2e().eq(
p.read_file("vendor/bar/src/lib.rs"),
str!["pub fn bar() {}"],
);
}

#[cargo_test]
fn deterministic_mtime() {
Package::new("foo", "0.1.0")
Expand Down