Skip to content

Commit 7d20230

Browse files
committed
Include Cargo.lock in package checks.
This includes `Cargo.lock` in the git dirty check. It explicitly excludes `Cargo.lock` as an untracked file, since it is not relevant for the dirty check; it is only checked if it is committed to git. This also adds `Cargo.lock` to the "did anything modify this" check during verification. I don't see a reason to exclude it (particularly since ephemeral workspaces do not save the lock file). Also add "Archiving: Cargo.lock" to the verbose output.
1 parent 8a30158 commit 7d20230

File tree

4 files changed

+56
-21
lines changed

4 files changed

+56
-21
lines changed

src/cargo/core/package.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ impl Package {
236236
toml
237237
))
238238
}
239+
240+
/// Returns if package should include `Cargo.lock`.
241+
pub fn include_lockfile(&self) -> bool {
242+
self.manifest().publish_lockfile()
243+
&& self.targets().iter().any(|t| t.is_example() || t.is_bin())
244+
}
239245
}
240246

241247
impl fmt::Display for Package {

src/cargo/ops/cargo_package.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option
7979
.iter()
8080
.map(|file| file.strip_prefix(root).unwrap().to_path_buf())
8181
.collect();
82-
if include_lockfile(pkg) {
82+
if pkg.include_lockfile() && !list.contains(&PathBuf::from("Cargo.lock")) {
83+
// A generated Cargo.lock will be included.
8384
list.push("Cargo.lock".into());
8485
}
8586
if vcs_info.is_some() {
@@ -140,8 +141,7 @@ fn build_lock(ws: &Workspace<'_>) -> CargoResult<String> {
140141
// Regenerate Cargo.lock using the old one as a guide.
141142
let specs = vec![PackageIdSpec::from_package_id(new_pkg.package_id())];
142143
let tmp_ws = Workspace::ephemeral(new_pkg, ws.config(), None, true)?;
143-
let (pkg_set, new_resolve) =
144-
ops::resolve_ws_with_method(&tmp_ws, Method::Everything, &specs)?;
144+
let (pkg_set, new_resolve) = ops::resolve_ws_with_method(&tmp_ws, Method::Everything, &specs)?;
145145

146146
if let Some(orig_resolve) = orig_resolve {
147147
compare_resolve(config, tmp_ws.current()?, &orig_resolve, &new_resolve)?;
@@ -151,10 +151,6 @@ fn build_lock(ws: &Workspace<'_>) -> CargoResult<String> {
151151
ops::resolve_to_string(&tmp_ws, &new_resolve)
152152
}
153153

154-
fn include_lockfile(pkg: &Package) -> bool {
155-
pkg.manifest().publish_lockfile() && pkg.targets().iter().any(|t| t.is_example() || t.is_bin())
156-
}
157-
158154
// Checks that the package has some piece of metadata that a human can
159155
// use to tell what the package is about.
160156
fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> {
@@ -337,6 +333,10 @@ fn tar(
337333
let relative_str = relative.to_str().ok_or_else(|| {
338334
failure::format_err!("non-utf8 path in source directory: {}", relative.display())
339335
})?;
336+
if relative_str == "Cargo.lock" {
337+
// This is added manually below.
338+
continue;
339+
}
340340
config
341341
.shell()
342342
.verbose(|shell| shell.status("Archiving", &relative_str))?;
@@ -432,9 +432,12 @@ fn tar(
432432
.chain_err(|| internal(format!("could not archive source file `{}`", fnd)))?;
433433
}
434434

435-
if include_lockfile(pkg) {
435+
if pkg.include_lockfile() {
436436
let new_lock = build_lock(&ws)?;
437437

438+
config
439+
.shell()
440+
.verbose(|shell| shell.status("Archiving", "Cargo.lock"))?;
438441
let path = format!(
439442
"{}-{}{}Cargo.lock",
440443
pkg.name(),
@@ -534,7 +537,10 @@ fn compare_resolve(
534537
)
535538
}
536539
};
537-
let msg = format!("package `{}` added to the packaged Cargo.lock file{}", pkg_id, extra);
540+
let msg = format!(
541+
"package `{}` added to the packaged Cargo.lock file{}",
542+
pkg_id, extra
543+
);
538544
config.shell().status_with_color("Note", msg, Color::Cyan)?;
539545
}
540546
Ok(())
@@ -625,9 +631,7 @@ fn hash_all(path: &Path) -> CargoResult<HashMap<PathBuf, u64>> {
625631
fn wrap(path: &Path) -> CargoResult<HashMap<PathBuf, u64>> {
626632
let mut result = HashMap::new();
627633
let walker = walkdir::WalkDir::new(path).into_iter();
628-
for entry in walker.filter_entry(|e| {
629-
!(e.depth() == 1 && (e.file_name() == "target" || e.file_name() == "Cargo.lock"))
630-
}) {
634+
for entry in walker.filter_entry(|e| !(e.depth() == 1 && e.file_name() == "target")) {
631635
let entry = entry?;
632636
let file_type = entry.file_type();
633637
if file_type.is_file() {

src/cargo/sources/path.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,13 @@ impl<'cfg> PathSource<'cfg> {
240240
}
241241
}
242242

243-
// Update to `ignore_should_package` for Stage 2.
244-
Ok(glob_should_package)
243+
let should_include = match path.file_name().and_then(|s| s.to_str()) {
244+
Some("Cargo.lock") => pkg.include_lockfile(),
245+
// Update to `ignore_should_package` for Stage 2.
246+
_ => glob_should_package,
247+
};
248+
249+
Ok(should_include)
245250
};
246251

247252
// Attempt Git-prepopulate only if no `include` (see rust-lang/cargo#4135).
@@ -332,7 +337,11 @@ impl<'cfg> PathSource<'cfg> {
332337
}
333338
let statuses = repo.statuses(Some(&mut opts))?;
334339
let untracked = statuses.iter().filter_map(|entry| match entry.status() {
335-
git2::Status::WT_NEW => Some((join(root, entry.path_bytes()), None)),
340+
// Don't include Cargo.lock if it is untracked. Packaging will
341+
// generate a new one as needed.
342+
git2::Status::WT_NEW if entry.path() != Some("Cargo.lock") => {
343+
Some((join(root, entry.path_bytes()), None))
344+
}
336345
_ => None,
337346
});
338347

@@ -342,17 +351,15 @@ impl<'cfg> PathSource<'cfg> {
342351
let file_path = file_path?;
343352

344353
// Filter out files blatantly outside this package. This is helped a
345-
// bit obove via the `pathspec` function call, but we need to filter
354+
// bit above via the `pathspec` function call, but we need to filter
346355
// the entries in the index as well.
347356
if !file_path.starts_with(pkg_path) {
348357
continue;
349358
}
350359

351360
match file_path.file_name().and_then(|s| s.to_str()) {
352-
// Filter out `Cargo.lock` and `target` always; we don't want to
353-
// package a lock file no one will ever read and we also avoid
354-
// build artifacts.
355-
Some("Cargo.lock") | Some("target") => continue,
361+
// The `target` directory is never included.
362+
Some("target") => continue,
356363

357364
// Keep track of all sub-packages found and also strip out all
358365
// matches we've found so far. Note, though, that if we find
@@ -467,7 +474,7 @@ impl<'cfg> PathSource<'cfg> {
467474
if is_root {
468475
// Skip Cargo artifacts.
469476
match name {
470-
Some("target") | Some("Cargo.lock") => continue,
477+
Some("target") => continue,
471478
_ => {}
472479
}
473480
}

tests/testsuite/publish_lockfile.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,23 @@ fn package_lockfile_git_repo() {
8787
Cargo.lock
8888
Cargo.toml
8989
src/main.rs
90+
",
91+
)
92+
.run();
93+
cargo_process("package -v")
94+
.cwd(g.root())
95+
.masquerade_as_nightly_cargo()
96+
.with_stderr(
97+
"\
98+
[PACKAGING] foo v0.0.1 ([..])
99+
[ARCHIVING] Cargo.toml
100+
[ARCHIVING] src/main.rs
101+
[ARCHIVING] .cargo_vcs_info.json
102+
[ARCHIVING] Cargo.lock
103+
[VERIFYING] foo v0.0.1 ([..])
104+
[COMPILING] foo v0.0.1 ([..])
105+
[RUNNING] `rustc --crate-name foo src/main.rs [..]
106+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
90107
",
91108
)
92109
.run();
@@ -185,6 +202,7 @@ fn note_resolve_changes() {
185202
[PACKAGING] foo v0.0.1 ([..])
186203
[ARCHIVING] Cargo.toml
187204
[ARCHIVING] src/main.rs
205+
[ARCHIVING] Cargo.lock
188206
[UPDATING] `[..]` index
189207
[NOTE] package `mutli v0.1.0` added to the packaged Cargo.lock file, was originally sourced from `[..]/foo/mutli`
190208
[NOTE] package `patched v1.0.0` added to the packaged Cargo.lock file, was originally sourced from `[..]/foo/patched`

0 commit comments

Comments
 (0)