Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/bin/cargo/commands/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ pub fn cli() -> App {
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_features()
.arg_package_spec(
"Package(s) to assemble",
"Assemble all packages in the workspace",
"Don't assemble specified packages",
)
.arg_manifest_path()
.arg_jobs()
.after_help("Run `cargo help package` for more detailed information.\n")
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let ws = args.workspace(config)?;
let specs = args.packages_from_flags()?;

ops::package(
&ws,
&PackageOpts {
Expand All @@ -43,10 +50,12 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
list: args.is_present("list"),
check_metadata: !args.is_present("no-metadata"),
allow_dirty: args.is_present("allow-dirty"),
to_package: specs,
targets: args.targets(),
jobs: args.jobs()?,
cli_features: args.cli_features()?,
},
)?;

Ok(())
}
2 changes: 2 additions & 0 deletions src/bin/cargo/commands/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub fn cli() -> App {
))
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg_package("Package to publish")
.arg_manifest_path()
.arg_features()
.arg_jobs()
Expand All @@ -41,6 +42,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
index,
verify: !args.is_present("no-verify"),
allow_dirty: args.is_present("allow-dirty"),
to_publish: args.packages_from_flags()?,
targets: args.targets(),
jobs: args.jobs()?,
dry_run: args.is_present("dry-run"),
Expand Down
94 changes: 70 additions & 24 deletions src/cargo/ops/cargo_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct PackageOpts<'cfg> {
pub allow_dirty: bool,
pub verify: bool,
pub jobs: Option<u32>,
pub to_package: ops::Packages,
pub targets: Vec<String>,
pub cli_features: CliFeatures,
}
Expand Down Expand Up @@ -61,16 +62,12 @@ enum GeneratedFile {
VcsInfo(String),
}

pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option<FileLock>> {
if ws.root().join("Cargo.lock").exists() {
// Make sure the Cargo.lock is up-to-date and valid.
let _ = ops::resolve_ws(ws)?;
// If Cargo.lock does not exist, it will be generated by `build_lock`
// below, and will be validated during the verification step.
}
let pkg = ws.current()?;
pub fn package_one(
ws: &Workspace<'_>,
pkg: &Package,
opts: &PackageOpts<'_>,
) -> CargoResult<Option<FileLock>> {
let config = ws.config();

let mut src = PathSource::new(pkg.root(), pkg.package_id().source_id(), config);
src.update()?;

Expand All @@ -96,12 +93,13 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option
None
};

let ar_files = build_ar_list(ws, pkg, src_files, vcs_info)?;
let ar_files = build_ar_list(&ws, pkg, src_files, vcs_info)?;

if opts.list {
for ar_file in ar_files {
drop_println!(config, "{}", ar_file.rel_str);
}

return Ok(None);
}

Expand All @@ -125,20 +123,65 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option
.shell()
.status("Packaging", pkg.package_id().to_string())?;
dst.file().set_len(0)?;
tar(ws, ar_files, dst.file(), &filename)
tar(&ws, pkg, ar_files, dst.file(), &filename)
.with_context(|| "failed to prepare local package for uploading")?;
if opts.verify {
dst.seek(SeekFrom::Start(0))?;
run_verify(ws, &dst, opts).with_context(|| "failed to verify package tarball")?
run_verify(&ws, pkg, &dst, opts).with_context(|| "failed to verify package tarball")?
}

dst.seek(SeekFrom::Start(0))?;
{
let src_path = dst.path();
let dst_path = dst.parent().join(&filename);
fs::rename(&src_path, &dst_path)
.with_context(|| "failed to move temporary tarball into final location")?;
let src_path = dst.path();
let dst_path = dst.parent().join(&filename);
fs::rename(&src_path, &dst_path)
.with_context(|| "failed to move temporary tarball into final location")?;

return Ok(Some(dst));
}

pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option<Vec<FileLock>>> {
let pkgs = ws.members_with_features(
&opts.to_package.to_package_id_specs(ws)?,
&opts.cli_features,
)?;

let mut dsts = Vec::with_capacity(pkgs.len());

if ws.root().join("Cargo.lock").exists() {
// Make sure the Cargo.lock is up-to-date and valid.
let _ = ops::resolve_ws(&ws)?;
// If Cargo.lock does not exist, it will be generated by `build_lock`
// below, and will be validated during the verification step.
}

for (pkg, cli_features) in pkgs {
let result = package_one(
ws,
pkg,
&PackageOpts {
config: opts.config,
list: opts.list,
check_metadata: opts.check_metadata,
allow_dirty: opts.allow_dirty,
verify: opts.verify,
jobs: opts.jobs,
to_package: ops::Packages::Default,
targets: opts.targets.clone(),
cli_features: cli_features,
},
)?;

if !opts.list {
dsts.push(result.unwrap());
}
}

if opts.list {
// We're just listing, so there's no file output
Ok(None)
} else {
Ok(Some(dsts))
}
Ok(Some(dst))
}

/// Builds list of files to archive.
Expand Down Expand Up @@ -265,12 +308,11 @@ fn build_ar_list(
}

/// Construct `Cargo.lock` for the package to be published.
fn build_lock(ws: &Workspace<'_>) -> CargoResult<String> {
fn build_lock(ws: &Workspace<'_>, orig_pkg: &Package) -> CargoResult<String> {
let config = ws.config();
let orig_resolve = ops::load_pkg_lockfile(ws)?;

// Convert Package -> TomlManifest -> Manifest -> Package
let orig_pkg = ws.current()?;
let toml_manifest = Rc::new(
orig_pkg
.manifest()
Expand Down Expand Up @@ -473,6 +515,7 @@ fn check_repo_state(

fn tar(
ws: &Workspace<'_>,
pkg: &Package,
ar_files: Vec<ArchiveFile>,
dst: &File,
filename: &str,
Expand All @@ -485,7 +528,6 @@ fn tar(

// Put all package files into a compressed archive.
let mut ar = Builder::new(encoder);
let pkg = ws.current()?;
let config = ws.config();

let base_name = format!("{}-{}", pkg.name(), pkg.version());
Expand Down Expand Up @@ -519,7 +561,7 @@ fn tar(
FileContents::Generated(generated_kind) => {
let contents = match generated_kind {
GeneratedFile::Manifest => pkg.to_registry_toml(ws)?,
GeneratedFile::Lockfile => build_lock(ws)?,
GeneratedFile::Lockfile => build_lock(ws, pkg)?,
GeneratedFile::VcsInfo(s) => s,
};
header.set_entry_type(EntryType::file());
Expand Down Expand Up @@ -647,9 +689,13 @@ fn check_yanked(config: &Config, pkg_set: &PackageSet<'_>, resolve: &Resolve) ->
Ok(())
}

fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> CargoResult<()> {
fn run_verify(
ws: &Workspace<'_>,
pkg: &Package,
tar: &FileLock,
opts: &PackageOpts<'_>,
) -> CargoResult<()> {
let config = ws.config();
let pkg = ws.current()?;

config.shell().status("Verifying", pkg)?;

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub use self::cargo_generate_lockfile::UpdateOptions;
pub use self::cargo_install::{install, install_list};
pub use self::cargo_new::{init, new, NewOptions, VersionControl};
pub use self::cargo_output_metadata::{output_metadata, ExportInfo, OutputMetadataOptions};
pub use self::cargo_package::{package, PackageOpts};
pub use self::cargo_package::{package, package_one, PackageOpts};
pub use self::cargo_pkgid::pkgid;
pub use self::cargo_read_manifest::{read_package, read_packages};
pub use self::cargo_run::run;
Expand Down
17 changes: 11 additions & 6 deletions src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,20 @@ pub struct PublishOpts<'cfg> {
pub verify: bool,
pub allow_dirty: bool,
pub jobs: Option<u32>,
pub to_publish: ops::Packages,
pub targets: Vec<String>,
pub dry_run: bool,
pub registry: Option<String>,
pub cli_features: CliFeatures,
}

pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {
let pkg = ws.current()?;
let mut publish_registry = opts.registry.clone();
let specs = opts.to_publish.to_package_id_specs(ws)?;
let mut pkgs = ws.members_with_features(&specs, &opts.cli_features)?;

let (pkg, cli_features) = pkgs.pop().unwrap();

let mut publish_registry = opts.registry.clone();
if let Some(ref allowed_registries) = *pkg.publish() {
if publish_registry.is_none() && allowed_registries.len() == 1 {
// If there is only one allowed registry, push to that one directly,
Expand Down Expand Up @@ -101,22 +105,23 @@ pub fn publish(ws: &Workspace<'_>, opts: &PublishOpts<'_>) -> CargoResult<()> {

// Prepare a tarball, with a non-suppressible warning if metadata
// is missing since this is being put online.
let tarball = ops::package(
ws,
let tarball = ops::package_one(
&ws,
pkg,
&ops::PackageOpts {
config: opts.config,
verify: opts.verify,
list: false,
check_metadata: true,
allow_dirty: opts.allow_dirty,
to_package: ops::Packages::Default,
targets: opts.targets.clone(),
jobs: opts.jobs,
cli_features: opts.cli_features.clone(),
cli_features: cli_features.clone(),
},
)?
.unwrap();

// Upload said tarball to the specified destination
opts.config
.shell()
.status("Uploading", pkg.package_id().to_string())?;
Expand Down
56 changes: 56 additions & 0 deletions tests/testsuite/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2105,3 +2105,59 @@ src/main.rs
.run();
p.cargo("package --allow-dirty").run();
}

#[cargo_test]
fn in_workspace() {
let p = project()
.file(
"Cargo.toml",
r#"
[project]
name = "foo"
version = "0.0.1"
authors = []
license = "MIT"
description = "foo"

[workspace]
members = ["bar"]
"#,
)
.file("src/main.rs", "fn main() {}")
.file(
"bar/Cargo.toml",
r#"
[project]
name = "bar"
version = "0.0.1"
authors = []
license = "MIT"
description = "bar"
workspace = ".."
"#,
)
.file("bar/src/main.rs", "fn main() {}")
.build();

p.cargo("package --workspace")
.with_stderr(
"\
[WARNING] manifest has no documentation, [..]
See [..]
[PACKAGING] bar v0.0.1 ([CWD]/bar)
[VERIFYING] bar v0.0.1 ([CWD]/bar)
[COMPILING] bar v0.0.1 ([CWD][..])
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
[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());
assert!(p.root().join("target/package/bar-0.0.1.crate").is_file());
}
Loading