From ebb5764ad80a1c2a985c6b08217e3adf0ece00f5 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 5 Apr 2019 13:25:08 -0700 Subject: [PATCH 01/12] Move publish-lockfile tests to a dedicated file. --- tests/testsuite/main.rs | 1 + tests/testsuite/package.rs | 167 --------------------------- tests/testsuite/publish_lockfile.rs | 171 ++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 167 deletions(-) create mode 100644 tests/testsuite/publish_lockfile.rs diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs index 95030c03718..ddc922ce894 100644 --- a/tests/testsuite/main.rs +++ b/tests/testsuite/main.rs @@ -68,6 +68,7 @@ mod profile_overrides; mod profile_targets; mod profiles; mod publish; +mod publish_lockfile; mod read_manifest; mod registry; mod rename_deps; diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 2b2a3555007..64a2e051b1a 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1018,173 +1018,6 @@ Caused by: .run(); } -#[test] -fn package_lockfile() { - let p = project() - .file( - "Cargo.toml", - r#" - cargo-features = ["publish-lockfile"] - - [project] - name = "foo" - version = "0.0.1" - authors = [] - license = "MIT" - description = "foo" - publish-lockfile = true - "#, - ) - .file("src/main.rs", "fn main() {}") - .build(); - - p.cargo("package") - .masquerade_as_nightly_cargo() - .with_stderr( - "\ -[WARNING] manifest has no documentation[..] -See [..] -[PACKAGING] foo v0.0.1 ([CWD]) -[VERIFYING] foo v0.0.1 ([CWD]) -[COMPILING] foo v0.0.1 ([CWD][..]) -[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] -", - ) - .run(); - assert!(p.root().join("target/package/foo-0.0.1.crate").is_file()); - p.cargo("package -l") - .masquerade_as_nightly_cargo() - .with_stdout( - "\ -Cargo.lock -Cargo.toml -src/main.rs -", - ) - .run(); - p.cargo("package") - .masquerade_as_nightly_cargo() - .with_stdout("") - .run(); - - let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - validate_crate_contents( - f, - "foo-0.0.1.crate", - &["Cargo.toml", "Cargo.toml.orig", "Cargo.lock", "src/main.rs"], - &[], - ); -} - -#[test] -fn package_lockfile_git_repo() { - let p = project().build(); - - // Create a Git repository containing a minimal Rust project. - let _ = git::repo(&paths::root().join("foo")) - .file( - "Cargo.toml", - r#" - cargo-features = ["publish-lockfile"] - - [project] - name = "foo" - version = "0.0.1" - license = "MIT" - description = "foo" - documentation = "foo" - homepage = "foo" - repository = "foo" - publish-lockfile = true - "#, - ) - .file("src/main.rs", "fn main() {}") - .build(); - p.cargo("package -l") - .masquerade_as_nightly_cargo() - .with_stdout( - "\ -.cargo_vcs_info.json -Cargo.lock -Cargo.toml -src/main.rs -", - ) - .run(); -} - -#[test] -fn no_lock_file_with_library() { - let p = project() - .file( - "Cargo.toml", - r#" - cargo-features = ["publish-lockfile"] - - [project] - name = "foo" - version = "0.0.1" - authors = [] - license = "MIT" - description = "foo" - publish-lockfile = true - "#, - ) - .file("src/lib.rs", "") - .build(); - - p.cargo("package").masquerade_as_nightly_cargo().run(); - - let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - validate_crate_contents( - f, - "foo-0.0.1.crate", - &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"], - &[], - ); -} - -#[test] -fn lock_file_and_workspace() { - let p = project() - .file( - "Cargo.toml", - r#" - [workspace] - members = ["foo"] - "#, - ) - .file( - "foo/Cargo.toml", - r#" - cargo-features = ["publish-lockfile"] - - [package] - name = "foo" - version = "0.0.1" - authors = [] - license = "MIT" - description = "foo" - publish-lockfile = true - "#, - ) - .file("foo/src/main.rs", "fn main() {}") - .build(); - - p.cargo("package") - .cwd("foo") - .masquerade_as_nightly_cargo() - .run(); - - let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); - validate_crate_contents( - f, - "foo-0.0.1.crate", - &["Cargo.toml", "Cargo.toml.orig", "src/main.rs", "Cargo.lock"], - &[], - ); -} - #[test] fn do_not_package_if_src_was_modified() { let p = project() diff --git a/tests/testsuite/publish_lockfile.rs b/tests/testsuite/publish_lockfile.rs new file mode 100644 index 00000000000..5aa0caa3f10 --- /dev/null +++ b/tests/testsuite/publish_lockfile.rs @@ -0,0 +1,171 @@ +use std; +use std::fs::File; + +use crate::support::{git, paths, project, publish::validate_crate_contents}; + +#[test] +fn package_lockfile() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["publish-lockfile"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish-lockfile = true + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("package") + .masquerade_as_nightly_cargo() + .with_stderr( + "\ +[WARNING] manifest has no documentation[..] +See [..] +[PACKAGING] foo v0.0.1 ([CWD]) +[VERIFYING] foo v0.0.1 ([CWD]) +[COMPILING] foo v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + assert!(p.root().join("target/package/foo-0.0.1.crate").is_file()); + p.cargo("package -l") + .masquerade_as_nightly_cargo() + .with_stdout( + "\ +Cargo.lock +Cargo.toml +src/main.rs +", + ) + .run(); + p.cargo("package") + .masquerade_as_nightly_cargo() + .with_stdout("") + .run(); + + let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "Cargo.lock", "src/main.rs"], + &[], + ); +} + +#[test] +fn package_lockfile_git_repo() { + let p = project().build(); + + // Create a Git repository containing a minimal Rust project. + let _ = git::repo(&paths::root().join("foo")) + .file( + "Cargo.toml", + r#" + cargo-features = ["publish-lockfile"] + + [project] + name = "foo" + version = "0.0.1" + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + publish-lockfile = true + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("package -l") + .masquerade_as_nightly_cargo() + .with_stdout( + "\ +.cargo_vcs_info.json +Cargo.lock +Cargo.toml +src/main.rs +", + ) + .run(); +} + +#[test] +fn no_lock_file_with_library() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["publish-lockfile"] + + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish-lockfile = true + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("package").masquerade_as_nightly_cargo().run(); + + let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"], + &[], + ); +} + +#[test] +fn lock_file_and_workspace() { + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["foo"] + "#, + ) + .file( + "foo/Cargo.toml", + r#" + cargo-features = ["publish-lockfile"] + + [package] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + publish-lockfile = true + "#, + ) + .file("foo/src/main.rs", "fn main() {}") + .build(); + + p.cargo("package") + .cwd("foo") + .masquerade_as_nightly_cargo() + .run(); + + let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs", "Cargo.lock"], + &[], + ); +} From 27932ead44548259e150756df00e40a1feecbc33 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 7 Apr 2019 14:58:56 -0700 Subject: [PATCH 02/12] publish-lockfile: Always check Cargo.lock is up-to-date. This changes it so that `cargo package` will make sure the Cargo.lock file is in sync with the Cargo.toml that is generated during packaging. This has several points: - This makes the Cargo.lock more accurately reflect what would be locked if a user runs `cargo install` on the resulting package. - In a workspace, this removes irrelevant packages from the lock file. - This handles `[patch]` dependencies and dual-source dependencies (like path/version). - Warnings are generated for any differences in the lock file compared to the original. This has a significant change in how `cargo package` works. It now unconditionally copies the package to `target/package`. Previously this was only done during the verification step. This is necessary to run the resolver against the new `Cargo.toml` that gets generated. --- src/cargo/ops/cargo_package.rs | 179 +++++++++++++++---- tests/testsuite/publish_lockfile.rs | 267 +++++++++++++++++++++------- 2 files changed, 347 insertions(+), 99 deletions(-) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 6409d7780de..35f73a495e5 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -1,18 +1,18 @@ -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use std::fs::{self, File}; use std::io::prelude::*; use std::io::SeekFrom; use std::path::{self, Path, PathBuf}; use std::sync::Arc; -use flate2::read::GzDecoder; use flate2::{Compression, GzBuilder}; use log::debug; use serde_json::{self, json}; -use tar::{Archive, Builder, EntryType, Header}; +use tar::{Builder, EntryType, Header}; use crate::core::compiler::{BuildConfig, CompileMode, DefaultExecutor, Executor}; -use crate::core::{Package, Source, SourceId, Workspace}; +use crate::core::resolver::Method; +use crate::core::{Package, PackageId, PackageIdSpec, Resolve, Source, SourceId, Workspace}; use crate::ops; use crate::sources::PathSource; use crate::util::errors::{CargoResult, CargoResultExt}; @@ -35,7 +35,6 @@ pub struct PackageOpts<'cfg> { static VCS_INFO_FILE: &'static str = ".cargo_vcs_info.json"; pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult> { - ops::resolve_ws(ws)?; let pkg = ws.current()?; let config = ws.config(); @@ -100,7 +99,7 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult