Skip to content

Commit 3235a3d

Browse files
committed
vendor: implement --explicit-version
Implement --explicit-version from standalone cargo-vendor. This helps with vendoring performance as it avoids redundantly deleting and re-copying already vendored packages. For example, when re-vendoring cargo's dependencies it makes a big improvement on wallclock time. For initial vendoring it makes no difference, but re-vendoring (ie, when most or all dependencies haven't changed) without explicit versions is actually slightly slower (5.8s -> 6s), but with explicit versions it goes from 5.8s -> 1.6s. Timings: Without explicit versions, initial vendor real 0m5.810s user 0m0.924s sys 0m2.491s Re-vendor: real 0m6.083s user 0m0.937s sys 0m2.654s With explicit versions, initial vendor: real 0m5.810s user 0m0.937s sys 0m2.461s Re-vendor: real 0m1.567s user 0m0.578s sys 0m0.967s The summaries of syscalls executed shows why: Revendoring without explicit versions: ``` % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 25.17 1.104699 18 59432 1065 openat 19.86 0.871574 21 41156 13825 unlink 13.64 0.598739 2 210510 lstat 9.02 0.395948 29 13208 copy_file_range 8.00 0.351242 11 30245 read 6.36 0.279005 3 72487 4476 statx 5.35 0.235027 6 37219 write 4.02 0.176267 3 58368 close ``` with explicit versions: ``` 29.38 0.419068 15 27798 13825 unlink 25.52 0.364021 1 209586 lstat 20.67 0.294788 16 17967 1032 openat 10.42 0.148586 4 35646 write 3.53 0.050350 3 13825 chmod 3.14 0.044786 2 16701 1622 statx 2.19 0.031171 1 16936 close 1.86 0.026538 24 1078 rmdir ``` Specifically, there are a lot fewer opens, copy_file_ranges, and unlinks.
1 parent abba15f commit 3235a3d

File tree

3 files changed

+54
-9
lines changed

3 files changed

+54
-9
lines changed

src/bin/cargo/commands/vendor.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ pub fn cli() -> App {
2727
.help("Respect `[source]` config in `.cargo/config`")
2828
.multiple(true),
2929
)
30+
.arg(
31+
Arg::with_name("explicit-version")
32+
.short("-x")
33+
.long("explicit-version")
34+
.help("Always include version in subdir name"),
35+
)
3036
.arg(
3137
Arg::with_name("no-merge-sources")
3238
.long("no-merge-sources")
@@ -42,12 +48,6 @@ pub fn cli() -> App {
4248
.long("only-git-deps")
4349
.hidden(true),
4450
)
45-
.arg(
46-
Arg::with_name("explicit-version")
47-
.short("-x")
48-
.long("explicit-version")
49-
.hidden(true),
50-
)
5151
.arg(
5252
Arg::with_name("disallow-duplicates")
5353
.long("disallow-duplicates")
@@ -85,8 +85,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
8585
Some("--relative-path")
8686
} else if args.is_present("only-git-deps") {
8787
Some("--only-git-deps")
88-
} else if args.is_present("explicit-version") {
89-
Some("--explicit-version")
9088
} else if args.is_present("disallow-duplicates") {
9189
Some("--disallow-duplicates")
9290
} else {
@@ -116,6 +114,7 @@ https://github.com/rust-lang/cargo/issues/new
116114
&ops::VendorOptions {
117115
no_delete: args.is_present("no-delete"),
118116
destination: &path,
117+
explicit_version: args.is_present("explicit-version"),
119118
extra: args
120119
.values_of_os("tomls")
121120
.unwrap_or_default()

src/cargo/ops/vendor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::path::{Path, PathBuf};
1414

1515
pub struct VendorOptions<'a> {
1616
pub no_delete: bool,
17+
pub explicit_version: bool,
1718
pub destination: &'a Path,
1819
pub extra: Vec<PathBuf>,
1920
}
@@ -186,7 +187,7 @@ fn sync(
186187
.parent()
187188
.expect("manifest_path should point to a file");
188189
let max_version = *versions[&id.name()].iter().rev().next().unwrap().0;
189-
let dir_has_version_suffix = id.version() != max_version;
190+
let dir_has_version_suffix = opts.explicit_version || id.version() != max_version;
190191
let dst_name = if dir_has_version_suffix {
191192
// Eg vendor/futures-0.1.13
192193
format!("{}-{}", id.name(), id.version())

tests/testsuite/vendor.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,51 @@ fn two_versions() {
8888
p.cargo("build").run();
8989
}
9090

91+
#[cargo_test]
92+
fn two_explicit_versions() {
93+
let p = project()
94+
.file(
95+
"Cargo.toml",
96+
r#"
97+
[package]
98+
name = "foo"
99+
version = "0.1.0"
100+
101+
[dependencies]
102+
bitflags = "0.8.0"
103+
bar = { path = "bar" }
104+
"#,
105+
)
106+
.file("src/lib.rs", "")
107+
.file(
108+
"bar/Cargo.toml",
109+
r#"
110+
[package]
111+
name = "bar"
112+
version = "0.1.0"
113+
114+
[dependencies]
115+
bitflags = "0.7.0"
116+
"#,
117+
)
118+
.file("bar/src/lib.rs", "")
119+
.build();
120+
121+
Package::new("bitflags", "0.7.0").publish();
122+
Package::new("bitflags", "0.8.0").publish();
123+
124+
p.cargo("vendor --respect-source-config --explicit-version")
125+
.run();
126+
127+
let lock = p.read_file("vendor/bitflags-0.8.0/Cargo.toml");
128+
assert!(lock.contains("version = \"0.8.0\""));
129+
let lock = p.read_file("vendor/bitflags-0.7.0/Cargo.toml");
130+
assert!(lock.contains("version = \"0.7.0\""));
131+
132+
add_vendor_config(&p);
133+
p.cargo("build").run();
134+
}
135+
91136
#[cargo_test]
92137
fn help() {
93138
let p = project().build();

0 commit comments

Comments
 (0)