Authentication-Results: mail-b.sr.ht; dkim=pass header.d=electriccoin.co header.i=@electriccoin.co Received: from mail-yw1-f179.google.com (mail-yw1-f179.google.com [209.85.128.179]) by mail-b.sr.ht (Postfix) with ESMTPS id C414411EF52 for <~ireas/public-inbox@lists.sr.ht>; Tue, 20 Sep 2022 22:03:41 +0000 (UTC) Received: by mail-yw1-f179.google.com with SMTP id 00721157ae682-3450a7358baso43138847b3.13 for <~ireas/public-inbox@lists.sr.ht>; Tue, 20 Sep 2022 15:03:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=electriccoin.co; s=google; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date; bh=h8UlN6HnRg+9VaHdRI7zcw3nSvBIro3xdz6XhDg/vQs=; b=i2qXs9+wTQOaKCyCWc384gBSdSPMNd5Juv9lzFiN4sAQli2IQ95pgythUAPEeTi4D2 uHwns48iGvWZOSRmdLJx36uyKxofxDwyEAVbyYw2LRaQ0hQGpSzwfTmgq6T1ey6hCzJz z0BXIvFuoX5REMSnRpTAo3SvL974EFfrmZEDQn92mE1/n81GCIitKwb7tgrj4ffLB/75 HwV42MCf08pFuHbAEKdbEzksI5pdxHlG7nTIAcnEpjczxTjCarkXCozBPe0hx8VQ9JtT QKX/N9LBJaClF2Acuaxh/uDhOetRSjPPxBwOBxLqz3y6ie6J1xrLrv3HN6n/JqfJbJIO p78Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date; bh=h8UlN6HnRg+9VaHdRI7zcw3nSvBIro3xdz6XhDg/vQs=; b=45cE5rPJAR3YJ/dDN6QNqKTERuGNRQa1pY71YzbxosoAaf/2ct6F1Z3cUmJNCkWAXc ZulNjcwegMA3zD7Wf5mHW40RoVQTrTEBsu8HUxobXickpG+a3CjsBTcE29gUeIlZ7HQn Tfy+THDcnkP4pbfOAQMqlzKiphd9OlB0LcOIitC+0oT+9t2RFtKEpoCwezoF98L3uEtZ AllJ6vbZR7b+0Nux+Zyuqv96MzpZ2DtHJ5edAX0VqQDzOIGua+PhnaKHFgloAzvggZdZ FpJydkWCqZUCHsSuSdAuhm3Lo7vCQlIB4pfgWFacMiDS1DRFMjZo7Y8GXMqwq60BkRTy 5fkg== X-Gm-Message-State: ACrzQf0TpcavJxX/sCZBoYUQPO8YbtR8EMD0rWWAcoDHo9dms2C0pvbs c+0DwA30XNpPLkJqU1lkO7RJ8HQnFpjK2oPB/TMdsF0zMzKrgA== X-Google-Smtp-Source: AMsMyM5rHs29ThmWoIc7we9cAA+P0NaGzTBRdBvA7B2CBgdlKPy3KmdDGSVA8VkrJubNYBJ81h6OQYMOIY6iL/Butq0= X-Received: by 2002:a81:846:0:b0:349:ecfc:ed9 with SMTP id 67-20020a810846000000b00349ecfc0ed9mr21509437ywi.512.1663711420879; Tue, 20 Sep 2022 15:03:40 -0700 (PDT) MIME-Version: 1.0 From: Nathan Wilcox Date: Tue, 20 Sep 2022 15:03:29 -0700 Message-ID: Subject: [PATCH cargo-depgraph] To: ~ireas/public-inbox@lists.sr.ht Content-Type: text/plain; charset="UTF-8" This patch adds a `--workspace-only` option which constrains the graph to only workspace crates. This is useful for understanding intra-workspace dependencies. --- src/cli.rs | 8 ++++++++ src/graph.rs | 20 ++++++++++++++++++++ src/main.rs | 6 +++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/cli.rs b/src/cli.rs index e9f2aa1..72b3fff 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -7,6 +7,7 @@ pub struct Config { pub dedup_transitive_deps: bool, pub hide: Vec, pub exclude: Vec, + pub workspace_only: bool, pub focus: Vec, pub features: Vec, @@ -76,6 +77,11 @@ pub fn parse_options() -> Config { dependency kind resolution", ), ) + .arg( + Arg::new("workspace_only") + .long("workspace-only") + .help("Exclude all packages outside of the workspace"), + ) .arg( Arg::new("focus") .long("focus") @@ -155,6 +161,7 @@ pub fn parse_options() -> Config { let dedup_transitive_deps = matches.is_present("dedup_transitive_deps"); let hide = matches.values_of("hide").map_or_else(Vec::new, collect_owned); let exclude = matches.values_of("exclude").map_or_else(Vec::new, collect_owned); + let workspace_only = matches.is_present("workspace_only"); let focus = matches.values_of("focus").map_or_else(Vec::new, collect_owned); let features = matches.values_of("features").map_or_else(Vec::new, collect_owned); @@ -174,6 +181,7 @@ pub fn parse_options() -> Config { dedup_transitive_deps, hide, exclude, + workspace_only, focus, features, all_features, diff --git a/src/graph.rs b/src/graph.rs index d41c0d3..d4f329c 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -80,6 +80,26 @@ fn update_node(graph: &mut DepGraph, idx: NodeIndex) { } } +pub fn remove_non_workspace_deps(graph: &mut DepGraph) { + let mut visit_queue: VecDeque<_> = graph.externals(Direction::Outgoing).collect(); + while let Some(idx) = visit_queue.pop_front() { + // A node can end up being in the list multiple times. If it was already removed by a + // previous iteration of this loop, skip it. + if !graph.contains_node(idx) { + continue; + } + + let pkg = &graph[idx]; + if !pkg.is_ws_member { + // The package node at `idx` should be removed. + // => First add its dependencies to the visit queue + visit_queue.extend(graph.neighbors_directed(idx, Direction::Incoming)); + // => Then actually remove it + graph.remove_node(idx); + } + } +} + pub fn remove_irrelevant_deps(graph: &mut DepGraph, focus: &[String]) { let mut visit_queue: VecDeque<_> = graph.externals(Direction::Outgoing).collect(); while let Some(idx) = visit_queue.pop_front() { diff --git a/src/main.rs b/src/main.rs index c86af4f..25c7ee3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,8 @@ mod output; use self::{ cli::parse_options, graph::{ - dedup_transitive_deps, get_dep_graph, remove_deps, remove_irrelevant_deps, update_dep_info, + dedup_transitive_deps, get_dep_graph, remove_deps, remove_irrelevant_deps, + remove_non_workspace_deps, update_dep_info, }, output::dot, util::set_name_stats, @@ -59,6 +60,9 @@ fn main() -> anyhow::Result<()> { let mut graph = get_dep_graph(metadata, &config)?; update_dep_info(&mut graph); + if config.workspace_only { + remove_non_workspace_deps(&mut graph); + } if !config.focus.is_empty() { remove_irrelevant_deps(&mut graph, &config.focus); } -- 2.30.2