Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9609881
Document feature unification
pacak Apr 9, 2024
90150d1
Change Pid into named structure, rename some fields in FeatGraph
pacak Apr 9, 2024
a7639aa
derp, feature is actually webbrowser.
pacak Aug 12, 2024
44d6a6e
Modernize, make clippy happy
pacak Jun 7, 2026
32355b4
Haven't seen serde doing anything stupid lately
pacak Jun 7, 2026
6f26eaa
workspace generator
pacak Jun 9, 2026
3a37310
start to replacing dev dependency with build
pacak Jun 9, 2026
f9a61e4
upgrade cargo-metadata
pacak Jun 10, 2026
aa9397a
clean up code in explain.rs
pacak Jun 10, 2026
6dfee7f
Start tracking crate instance: host/target
pacak Jun 10, 2026
be3cc0d
add a simple example for dev dependencies
pacak Jun 10, 2026
133deef
there's no dev unification, there is build unification
pacak Jun 14, 2026
d41c470
test workspace
pacak Jun 10, 2026
0cae46a
workspace-gen
pacak Jun 10, 2026
0c90d13
Track optional dependency feature separately
pacak Jun 14, 2026
d84bedb
Proc macros are always compiled for host
pacak Jun 14, 2026
a35464d
simplify fetching dependency index
pacak Jun 14, 2026
5d6b8c3
WIP
pacak Jun 14, 2026
0e2a252
keep name consistent consistent
pacak Jun 15, 2026
a64fa46
prefer resolved
pacak Jun 14, 2026
0ea7ac9
display host instances in lightblue
pacak Jun 14, 2026
5ce8e28
Wire dependency edges for both Host and Target instances
pacak Jun 15, 2026
e9cd480
Create base nodes for both Host and Target instances in add_package
pacak Jun 15, 2026
716c35f
unused variable
pacak Jun 15, 2026
529b099
drop test crates
pacak Jun 15, 2026
1326ec9
Upgrade petgraph
pacak Jun 16, 2026
c5c9d01
Update webbrowser
pacak Jun 16, 2026
27494aa
Update toml_edit
pacak Jun 16, 2026
36efe41
Update compatible crates
pacak Jun 16, 2026
c790e1a
use current platform or platform from the config
pacak Jun 15, 2026
c7de231
prepare to release 0.2.10
pacak Jun 15, 2026
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
1,082 changes: 727 additions & 355 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cargo-hackerman"
version = "0.2.9"
edition = "2021"
version = "0.2.10"
edition = "2024"
description = "Workspace hack management and package/feature query"
license = "MIT OR Apache-2.0"
repository = "https://github.com/pacak/hackerman/"
Expand All @@ -12,23 +12,25 @@ exclude = ["TODO", "test_workspaces"]
[dependencies]
anyhow = "1.0.52"
bpaf = { version = "0.9.9", features = ["derive", "autocomplete", "docgen"] }
cargo-platform = "0.1"
cargo_metadata = { version = "0.18" }
cargo_metadata = { version = "0.23" }
dot = "0.1.4"
pathdiff = { version = "0.2", features = ["camino"] }
petgraph = "0.6.0"
petgraph = "0.8.3"
semver = "1.0"
serde = "=1.0.196"
serde = "1"
serde_json = "1.0"
target-spec = "3.0"
tempfile = { version = "3.3.0" }
toml_edit = "0.21"
toml_edit = "0.25"
tracing = "0.1.29"
tracing-subscriber = { version = "0.3.5", default-features = false, features = [ "alloc", "env-filter", "registry", "std", "fmt" ] }
webbrowser = { version = "0.8.10", optional = true }
webbrowser = { version = "1.2.1", optional = true }


[features]
bright-color = ["bpaf/bright-color"]
default = ["dull-color"]
dull-color = ["bpaf/dull-color"]

[workspace]
members = ["./workspace-gen"]
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ You can pass **`--help`** twice for more detailed help

Unify crate dependencies across individual crates in the workspace

**Usage**: **`cargo hackerman`** **`hack`** _`CARGO_OPTS`_ \[**`--dry`**\] \[**`--lock`**\] \[**`-D`**\]
**Usage**: **`cargo hackerman`** **`hack`** _`CARGO_OPTS`_ \[**`--dry`**\] \[**`--lock`**\]

You can undo those changes using `cargo hackerman restore`.

Expand Down Expand Up @@ -251,8 +251,6 @@ You can undo those changes using `cargo hackerman restore`.
lock = true
```

- **`-D`**, **`--no-dev`** —
Don't unify dev dependencies
- **`-h`**, **`--help`** —
Prints help information

Expand Down Expand Up @@ -300,7 +298,7 @@ Check if unification is required and if checksums are correct

Similar to `cargo-hackerman hack --dry`, but also sets exit status to 1 so you can use it as part of CI process

**Usage**: **`cargo hackerman`** **`check`** _`CARGO_OPTS`_ \[**`-D`**\]
**Usage**: **`cargo hackerman`** **`check`** _`CARGO_OPTS`_

**Cargo options:**
- **` --manifest-path`**=_`PATH`_ —
Expand All @@ -317,8 +315,6 @@ Similar to `cargo-hackerman hack --dry`, but also sets exit status to 1 so you c


**Available options:**
- **`-D`**, **`--no-dev`** —
Don't unify dev dependencies
- **`-h`**, **`--help`** —
Prints help information

Expand Down
40 changes: 21 additions & 19 deletions src/explain.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
feat_graph::{FeatGraph, HasIndex},
feat_graph::{CrateInstance, FeatGraph, HasIndex},
metadata::{DepKindInfo, Link},
};

Expand All @@ -11,35 +11,36 @@ use semver::Version;
use std::collections::BTreeSet;
use tracing::{debug, info};

/// Find all the packages that can be a starting point for a query to display (display purposes)
///
/// Match all crates by name, with refining by a feature name and/or version number
fn collect_packages(
fg: &mut FeatGraph,

krate: &str,
feature: Option<&String>,
feature: Option<&str>,
version: Option<&Version>,
) -> Vec<NodeIndex> {
fg.features
.node_indices()
.filter(|&ix| {
if let Some(fid) = fg.features[ix].fid() {
let package = fid.pid.package();
// name must match.
// feature must match if given, otherwise look for base
// version must match if given
package.name == krate
&& feature.map_or(fid.pid.base() == fid, |f| fid.pid.named(f) == fid)
&& version.map_or(true, |v| package.version == *v)
} else {
false
}
let Some(fid) = fg.features[ix].fid() else {
return false;
};
let package = fid.pid.package();
// name must match.
// feature must match if given, otherwise look for base
// version must match if given
package.name == krate
&& version.is_none_or(|v| package.version == *v)
&& (feature.is_none() || feature == fid.name())
})
.collect::<Vec<_>>()
}

pub fn tree<'a>(
fg: &'a mut FeatGraph<'a>,
krate: Option<&String>,
feature: Option<&String>,
feature: Option<&str>,
version: Option<&Version>,
package_nodes: bool,
workspace: bool,
Expand All @@ -54,7 +55,7 @@ pub fn tree<'a>(
let members = fg.workspace_members.clone();
members
.iter()
.map(|f| fg.fid_index(f.base()))
.map(|f| fg.fid_index(f.base(CrateInstance::Target)))
.collect::<Vec<_>>()
}
};
Expand Down Expand Up @@ -82,6 +83,7 @@ pub fn tree<'a>(
node
};
nodes.insert(this_node);

for edge in g.edges_directed(node, petgraph::EdgeDirection::Outgoing) {
if package_nodes {
new_edges.insert((
Expand All @@ -97,7 +99,7 @@ pub fn tree<'a>(

if package_nodes {
for (a, b) in new_edges {
let a = a.get_index(fg)?;
let a = a.get_index(fg, CrateInstance::Target)?;
if a != b {
let link = Link {
optional: false,
Expand All @@ -119,7 +121,7 @@ pub fn tree<'a>(
pub fn explain<'a>(
fg: &'a mut FeatGraph<'a>,
krate: &str,
feature: Option<&String>,
feature: Option<&str>,
version: Option<&Version>,
package_nodes: bool,
stdout: bool,
Expand Down Expand Up @@ -178,7 +180,7 @@ pub fn explain<'a>(

if package_nodes {
for (a, b) in new_edges {
let a = a.get_index(fg)?;
let a = a.get_index(fg, CrateInstance::Target)?;
if a != b {
let link = Link {
optional: false,
Expand Down
Loading