diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 037d53ba9..84115a6da 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -330,7 +330,7 @@ fn run_verify(ws: &Workspace, tar: &FileLock, opts: &PackageOpts) -> CargoResult let id = SourceId::for_path(&dst)?; let mut src = PathSource::new(&dst, &id, ws.config()); let new_pkg = src.root_package()?; - let pkg_fingerprint = src.fingerprint(&new_pkg)?; + let pkg_fingerprint = src.last_modified_file(&new_pkg)?; let ws = Workspace::ephemeral(new_pkg, config, None, true)?; ops::compile_ws( @@ -354,11 +354,14 @@ fn run_verify(ws: &Workspace, tar: &FileLock, opts: &PackageOpts) -> CargoResult )?; // Check that build.rs didn't modify any files in the src directory. - let ws_fingerprint = src.fingerprint(ws.current()?)?; + let ws_fingerprint = src.last_modified_file(ws.current()?)?; if pkg_fingerprint != ws_fingerprint { + let (_, path) = ws_fingerprint; bail!( "Source directory was modified by build.rs during cargo publish. \ - Build scripts should not modify anything outside of OUT_DIR." + Build scripts should not modify anything outside of OUT_DIR. \ + Modified file: {}", + path.display() ) } diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index c7a0fdf75..f058b2570 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -467,6 +467,29 @@ impl<'cfg> PathSource<'cfg> { } Ok(()) } + + pub fn last_modified_file(&self, pkg: &Package) -> CargoResult<(FileTime, PathBuf)> { + if !self.updated { + return Err(internal("BUG: source was not updated")); + } + + let mut max = FileTime::zero(); + let mut max_path = PathBuf::new(); + for file in self.list_files(pkg)? { + // An fs::stat error here is either because path is a + // broken symlink, a permissions error, or a race + // condition where this path was rm'ed - either way, + // we can ignore the error and treat the path's mtime + // as 0. + let mtime = paths::mtime(&file).unwrap_or(FileTime::zero()); + if mtime > max { + max = mtime; + max_path = file; + } + } + trace!("last modified file {}: {}", self.path.display(), max); + Ok((max, max_path)) + } } impl<'cfg> Debug for PathSource<'cfg> { @@ -516,26 +539,7 @@ impl<'cfg> Source for PathSource<'cfg> { } fn fingerprint(&self, pkg: &Package) -> CargoResult { - if !self.updated { - return Err(internal("BUG: source was not updated")); - } - - let mut max = FileTime::zero(); - let mut max_path = PathBuf::from(""); - for file in self.list_files(pkg)? { - // An fs::stat error here is either because path is a - // broken symlink, a permissions error, or a race - // condition where this path was rm'ed - either way, - // we can ignore the error and treat the path's mtime - // as 0. - let mtime = paths::mtime(&file).unwrap_or(FileTime::zero()); - warn!("{} {}", mtime, file.display()); - if mtime > max { - max = mtime; - max_path = file; - } - } - trace!("fingerprint {}: {}", self.path.display(), max); + let (max, max_path) = self.last_modified_file(pkg)?; Ok(format!("{} ({})", max, max_path.display())) } }