Skip to content

Commit 1ae77f5

Browse files
committed
fix(vendor): Strip excluded build targets
This is a **very** hacky solution, duplicating the minimum of what `prepare_for_publish` does to fix this one issue and in the least intrusive way to the vendor code. The intention is to keep this low risk for backporting to beta and stable. We need to revisit this, refactoring the `cargo package` code so that we can call into that for each vendored dependency. Fixes #14348
1 parent 33862df commit 1ae77f5

File tree

3 files changed

+129
-70
lines changed

3 files changed

+129
-70
lines changed

src/cargo/ops/vendor.rs

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ fn sync(
221221
let pathsource = PathSource::new(src, id.source_id(), gctx);
222222
let paths = pathsource.list_files(pkg)?;
223223
let mut map = BTreeMap::new();
224-
cp_sources(pkg, src, &paths, &dst, &mut map, &mut tmp_buf)
224+
cp_sources(pkg, src, &paths, &dst, &mut map, &mut tmp_buf, gctx)
225225
.with_context(|| format!("failed to copy over vendored sources for: {}", id))?;
226226

227227
// Finally, emit the metadata about this package
@@ -317,6 +317,7 @@ fn cp_sources(
317317
dst: &Path,
318318
cksums: &mut BTreeMap<String, String>,
319319
tmp_buf: &mut [u8],
320+
gctx: &GlobalContext,
320321
) -> CargoResult<()> {
321322
for p in paths {
322323
let relative = p.strip_prefix(&src).unwrap();
@@ -360,7 +361,12 @@ fn cp_sources(
360361
let cksum = if dst.file_name() == Some(OsStr::new("Cargo.toml"))
361362
&& pkg.package_id().source_id().is_git()
362363
{
363-
let contents = pkg.manifest().to_normalized_contents()?;
364+
let packaged_files = paths
365+
.iter()
366+
.map(|p| p.strip_prefix(src).unwrap().to_owned())
367+
.collect::<Vec<_>>();
368+
let vendored_pkg = prepare_for_vendor(pkg, &packaged_files, gctx)?;
369+
let contents = vendored_pkg.manifest().to_normalized_contents()?;
364370
copy_and_checksum(
365371
&dst,
366372
&mut dst_opts,
@@ -392,6 +398,119 @@ fn cp_sources(
392398
Ok(())
393399
}
394400

401+
/// HACK: Perform the bare minimum of `prepare_for_publish` needed for #14348.
402+
///
403+
/// There are parts of `prepare_for_publish` that could be directly useful (e.g. stripping
404+
/// `[workspace]`) while other parts that require other filesystem operations (moving the README
405+
/// file) and ideally we'd reuse `cargo package` code to take care of all of this for us.
406+
fn prepare_for_vendor(
407+
me: &Package,
408+
packaged_files: &[PathBuf],
409+
gctx: &GlobalContext,
410+
) -> CargoResult<Package> {
411+
let contents = me.manifest().contents();
412+
let document = me.manifest().document();
413+
let original_toml = prepare_toml_for_vendor(
414+
me.manifest().normalized_toml().clone(),
415+
packaged_files,
416+
gctx,
417+
)?;
418+
let normalized_toml = original_toml.clone();
419+
let features = me.manifest().unstable_features().clone();
420+
let workspace_config = me.manifest().workspace_config().clone();
421+
let source_id = me.package_id().source_id();
422+
let mut warnings = Default::default();
423+
let mut errors = Default::default();
424+
let manifest = crate::util::toml::to_real_manifest(
425+
contents.to_owned(),
426+
document.clone(),
427+
original_toml,
428+
normalized_toml,
429+
features,
430+
workspace_config,
431+
source_id,
432+
me.manifest_path(),
433+
gctx,
434+
&mut warnings,
435+
&mut errors,
436+
)?;
437+
let new_pkg = Package::new(manifest, me.manifest_path());
438+
Ok(new_pkg)
439+
}
440+
441+
fn prepare_toml_for_vendor(
442+
mut me: cargo_util_schemas::manifest::TomlManifest,
443+
packaged_files: &[PathBuf],
444+
gctx: &GlobalContext,
445+
) -> CargoResult<cargo_util_schemas::manifest::TomlManifest> {
446+
let package = me
447+
.package
448+
.as_mut()
449+
.expect("venedored manifests must have packages");
450+
if let Some(cargo_util_schemas::manifest::StringOrBool::String(path)) = &package.build {
451+
let path = paths::normalize_path(Path::new(path));
452+
let included = packaged_files.contains(&path);
453+
let build = if included {
454+
let path = path
455+
.into_os_string()
456+
.into_string()
457+
.map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
458+
let path = crate::util::toml::normalize_path_string_sep(path);
459+
cargo_util_schemas::manifest::StringOrBool::String(path)
460+
} else {
461+
gctx.shell().warn(format!(
462+
"ignoring `package.build` as `{}` is not included in the published package",
463+
path.display()
464+
))?;
465+
cargo_util_schemas::manifest::StringOrBool::Bool(false)
466+
};
467+
package.build = Some(build);
468+
}
469+
470+
let lib = if let Some(target) = &me.lib {
471+
crate::util::toml::prepare_target_for_publish(
472+
target,
473+
Some(packaged_files),
474+
"library",
475+
gctx,
476+
)?
477+
} else {
478+
None
479+
};
480+
let bin = crate::util::toml::prepare_targets_for_publish(
481+
me.bin.as_ref(),
482+
Some(packaged_files),
483+
"binary",
484+
gctx,
485+
)?;
486+
let example = crate::util::toml::prepare_targets_for_publish(
487+
me.example.as_ref(),
488+
Some(packaged_files),
489+
"example",
490+
gctx,
491+
)?;
492+
let test = crate::util::toml::prepare_targets_for_publish(
493+
me.test.as_ref(),
494+
Some(packaged_files),
495+
"test",
496+
gctx,
497+
)?;
498+
let bench = crate::util::toml::prepare_targets_for_publish(
499+
me.bench.as_ref(),
500+
Some(packaged_files),
501+
"benchmark",
502+
gctx,
503+
)?;
504+
505+
me.lib = lib;
506+
me.bin = bin;
507+
me.example = example;
508+
me.test = test;
509+
me.bench = bench;
510+
511+
Ok(me)
512+
}
513+
395514
fn copy_and_checksum<T: Read>(
396515
dst_path: &Path,
397516
dst_opts: &mut OpenOptions,

src/cargo/util/toml/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,7 @@ fn deprecated_ws_default_features(
10861086
}
10871087

10881088
#[tracing::instrument(skip_all)]
1089-
fn to_real_manifest(
1089+
pub fn to_real_manifest(
10901090
contents: String,
10911091
document: toml_edit::ImDocument<String>,
10921092
original_toml: manifest::TomlManifest,
@@ -2889,7 +2889,7 @@ fn prepare_toml_for_publish(
28892889
}
28902890
}
28912891

2892-
fn prepare_targets_for_publish(
2892+
pub fn prepare_targets_for_publish(
28932893
targets: Option<&Vec<manifest::TomlTarget>>,
28942894
packaged_files: Option<&[PathBuf]>,
28952895
context: &str,
@@ -2915,7 +2915,7 @@ fn prepare_targets_for_publish(
29152915
}
29162916
}
29172917

2918-
fn prepare_target_for_publish(
2918+
pub fn prepare_target_for_publish(
29192919
target: &manifest::TomlTarget,
29202920
packaged_files: Option<&[PathBuf]>,
29212921
context: &str,
@@ -2950,7 +2950,7 @@ fn normalize_path_sep(path: PathBuf, context: &str) -> CargoResult<PathBuf> {
29502950
Ok(path.into())
29512951
}
29522952

2953-
fn normalize_path_string_sep(path: String) -> String {
2953+
pub fn normalize_path_string_sep(path: String) -> String {
29542954
if std::path::MAIN_SEPARATOR != '/' {
29552955
path.replace(std::path::MAIN_SEPARATOR, "/")
29562956
} else {

tests/testsuite/vendor.rs

Lines changed: 4 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,6 @@ fn discovery_inferred_build_rs_included() {
284284
# will likely look very different (and much more reasonable).
285285
# See Cargo.toml.orig for the original contents.
286286
287-
bin = []
288-
example = []
289-
test = []
290-
bench = []
291-
292287
[package]
293288
edition = "2015"
294289
name = "dep"
@@ -377,17 +372,12 @@ fn discovery_inferred_build_rs_excluded() {
377372
# will likely look very different (and much more reasonable).
378373
# See Cargo.toml.orig for the original contents.
379374
380-
bin = []
381-
example = []
382-
test = []
383-
bench = []
384-
385375
[package]
386376
edition = "2015"
387377
name = "dep"
388378
version = "0.0.1"
389379
authors = []
390-
build = "build.rs"
380+
build = false
391381
include = ["src/lib.rs"]
392382
autobins = false
393383
autoexamples = false
@@ -405,16 +395,7 @@ path = "src/lib.rs"
405395
"##]],
406396
);
407397

408-
p.cargo("check")
409-
.with_status(101)
410-
.with_stderr_data(str![[r#"
411-
[COMPILING] dep v0.0.1 ([ROOTURL]/dep#[..])
412-
[ERROR] couldn't read [ROOT]/foo/vendor/dep/build.rs: [NOT_FOUND]
413-
414-
[ERROR] could not compile `dep` (build script) due to 1 previous error
415-
416-
"#]])
417-
.run();
398+
p.cargo("check").run();
418399
}
419400

420401
#[cargo_test]
@@ -476,10 +457,6 @@ fn discovery_inferred_lib_included() {
476457
# will likely look very different (and much more reasonable).
477458
# See Cargo.toml.orig for the original contents.
478459
479-
example = []
480-
test = []
481-
bench = []
482-
483460
[package]
484461
edition = "2015"
485462
name = "dep"
@@ -572,10 +549,6 @@ fn discovery_inferred_lib_excluded() {
572549
# will likely look very different (and much more reasonable).
573550
# See Cargo.toml.orig for the original contents.
574551
575-
example = []
576-
test = []
577-
bench = []
578-
579552
[package]
580553
edition = "2015"
581554
name = "dep"
@@ -592,27 +565,14 @@ documentation = "docs.rs/foo"
592565
readme = false
593566
license = "MIT"
594567
595-
[lib]
596-
name = "dep"
597-
path = "src/lib.rs"
598-
599568
[[bin]]
600569
name = "dep"
601570
path = "src/main.rs"
602571
603572
"##]],
604573
);
605574

606-
p.cargo("check")
607-
.with_status(101)
608-
.with_stderr_data(str![[r#"
609-
[CHECKING] dep v0.0.1 ([ROOTURL]/dep#[..])
610-
[ERROR] couldn't read [ROOT]/foo/vendor/dep/src/lib.rs: [NOT_FOUND]
611-
612-
[ERROR] could not compile `dep` (lib) due to 1 previous error
613-
614-
"#]])
615-
.run();
575+
p.cargo("check").run();
616576
}
617577

618578
#[cargo_test]
@@ -807,22 +767,6 @@ license = "MIT"
807767
name = "dep"
808768
path = "src/lib.rs"
809769
810-
[[bin]]
811-
name = "foo"
812-
path = "src/bin/foo/main.rs"
813-
814-
[[example]]
815-
name = "example_foo"
816-
path = "examples/example_foo.rs"
817-
818-
[[test]]
819-
name = "test_foo"
820-
path = "tests/test_foo.rs"
821-
822-
[[bench]]
823-
name = "bench_foo"
824-
path = "benches/bench_foo.rs"
825-
826770
"##]],
827771
);
828772

@@ -1577,10 +1521,6 @@ fn git_deterministic() {
15771521
# will likely look very different (and much more reasonable).
15781522
# See Cargo.toml.orig for the original contents.
15791523
1580-
bin = []
1581-
test = []
1582-
bench = []
1583-
15841524
[package]
15851525
edition = "2021"
15861526
name = "git_dep"
@@ -1598,7 +1538,7 @@ license = "MIT"
15981538
15991539
[lib]
16001540
name = "git_dep"
1601-
path = [..]
1541+
path = "src/lib.rs"
16021542
16031543
[[example]]
16041544
name = "a"

0 commit comments

Comments
 (0)