Skip to content

Commit

Permalink
Fix handling of glob members in --no-private
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Jan 24, 2024
1 parent fc62618 commit c19edad
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 22 deletions.
11 changes: 9 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,9 +561,16 @@ impl Args {
None => LogGroup::auto(),
};

if no_dev_deps {
if no_dev_deps || no_private {
let flag = if no_dev_deps && no_private {
"--no-dev-deps and --no-private modify"
} else if no_dev_deps {
"--no-dev-deps modifies"
} else {
"--no-private modifies"
};
info!(
"--no-dev-deps removes dev-dependencies from real `Cargo.toml` while cargo-hack is running and restores it when finished"
"{flag} real `Cargo.toml` while cargo-hack is running and restores it when finished"
);
}

Expand Down
59 changes: 43 additions & 16 deletions src/manifest.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use std::{collections::BTreeMap, path::Path};
use std::{
collections::{BTreeMap, BTreeSet},
path::Path,
};

use anyhow::{bail, format_err, Context as _, Result};

Expand Down Expand Up @@ -106,7 +109,7 @@ pub(crate) fn with(cx: &Context, f: impl FnOnce() -> Result<()>) -> Result<()> {
let workspace_root = &cx.metadata.workspace_root;
let root_manifest = &workspace_root.join("Cargo.toml");
let mut root_id = None;
let mut private_crates = vec![];
let mut private_crates = BTreeSet::new();
for id in &cx.metadata.workspace_members {
let package = cx.packages(id);
let manifest_path = &*package.manifest_path;
Expand All @@ -121,7 +124,7 @@ pub(crate) fn with(cx: &Context, f: impl FnOnce() -> Result<()>) -> Result<()> {
"--no-private is not supported yet with workspace with private root crate"
);
}
private_crates.push(manifest_path);
private_crates.insert(manifest_path);
} else if is_root && no_private {
// This case is handled in the if block after loop.
} else if no_dev_deps {
Expand Down Expand Up @@ -165,7 +168,7 @@ pub(crate) fn with(cx: &Context, f: impl FnOnce() -> Result<()>) -> Result<()> {
if term::verbose() {
info!("removing private crates from {}", manifest_path.display());
}
remove_private_crates(&mut doc, workspace_root, &private_crates)?;
remove_private_crates(&mut doc, workspace_root, private_crates);
}
restore_handles.push(cx.restore.register(orig, manifest_path));
fs::write(manifest_path, doc.to_string())?;
Expand Down Expand Up @@ -205,8 +208,8 @@ fn remove_dev_deps(doc: &mut toml_edit::Document) {
fn remove_private_crates(
doc: &mut toml_edit::Document,
workspace_root: &Path,
private_crates: &[&Path],
) -> Result<()> {
mut private_crates: BTreeSet<&Path>,
) {
let table = doc.as_table_mut();
if let Some(workspace) = table.get_mut("workspace").and_then(toml_edit::Item::as_table_like_mut)
{
Expand All @@ -216,25 +219,49 @@ fn remove_private_crates(
while i < members.len() {
if let Some(member) = members.get(i).and_then(toml_edit::Value::as_str) {
let manifest_path = workspace_root.join(member).join("Cargo.toml");
if private_crates
.iter()
.find_map(|p| {
same_file::is_same_file(p, &manifest_path)
.map(|v| if v { Some(()) } else { None })
.transpose()
if let Some(p) = private_crates.iter().find_map(|p| {
same_file::is_same_file(p, &manifest_path).ok().and_then(|v| {
if v {
Some(*p)
} else {
None
}
})
.transpose()?
.is_some()
{
}) {
members.remove(i);
private_crates.remove(p);
continue;
}
}
i += 1;
}
}
if private_crates.is_empty() {
return;
}
// Handles the case that the members field contains glob.
// TODO: test that it also works when public and private crates are nested.
if let Some(exclude) = workspace.get_mut("exclude").and_then(toml_edit::Item::as_array_mut)
{
for private_crate in private_crates {
exclude.push(private_crate.parent().unwrap().to_str().unwrap());
}
} else {
workspace.insert(
"exclude",
toml_edit::Item::Value(toml_edit::Value::Array(
private_crates
.iter()
.map(|p| {
toml_edit::Value::String(toml_edit::Formatted::new(
p.parent().unwrap().to_str().unwrap().to_owned(),
))
})
.collect::<toml_edit::Array>(),
)),
);
}
}
Ok(())
}

#[cfg(test)]
Expand Down
8 changes: 4 additions & 4 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,16 @@ fn no_dev_deps() {
cargo_hack(["check", "--no-dev-deps"]).assert_success("real").stderr_contains(
"
running `cargo check` on real
--no-dev-deps removes dev-dependencies from real `Cargo.toml` while cargo-hack is \
running and restores it when finished
--no-dev-deps modifies real `Cargo.toml` while cargo-hack is running and \
restores it when finished
",
);

// with --all
cargo_hack(["check", "--no-dev-deps", "--all"]).assert_success("real").stderr_contains(
"
--no-dev-deps removes dev-dependencies from real `Cargo.toml` while cargo-hack is \
running and restores it when finished
--no-dev-deps modifies real `Cargo.toml` while cargo-hack is running and \
restores it when finished
",
);
}
Expand Down

0 comments on commit c19edad

Please sign in to comment.