{
+{
/* Array of all packages in the workspace.
It also includes all feature-enabled dependencies unless --no-deps is used.
*/
diff --git a/src/doc/man/generated/cargo-vendor.html b/src/doc/man/generated/cargo-vendor.html
new file mode 100644
index 000000000..87ead7624
--- /dev/null
+++ b/src/doc/man/generated/cargo-vendor.html
@@ -0,0 +1,207 @@
+NAME
+
+cargo-vendor - Vendor all dependencies locally
+
+
+SYNOPSIS
+
+
+cargo vendor [OPTIONS] [PATH]
+
+
+
+
+DESCRIPTION
+
+
+This cargo subcommand will vendor all crates.io and git dependencies for a
+project into the specified directory at <path>
. After this command completes
+the vendor directory specified by <path>
will contain all remote sources from
+dependencies specified. Additional manifests beyond the default one can be
+specified with the -s
option.
+
+
+The cargo vendor
command will also print out the configuration necessary
+to use the vendored sources, which you will need to add to .cargo/config
.
+
+
+
+
+OPTIONS
+
+
+Owner Options
+
+
+- -s MANIFEST
+- --sync MANIFEST
+-
+
Specify extra Cargo.toml
manifests to workspaces which should also be
+vendored and synced to the output.
+
+- --no-delete
+-
+
Don’t delete the "vendor" directory when vendoring, but rather keep all
+existing contents of the vendor directory
+
+- --respect-source-config
+-
+
Instead of ignoring [source]
configuration by default in .cargo/config
+read it and use it when downloading crates from crates.io, for example
+
+
+
+
+
+Manifest Options
+
+
+- --manifest-path PATH
+-
+
Path to the Cargo.toml
file. By default, Cargo searches in the current
+directory or any parent directory for the Cargo.toml
file.
+
+
+
+
+
+Display Options
+
+
+- -v
+- --verbose
+-
+
Use verbose output. May be specified twice for "very verbose" output which
+includes extra output such as dependency warnings and build script output.
+May also be specified with the term.verbose
+config value.
+
+- -q
+- --quiet
+-
+
No output printed to stdout.
+
+- --color WHEN
+-
+
Control when colored output is used. Valid values:
+
+
+-
+
auto
(default): Automatically detect if color support is available on the
+terminal.
+
+-
+
always
: Always display colors.
+
+-
+
never
: Never display colors.
+
+
+
+
+May also be specified with the term.color
+config value.
+
+
+
+
+
+
+Common Options
+
+
+- -h
+- --help
+-
+
Prints help information.
+
+- -Z FLAG…
+-
+
Unstable (nightly-only) flags to Cargo. Run cargo -Z help
for
+details.
+
+- --frozen
+- --locked
+-
+
Either of these flags requires that the Cargo.lock
file is
+up-to-date. If the lock file is missing, or it needs to be updated, Cargo will
+exit with an error. The --frozen
flag also prevents Cargo from
+attempting to access the network to determine if it is out-of-date.
+
+These may be used in environments where you want to assert that the
+Cargo.lock
file is up-to-date (such as a CI build) or want to avoid network
+access.
+
+
+
+
+
+
+
+
+ENVIRONMENT
+
+
+See the reference for
+details on environment variables that Cargo reads.
+
+
+
+
+Exit Status
+
+
+
+- 0
+-
+
Cargo succeeded.
+
+- 101
+-
+
Cargo failed to complete.
+
+
+
+
+
+
+EXAMPLES
+
+
+
+-
+
Vendor all dependencies into a local "vendor" folder
+
+
+cargo vendor
+
+
+
+-
+
Vendor all dependencies into a local "third-part/vendor" folder
+
+
+cargo vendor third-party/vendor
+
+
+
+-
+
Vendor the current workspace as well as another to "vendor"
+
+
+cargo vendor -s ../path/to/Cargo.toml
+
+
+
+
+
+
+
+
+SEE ALSO
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/doc/src/SUMMARY.md b/src/doc/src/SUMMARY.md
index 3a69c0a31..4943d2512 100644
--- a/src/doc/src/SUMMARY.md
+++ b/src/doc/src/SUMMARY.md
@@ -49,6 +49,7 @@
* [metadata](commands/cargo-metadata.md)
* [pkgid](commands/cargo-pkgid.md)
* [update](commands/cargo-update.md)
+ * [vendor](commands/cargo-vendor.md)
* [verify-project](commands/cargo-verify-project.md)
* [Package Commands](commands/package-commands.md)
* [init](commands/cargo-init.md)
diff --git a/src/doc/src/commands/cargo-vendor.md b/src/doc/src/commands/cargo-vendor.md
new file mode 100644
index 000000000..1e0f333fe
--- /dev/null
+++ b/src/doc/src/commands/cargo-vendor.md
@@ -0,0 +1,4 @@
+# cargo vendor
+{{#include command-common.html}}
+{{#include ../../man/generated/cargo-vendor.html}}
+
diff --git a/src/doc/src/reference/source-replacement.md b/src/doc/src/reference/source-replacement.md
index d7e23fa99..802f41d62 100644
--- a/src/doc/src/reference/source-replacement.md
+++ b/src/doc/src/reference/source-replacement.md
@@ -107,12 +107,8 @@ the crates that are present).
A "directory source" is similar to a local registry source where it contains a
number of crates available on the local filesystem, suitable for vendoring
-dependencies. Also like local registries, directory sources can primarily be
-managed by an external subcommand, [`cargo-vendor`][cargo-vendor],
-[available on crates.io][cargo-vendor] and can be
-installed with `cargo install cargo-vendor`.
-
-[cargo-vendor]: https://crates.io/crates/cargo-vendor
+dependencies. Directory sources are primarily managed the `cargo vendor`
+subcommand.
Directory sources are distinct from local registries though in that they contain
the unpacked version of `*.crate` files, making it more suitable in some
diff --git a/src/etc/man/cargo-vendor.1 b/src/etc/man/cargo-vendor.1
new file mode 100644
index 000000000..3937cc949
--- /dev/null
+++ b/src/etc/man/cargo-vendor.1
@@ -0,0 +1,223 @@
+'\" t
+.\" Title: cargo-vendor
+.\" Author: [see the "AUTHOR(S)" section]
+.\" Generator: Asciidoctor 2.0.8
+.\" Date: 2019-04-29
+.\" Manual: \ \&
+.\" Source: \ \&
+.\" Language: English
+.\"
+.TH "CARGO\-VENDOR" "1" "2019-04-29" "\ \&" "\ \&"
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.ss \n[.ss] 0
+.nh
+.ad l
+.de URL
+\fI\\$2\fP <\\$1>\\$3
+..
+.als MTO URL
+.if \n[.g] \{\
+. mso www.tmac
+. am URL
+. ad l
+. .
+. am MTO
+. ad l
+. .
+. LINKSTYLE blue R < >
+.\}
+.SH "NAME"
+cargo\-vendor \- Vendor all dependencies locally
+.SH "SYNOPSIS"
+.sp
+\fBcargo vendor [\fIOPTIONS\fP] [\fIPATH\fP]\fP
+.SH "DESCRIPTION"
+.sp
+This cargo subcommand will vendor all crates.io and git dependencies for a
+project into the specified directory at \fB\fP. After this command completes
+the vendor directory specified by \fB\fP will contain all remote sources from
+dependencies specified. Additional manifests beyond the default one can be
+specified with the \fB\-s\fP option.
+.sp
+The \fBcargo vendor\fP command will also print out the configuration necessary
+to use the vendored sources, which you will need to add to \fB.cargo/config\fP.
+.SH "OPTIONS"
+.SS "Owner Options"
+.sp
+\fB\-s\fP \fIMANIFEST\fP, \fB\-\-sync\fP \fIMANIFEST\fP
+.RS 4
+Specify extra \fBCargo.toml\fP manifests to workspaces which should also be
+vendored and synced to the output.
+.RE
+.sp
+\fB\-\-no\-delete\fP
+.RS 4
+Don\(cqt delete the "vendor" directory when vendoring, but rather keep all
+existing contents of the vendor directory
+.RE
+.sp
+\fB\-\-respect\-source\-config\fP
+.RS 4
+Instead of ignoring \fB[source]\fP configuration by default in \fB.cargo/config\fP
+read it and use it when downloading crates from crates.io, for example
+.RE
+.SS "Manifest Options"
+.sp
+\fB\-\-manifest\-path\fP \fIPATH\fP
+.RS 4
+Path to the \fBCargo.toml\fP file. By default, Cargo searches in the current
+directory or any parent directory for the \fBCargo.toml\fP file.
+.RE
+.SS "Display Options"
+.sp
+\fB\-v\fP, \fB\-\-verbose\fP
+.RS 4
+Use verbose output. May be specified twice for "very verbose" output which
+includes extra output such as dependency warnings and build script output.
+May also be specified with the \fBterm.verbose\fP
+.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "."
+.RE
+.sp
+\fB\-q\fP, \fB\-\-quiet\fP
+.RS 4
+No output printed to stdout.
+.RE
+.sp
+\fB\-\-color\fP \fIWHEN\fP
+.RS 4
+Control when colored output is used. Valid values:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+\fBauto\fP (default): Automatically detect if color support is available on the
+terminal.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+\fBalways\fP: Always display colors.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+. sp -1
+. IP \(bu 2.3
+.\}
+\fBnever\fP: Never display colors.
+.RE
+.sp
+May also be specified with the \fBterm.color\fP
+.URL "https://doc.rust\-lang.org/cargo/reference/config.html" "config value" "."
+.RE
+.SS "Common Options"
+.sp
+\fB\-h\fP, \fB\-\-help\fP
+.RS 4
+Prints help information.
+.RE
+.sp
+\fB\-Z\fP \fIFLAG\fP...
+.RS 4
+Unstable (nightly\-only) flags to Cargo. Run \fBcargo \-Z help\fP for
+details.
+.RE
+.sp
+\fB\-\-frozen\fP, \fB\-\-locked\fP
+.RS 4
+Either of these flags requires that the \fBCargo.lock\fP file is
+up\-to\-date. If the lock file is missing, or it needs to be updated, Cargo will
+exit with an error. The \fB\-\-frozen\fP flag also prevents Cargo from
+attempting to access the network to determine if it is out\-of\-date.
+.sp
+These may be used in environments where you want to assert that the
+\fBCargo.lock\fP file is up\-to\-date (such as a CI build) or want to avoid network
+access.
+.RE
+.SH "ENVIRONMENT"
+.sp
+See \c
+.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html" "the reference" " "
+for
+details on environment variables that Cargo reads.
+.SH "EXIT STATUS"
+.sp
+0
+.RS 4
+Cargo succeeded.
+.RE
+.sp
+101
+.RS 4
+Cargo failed to complete.
+.RE
+.SH "EXAMPLES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+. sp -1
+. IP " 1." 4.2
+.\}
+Vendor all dependencies into a local "vendor" folder
+.sp
+.if n .RS 4
+.nf
+cargo vendor
+.fi
+.if n .RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+. sp -1
+. IP " 2." 4.2
+.\}
+Vendor all dependencies into a local "third\-part/vendor" folder
+.sp
+.if n .RS 4
+.nf
+cargo vendor third\-party/vendor
+.fi
+.if n .RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+. sp -1
+. IP " 3." 4.2
+.\}
+Vendor the current workspace as well as another to "vendor"
+.sp
+.if n .RS 4
+.nf
+cargo vendor \-s ../path/to/Cargo.toml
+.fi
+.if n .RE
+.RE
+.SH "SEE ALSO"
+.sp
+\fBcargo\fP(1)
\ No newline at end of file
diff --git a/src/etc/man/cargo.1 b/src/etc/man/cargo.1
index f715eea6f..757510051 100644
--- a/src/etc/man/cargo.1
+++ b/src/etc/man/cargo.1
@@ -487,4 +487,4 @@ See \c
for issues.
.SH "SEE ALSO"
.sp
-\fBrustc\fP(1), \fBrustdoc\fP(1)
\ No newline at end of file
+\fBrustc\fP(1), \fBrustdoc\fP(1)
diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs
index a34277f34..682e4f00d 100644
--- a/tests/testsuite/main.rs
+++ b/tests/testsuite/main.rs
@@ -89,6 +89,7 @@ mod small_fd_limits;
mod test;
mod tool_paths;
mod update;
+mod vendor;
mod verify_project;
mod version;
mod warn_on_failure;
diff --git a/tests/testsuite/support/registry.rs b/tests/testsuite/support/registry.rs
index 023ece913..709f748ce 100644
--- a/tests/testsuite/support/registry.rs
+++ b/tests/testsuite/support/registry.rs
@@ -538,9 +538,7 @@ impl Package {
}
pub fn cksum(s: &[u8]) -> String {
- let mut sha = Sha256::new();
- sha.update(s);
- hex::encode(&sha.finish())
+ Sha256::new().update(s).finish_hex()
}
impl Dependency {
diff --git a/tests/testsuite/vendor.rs b/tests/testsuite/vendor.rs
new file mode 100644
index 000000000..aa5e93470
--- /dev/null
+++ b/tests/testsuite/vendor.rs
@@ -0,0 +1,508 @@
+use crate::support::git;
+use crate::support::registry::Package;
+use crate::support::{basic_lib_manifest, project, Project};
+
+#[test]
+fn vendor_simple() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ log = "0.3.5"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ Package::new("log", "0.3.5").publish();
+
+ p.cargo("vendor --respect-source-config").run();
+ let lock = p.read_file("vendor/log/Cargo.toml");
+ assert!(lock.contains("version = \"0.3.5\""));
+
+ add_vendor_config(&p);
+ p.cargo("build").run();
+}
+
+fn add_vendor_config(p: &Project) {
+ p.change_file(
+ ".cargo/config",
+ r#"
+ [source.crates-io]
+ replace-with = 'vendor'
+
+ [source.vendor]
+ directory = 'vendor'
+ "#,
+ );
+}
+
+#[test]
+fn two_versions() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "0.8.0"
+ bar = { path = "bar" }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "0.7.0"
+ "#,
+ )
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ Package::new("bitflags", "0.7.0").publish();
+ Package::new("bitflags", "0.8.0").publish();
+
+ p.cargo("vendor --respect-source-config").run();
+
+ let lock = p.read_file("vendor/bitflags/Cargo.toml");
+ assert!(lock.contains("version = \"0.8.0\""));
+ let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
+ assert!(lock.contains("version = \"0.7.0\""));
+
+ add_vendor_config(&p);
+ p.cargo("build").run();
+}
+
+#[test]
+fn help() {
+ let p = project().build();
+ p.cargo("vendor -h").run();
+}
+
+#[test]
+fn update_versions() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "0.7.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ Package::new("bitflags", "0.7.0").publish();
+ Package::new("bitflags", "0.8.0").publish();
+
+ p.cargo("vendor --respect-source-config").run();
+
+ let lock = p.read_file("vendor/bitflags/Cargo.toml");
+ assert!(lock.contains("version = \"0.7.0\""));
+
+ p.change_file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "0.8.0"
+ "#,
+ );
+ p.cargo("vendor --respect-source-config").run();
+
+ let lock = p.read_file("vendor/bitflags/Cargo.toml");
+ assert!(lock.contains("version = \"0.8.0\""));
+}
+
+#[test]
+fn two_lockfiles() {
+ let p = project()
+ .no_manifest()
+ .file(
+ "foo/Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "=0.7.0"
+ "#,
+ )
+ .file("foo/src/lib.rs", "")
+ .file(
+ "bar/Cargo.toml",
+ r#"
+ [package]
+ name = "bar"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "=0.8.0"
+ "#,
+ )
+ .file("bar/src/lib.rs", "")
+ .build();
+
+ Package::new("bitflags", "0.7.0").publish();
+ Package::new("bitflags", "0.8.0").publish();
+
+ p.cargo("vendor --respect-source-config -s bar/Cargo.toml --manifest-path foo/Cargo.toml")
+ .run();
+
+ let lock = p.read_file("vendor/bitflags/Cargo.toml");
+ assert!(lock.contains("version = \"0.8.0\""));
+ let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
+ assert!(lock.contains("version = \"0.7.0\""));
+
+ add_vendor_config(&p);
+ p.cargo("build").cwd("foo").run();
+ p.cargo("build").cwd("bar").run();
+}
+
+#[test]
+fn delete_old_crates() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ bitflags = "=0.7.0"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ Package::new("bitflags", "0.7.0").publish();
+ Package::new("log", "0.3.5").publish();
+
+ p.cargo("vendor --respect-source-config").run();
+ p.read_file("vendor/bitflags/Cargo.toml");
+
+ p.change_file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ log = "=0.3.5"
+ "#,
+ );
+
+ p.cargo("vendor --respect-source-config").run();
+ let lock = p.read_file("vendor/log/Cargo.toml");
+ assert!(lock.contains("version = \"0.3.5\""));
+ assert!(!p.root().join("vendor/bitflags/Cargo.toml").exists());
+}
+
+#[test]
+fn ignore_files() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ url = "1.4.1"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ Package::new("url", "1.4.1")
+ .file("src/lib.rs", "")
+ .file("foo.orig", "")
+ .file(".gitignore", "")
+ .file(".gitattributes", "")
+ .file("foo.rej", "")
+ .publish();
+
+ p.cargo("vendor --respect-source-config").run();
+ let csum = p.read_file("vendor/url/.cargo-checksum.json");
+ assert!(!csum.contains("foo.orig"));
+ assert!(!csum.contains(".gitignore"));
+ assert!(!csum.contains(".gitattributes"));
+ assert!(!csum.contains(".cargo-ok"));
+ assert!(!csum.contains("foo.rej"));
+}
+
+#[test]
+fn included_files_only() {
+ let git = git::new("a", |p| {
+ p.file("Cargo.toml", &basic_lib_manifest("a"))
+ .file("src/lib.rs", "")
+ .file(".gitignore", "a")
+ .file("a/b.md", "")
+ })
+ .unwrap();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
+ git.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("vendor --respect-source-config").run();
+ let csum = p.read_file("vendor/a/.cargo-checksum.json");
+ assert!(!csum.contains("a/b.md"));
+}
+
+#[test]
+fn dependent_crates_in_crates() {
+ let git = git::new("a", |p| {
+ p.file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+
+ [dependencies]
+ b = { path = 'b' }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("b/Cargo.toml", &basic_lib_manifest("b"))
+ .file("b/src/lib.rs", "")
+ })
+ .unwrap();
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
+ git.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("vendor --respect-source-config").run();
+ p.read_file("vendor/a/.cargo-checksum.json");
+ p.read_file("vendor/b/.cargo-checksum.json");
+}
+
+#[test]
+fn vendoring_git_crates() {
+ let git = git::new("git", |p| {
+ p.file("Cargo.toml", &basic_lib_manifest("serde_derive"))
+ .file("src/lib.rs", "")
+ .file("src/wut.rs", "")
+ })
+ .unwrap();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies.serde]
+ version = "0.5.0"
+
+ [dependencies.serde_derive]
+ version = "0.5.0"
+
+ [patch.crates-io]
+ serde_derive = {{ git = '{}' }}
+ "#,
+ git.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+ Package::new("serde", "0.5.0")
+ .dep("serde_derive", "0.5")
+ .publish();
+ Package::new("serde_derive", "0.5.0").publish();
+
+ p.cargo("vendor --respect-source-config").run();
+ p.read_file("vendor/serde_derive/src/wut.rs");
+
+ add_vendor_config(&p);
+ p.cargo("build").run();
+}
+
+#[test]
+fn git_simple() {
+ let git = git::new("git", |p| {
+ p.file("Cargo.toml", &basic_lib_manifest("a"))
+ .file("src/lib.rs", "")
+ })
+ .unwrap();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ "#,
+ git.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ p.cargo("vendor --respect-source-config").run();
+ let csum = p.read_file("vendor/a/.cargo-checksum.json");
+ assert!(csum.contains("\"package\":null"));
+}
+
+#[test]
+fn git_duplicate() {
+ let git = git::new("a", |p| {
+ p.file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "a"
+ version = "0.1.0"
+
+ [dependencies]
+ b = { path = 'b' }
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("b/Cargo.toml", &basic_lib_manifest("b"))
+ .file("b/src/lib.rs", "")
+ })
+ .unwrap();
+
+ let p = project()
+ .file(
+ "Cargo.toml",
+ &format!(
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ a = {{ git = '{}' }}
+ b = '0.5.0'
+
+ "#,
+ git.url()
+ ),
+ )
+ .file("src/lib.rs", "")
+ .build();
+ Package::new("b", "0.5.0").publish();
+
+ p.cargo("vendor --respect-source-config")
+ .with_stderr(
+ "\
+[UPDATING] [..]
+[UPDATING] [..]
+[DOWNLOADING] [..]
+[DOWNLOADED] [..]
+error: failed to sync
+
+Caused by:
+ found duplicate version of package `b v0.5.0` vendored from two sources:
+
+source 1: [..]
+source 2: [..]
+",
+ )
+ .with_status(101)
+ .run();
+}
+
+#[test]
+fn depend_on_vendor_dir_not_deleted() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ libc = "0.2.30"
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .build();
+
+ Package::new("libc", "0.2.30").publish();
+
+ p.cargo("vendor --respect-source-config").run();
+ assert!(p.root().join("vendor/libc").is_dir());
+
+ p.change_file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+
+ [dependencies]
+ libc = "0.2.30"
+
+ [patch.crates-io]
+ libc = { path = 'vendor/libc' }
+ "#,
+ );
+
+ p.cargo("vendor --respect-source-config").run();
+ assert!(p.root().join("vendor/libc").is_dir());
+}