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
27 changes: 22 additions & 5 deletions src/cargo/ops/cargo_package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ fn create_package(
}

let filename = pkg.package_id().tarball_name();
let dir = ws.target_dir().join("package");
let dir = ws.build_dir().join("package");
let mut dst = {
let tmp = format!(".{}", filename);
dir.open_rw_exclusive_create(&tmp, gctx, "package scratch space")?
Expand Down Expand Up @@ -217,10 +217,27 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Vec<Fi
// So we need filter
pkgs.retain(|(pkg, _feats)| specs.iter().any(|spec| spec.matches(pkg.package_id())));

Ok(do_package(ws, opts, pkgs)?
.into_iter()
.map(|x| x.2)
.collect())
let packaged = do_package(ws, opts, pkgs)?;

let mut result = Vec::new();
let target_dir = ws.target_dir();
let build_dir = ws.build_dir();
if target_dir == build_dir {
result.extend(packaged.into_iter().map(|(_, _, src)| src));
} else {
// Uplifting artifacts
let artifact_dir = target_dir.join("package");
for (pkg, _, src) in packaged {
let filename = pkg.package_id().tarball_name();
let dst =
artifact_dir.open_rw_exclusive_create(filename, ws.gctx(), "uplifted package")?;
src.file().seek(SeekFrom::Start(0))?;
std::io::copy(&mut src.file(), &mut dst.file())?;
result.push(dst);
}
}

Ok(result)
}

/// Packages an entire workspace.
Expand Down
2 changes: 1 addition & 1 deletion src/doc/src/reference/build-cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ the `target` directory:
Directory | Description
----------|------------
<code style="white-space: nowrap">target/doc/</code> | Contains rustdoc documentation ([`cargo doc`]).
<code style="white-space: nowrap">target/package/</code> | Contains the output of the [`cargo package`] and [`cargo publish`] commands.
<code style="white-space: nowrap">target/package/</code> | Contains the output of the [`cargo package`].

Cargo also creates several other directories and files in the build-dir needed for the build
process. The build-dir layout is considered internal to Cargo, and is subject to
Expand Down
33 changes: 33 additions & 0 deletions tests/testsuite/build_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use std::path::PathBuf;

use crate::prelude::*;
use cargo_test_support::registry::RegistryBuilder;
use cargo_test_support::{Project, prelude::*};
use cargo_test_support::{paths, project, str};
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX, EXE_SUFFIX};
Expand Down Expand Up @@ -359,6 +360,38 @@ fn cargo_package_should_build_in_build_dir_and_output_to_target_dir() {
assert!(package_build_dir.join("foo-0.0.1").is_dir());
}

#[cargo_test]
fn cargo_publish_should_only_touch_build_dir() {
let registry = RegistryBuilder::new().http_api().http_index().build();

let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();

p.cargo("publish")
.replace_crates_io(registry.index_url())
.enable_mac_dsym()
.run();

assert_build_dir_layout(p.root().join("build-dir"), "debug");

let package_artifact_dir = p.root().join("target-dir/package");
assert!(!package_artifact_dir.exists());

let package_build_dir = p.root().join("build-dir/package");
assert_exists(&package_build_dir);
assert_exists(&package_build_dir.join("foo-0.0.1"));
assert!(package_build_dir.join("foo-0.0.1").is_dir());
}

#[cargo_test]
fn cargo_clean_should_clean_the_target_dir_and_build_dir() {
let p = project()
Expand Down
Loading