Skip to content

Commit 465a3f0

Browse files
committed
fix(vendor): Make vendor use Manifest's "original" Cargo.toml
1 parent ba607b2 commit 465a3f0

File tree

2 files changed

+97
-17
lines changed

2 files changed

+97
-17
lines changed

src/cargo/ops/vendor.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::core::shell::Verbosity;
2-
use crate::core::{GitReference, Workspace};
2+
use crate::core::{GitReference, Package, Workspace};
33
use crate::ops;
44
use crate::sources::path::PathSource;
55
use crate::sources::CRATES_IO_REGISTRY;
@@ -9,6 +9,7 @@ use cargo_util::{paths, Sha256};
99
use serde::Serialize;
1010
use std::collections::HashSet;
1111
use std::collections::{BTreeMap, BTreeSet, HashMap};
12+
use std::ffi::OsStr;
1213
use std::fs::{self, File, OpenOptions};
1314
use std::io::{Read, Write};
1415
use std::path::{Path, PathBuf};
@@ -225,7 +226,7 @@ fn sync(
225226
let pathsource = PathSource::new(src, id.source_id(), config);
226227
let paths = pathsource.list_files(pkg)?;
227228
let mut map = BTreeMap::new();
228-
cp_sources(src, &paths, &dst, &mut map, &mut tmp_buf)
229+
cp_sources(pkg, src, &paths, &dst, &mut map, &mut tmp_buf)
229230
.with_context(|| format!("failed to copy over vendored sources for: {}", id))?;
230231

231232
// Finally, emit the metadata about this package
@@ -313,6 +314,7 @@ fn sync(
313314
}
314315

315316
fn cp_sources(
317+
pkg: &Package,
316318
src: &Path,
317319
paths: &[PathBuf],
318320
dst: &Path,
@@ -352,35 +354,52 @@ fn cp_sources(
352354
.fold(dst.to_owned(), |acc, component| acc.join(&component));
353355

354356
paths::create_dir_all(dst.parent().unwrap())?;
357+
let mut dst_opts = OpenOptions::new();
358+
dst_opts.write(true).create(true).truncate(true);
359+
let cksum = if dst.file_name() == Some(OsStr::new("Cargo.toml")) {
360+
let contents = toml::to_string_pretty(pkg.manifest().original())?;
361+
copy_and_checksum(
362+
&dst,
363+
&mut dst_opts,
364+
&mut contents.as_bytes(),
365+
"Generated Cargo.toml",
366+
tmp_buf,
367+
)?
368+
} else {
369+
let mut src = File::open(&p).with_context(|| format!("failed to open {:?}", &p))?;
370+
#[cfg(unix)]
371+
{
372+
use std::os::unix::fs::{MetadataExt, OpenOptionsExt};
373+
let src_metadata = src
374+
.metadata()
375+
.with_context(|| format!("failed to stat {:?}", p))?;
376+
dst_opts.mode(src_metadata.mode());
377+
}
378+
copy_and_checksum(&dst, &mut dst_opts, &mut src, p.to_str().unwrap(), tmp_buf)?
379+
};
355380

356-
let cksum = copy_and_checksum(p, &dst, tmp_buf)?;
357381
cksums.insert(relative.to_str().unwrap().replace("\\", "/"), cksum);
358382
}
359383
Ok(())
360384
}
361385

362-
fn copy_and_checksum(src_path: &Path, dst_path: &Path, buf: &mut [u8]) -> CargoResult<String> {
363-
let mut src = File::open(src_path).with_context(|| format!("failed to open {:?}", src_path))?;
364-
let mut dst_opts = OpenOptions::new();
365-
dst_opts.write(true).create(true).truncate(true);
366-
#[cfg(unix)]
367-
{
368-
use std::os::unix::fs::{MetadataExt, OpenOptionsExt};
369-
let src_metadata = src
370-
.metadata()
371-
.with_context(|| format!("failed to stat {:?}", src_path))?;
372-
dst_opts.mode(src_metadata.mode());
373-
}
386+
fn copy_and_checksum<T: Read>(
387+
dst_path: &Path,
388+
dst_opts: &mut OpenOptions,
389+
contents: &mut T,
390+
contents_path: &str,
391+
buf: &mut [u8],
392+
) -> CargoResult<String> {
374393
let mut dst = dst_opts
375394
.open(dst_path)
376395
.with_context(|| format!("failed to create {:?}", dst_path))?;
377396
// Not going to bother setting mode on pre-existing files, since there
378397
// shouldn't be any under normal conditions.
379398
let mut cksum = Sha256::new();
380399
loop {
381-
let n = src
400+
let n = contents
382401
.read(buf)
383-
.with_context(|| format!("failed to read from {:?}", src_path))?;
402+
.with_context(|| format!("failed to read from {:?}", contents_path))?;
384403
if n == 0 {
385404
break Ok(cksum.finish_hex());
386405
}

tests/testsuite/vendor.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -926,3 +926,64 @@ fn no_remote_dependency_no_vendor() {
926926
.run();
927927
assert!(!p.root().join("vendor").exists());
928928
}
929+
930+
#[cargo_test]
931+
fn vendor_crate_with_ws_inherit() {
932+
let git = git::new("ws", |p| {
933+
p.file(
934+
"Cargo.toml",
935+
r#"
936+
[workspace]
937+
members = ["bar"]
938+
[workspace.package]
939+
version = "0.1.0"
940+
"#,
941+
)
942+
.file(
943+
"bar/Cargo.toml",
944+
r#"
945+
[package]
946+
name = "bar"
947+
version.workspace = true
948+
"#,
949+
)
950+
.file("bar/src/lib.rs", "")
951+
});
952+
953+
let p = project()
954+
.file(
955+
"Cargo.toml",
956+
&format!(
957+
r#"
958+
[package]
959+
name = "foo"
960+
version = "0.1.0"
961+
962+
[dependencies]
963+
bar = {{ git = '{}' }}
964+
"#,
965+
git.url()
966+
),
967+
)
968+
.file("src/lib.rs", "")
969+
.build();
970+
971+
p.cargo("vendor --respect-source-config").run();
972+
p.change_file(
973+
".cargo/config",
974+
&format!(
975+
r#"
976+
[source."{}"]
977+
git = "{}"
978+
replace-with = "vendor"
979+
980+
[source.vendor]
981+
directory = "vendor"
982+
"#,
983+
git.url(),
984+
git.url()
985+
),
986+
);
987+
988+
p.cargo("check").run()
989+
}

0 commit comments

Comments
 (0)