~ireas/public-inbox

2 2

[PATCH cargo-depgraph]

Nathan Wilcox <nathan@electriccoin.co>
Details
Message ID
<CAK8perBBGxCudy=96Tx+Wrxf3saPBVXht_JOHBFTEbZZK=nj0A@mail.gmail.com>
DKIM signature
missing
Download raw message
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<String>,
     pub exclude: Vec<String>,
+    pub workspace_only: bool,
     pub focus: Vec<String>,

     pub features: Vec<String>,
@@ -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<u16>) {
     }
 }

+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
Details
Message ID
<20220921071716.GA1221@ireas.org>
In-Reply-To
<CAK8perBBGxCudy=96Tx+Wrxf3saPBVXht_JOHBFTEbZZK=nj0A@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
Hi Nathan,

I’m not affiliated with the cargo-depgraph project.  You should probably
send the patch directly to Jonas.

Best,
Robin

On 2022-09-20 15:03:29, Nathan Wilcox wrote:
> 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<String>,
>      pub exclude: Vec<String>,
> +    pub workspace_only: bool,
>      pub focus: Vec<String>,
> 
>      pub features: Vec<String>,
> @@ -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<u16>) {
>      }
>  }
> 
> +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
Nathan Wilcox <nathan@electriccoin.co>
Details
Message ID
<CAK8perDu=-f39g5KfjB6idQige+n1kBiaqU=Vd1z6BqC3sYeMA@mail.gmail.com>
In-Reply-To
<20220921071716.GA1221@ireas.org> (view parent)
DKIM signature
missing
Download raw message
Apologies for the confusion!

Is `jplatte+git@posteo.de` the correct destination for `cargo-depgraph` patches?

Yesterday I found a page saying email patches should all be sent to
`~ireas/public-inbox@lists.sr.ht`, except some projects have their own
mailing list. I glanced at the list of projects and didn't see
`cargo-depgraph` there, so I assumed I should use the default email.
Today I can't find that page, so I'm not sure how I ran across it.

For someone new to sr.ht like me (who's also never submitted git
patches via email before) it would help to have the correct email
address on https://git.sr.ht/~jplatte/cargo-depgraph . In fact, the
most helpful thing would be to alter the text which says "You can also
use your local clone with <git send-email>." into "You can also use
your local clone with <git send-email> by running `git send-email
--to=<project-specific-email>`." If that were in the base template of
sr.ht (and all projects were required to declare the patch email
addr), it would streamline this piece of the puzzle for newcomers.
Where can I go to file an issue or submit a patch to add that feature
to sr.ht ?

regards,
Nate



On Wed, Sep 21, 2022 at 12:17 AM Robin Krahl <robin.krahl@ireas.org> wrote:
>
> Hi Nathan,
>
> I’m not affiliated with the cargo-depgraph project.  You should probably
> send the patch directly to Jonas.
>
> Best,
> Robin
>
> On 2022-09-20 15:03:29, Nathan Wilcox wrote:
> > 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<String>,
> >      pub exclude: Vec<String>,
> > +    pub workspace_only: bool,
> >      pub focus: Vec<String>,
> >
> >      pub features: Vec<String>,
> > @@ -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<u16>) {
> >      }
> >  }
> >
> > +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



-- 

Nathan Wilcox

Chief Research Officer

nathan@electriccoin.co | @least_nathan
Reply to thread Export thread (mbox)