Skip to content
This repository has been archived by the owner on Jun 21, 2019. It is now read-only.

Commit

Permalink
use cargo::sources to determine files to copy for vendoring
Browse files Browse the repository at this point in the history
This change has the effect of honoring package.{include,exclude}, and it
also correctly handles vendoring from non-crates.io sources when the
vendored crate contains depended-upon crates.

Fixes #137.
  • Loading branch information
froydnj committed Oct 31, 2018
1 parent 0e8c41a commit 90f9f45
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 16 deletions.
53 changes: 37 additions & 16 deletions src/main.rs
Expand Up @@ -360,8 +360,10 @@ fn sync(workspaces: &[Workspace],
&format!("{} ({}) to {}", id, src.to_string_lossy(), dst.display()))?;

let _ = fs::remove_dir_all(&dst);
let pathsource = cargo::sources::path::PathSource::new(&src, id.source_id(), config);
let paths = pathsource.list_files(&pkg)?;
let mut map = BTreeMap::new();
cp_r(&src, &dst, &dst, &mut map).chain_err(|| {
cp_sources(&src, &paths, &dst, &mut map).chain_err(|| {
format!("failed to copy over vendored sources for: {}", id)
})?;

Expand Down Expand Up @@ -476,15 +478,18 @@ fn sync(workspaces: &[Workspace],
Ok(VendorConfig { source: config })
}

fn cp_r(src: &Path,
dst: &Path,
root: &Path,
cksums: &mut BTreeMap<String, String>) -> io::Result<()> {
fn cp_sources(src: &Path,
paths: &Vec<PathBuf>,
dst: &Path,
cksums: &mut BTreeMap<String, String>) -> io::Result<()> {
let mut created_directories = BTreeSet::new();
fs::create_dir(dst)?;
for entry in src.read_dir()? {
let entry = entry?;
created_directories.insert(dst.to_owned());

match entry.file_name().to_str() {
for p in paths {
let relative = p.strip_prefix(&src).unwrap();

match relative.to_str() {
// Skip git config files as they're not relevant to builds most of
// the time and if we respect them (e.g. in git) then it'll
// probably mess with the checksums when a vendor dir is checked
Expand All @@ -505,17 +510,33 @@ fn cp_r(src: &Path,
}
}
_ => ()
};

let dst = dst.join(&relative);

// Create any necessary directories for the given file. We may need
// to create multiple directories, so loop until we find a directory
// we've already created.
let mut to_create = Vec::new();
{
let mut parent = dst.to_owned();
loop {
parent = parent.parent().unwrap().to_owned();
if created_directories.insert(parent.to_owned()) {
to_create.push(parent.to_owned());
} else {
break;
}
}
}

let src = entry.path();
let dst = dst.join(entry.file_name());
if entry.file_type()?.is_dir() {
cp_r(&src, &dst, root, cksums)?;
} else {
fs::copy(&src, &dst)?;
let rel = dst.strip_prefix(root).unwrap().to_str().unwrap();
cksums.insert(rel.replace("\\", "/"), sha256(&dst)?);
to_create.reverse();
for p in to_create.iter() {
fs::create_dir(&p)?;
}

fs::copy(&p, &dst)?;
cksums.insert(relative.to_str().unwrap().replace("\\", "/"), sha256(&dst)?);
}
Ok(())
}
Expand Down
21 changes: 21 additions & 0 deletions tests/vendor.rs
Expand Up @@ -304,6 +304,27 @@ fn ignore_files() {
assert!(!csum.contains("\"Cargo.toml.orig\""));
}

#[test]
fn included_files_only() {
let (dir, _lock) = dir();
// Use a fixed commit so we know what files are excluded.
file(&dir, "Cargo.toml", r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies.libc]
git = "https://github.com/rust-lang/libc"
rev = "b95fa265332df919e53eb66de5e6bd37fcd94041"
"#);
file(&dir, "src/lib.rs", "");

run(&mut vendor(&dir));
let csum = read(&dir.join("vendor/libc/.cargo-checksum.json"));
assert!(!csum.contains("\"ci/README.md\""));
assert!(!csum.contains("\"ci/docker/aarch64-linux-android\""));
}

#[test]
fn git_simple() {
let (dir, _lock) = dir();
Expand Down

0 comments on commit 90f9f45

Please sign in to comment.