Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign CLI commands #235

Merged
merged 27 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e9cee12
Move `rust-analyzer`-related logic into `crate::analyzer` module
regexident Dec 5, 2023
b928e32
Remove `generate` CLI root-command in favor of promoting its sub-comm…
regexident Nov 26, 2023
7d67f6a
Dissolve sub-modules of `crate::theme` into `crate::graph` & `crate::…
regexident Nov 25, 2023
9993813
Rename `crate::commands` to `crate::command`
regexident Nov 26, 2023
a928590
Make `Command::run` consume `self`
regexident Nov 26, 2023
edee6be
Rename `cargo modules tree` CLI command to `… structure`
regexident Nov 26, 2023
35f3ea3
Update snapshot tests for `structure` command
regexident Dec 4, 2023
b9438e4
Rename test snapshot files of `structure` command
regexident Dec 4, 2023
5618441
Rename `cargo modules graph` CLI command to `… dependencies`
regexident Nov 26, 2023
5e8dcc4
Update snapshot tests for `dependencies` command
regexident Dec 4, 2023
3b3045e
Rename test snapshot files of `dependencies` command
regexident Dec 4, 2023
333a5ed
Remove obsolete `crate::options::selection`
regexident Nov 26, 2023
d2d9e78
Add `cargo modules orphans` CLI command
regexident Dec 5, 2023
ed38a8e
Move CLI color palette into command-agnostic root module
regexident Nov 26, 2023
56800d2
Refine error messages of `orphans` command
regexident Nov 26, 2023
5b15b96
Remove `--orphans` CLI flag, simplifying implementations
regexident Nov 26, 2023
b2f01b2
Add test projects for `orphans` command
regexident Dec 5, 2023
f6fcae5
Remove `crate::orphans` from 'smoke' test project
regexident Dec 5, 2023
7c4f908
Change `--x` & `--no-<x>` from being mixed opt-in/opt-out to being op…
regexident Dec 6, 2023
7b8b9bc
Fix ignore path in 'skywalking-eyes.yml' file
regexident Dec 5, 2023
2fbd720
Remove global `--no-sysroot` CLI option, moving it into `dependencies…
regexident Dec 6, 2023
b9a8425
Replace `--no-tests` & `--no-cfg-test` CLI options with `--cfg-test` …
regexident Dec 6, 2023
5ada9cd
Remove unused `Command::validate_options(&self)` method
regexident Dec 6, 2023
b223996
Sort selection options alphabetically
regexident Dec 6, 2023
869b5c2
Add snapshot tests for `--help` CLI option
regexident Dec 6, 2023
457b683
Update 'README.md' file
regexident Dec 6, 2023
a2900a3
Update changelog
regexident Dec 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/configs/skywalking-eyes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ header:
paths:
- "src/**/*.rs"
paths-ignore:
- "src/graph/cycles/tri_color.rs"
- "src/dependencies/cycles/tri_color.rs"
29 changes: 26 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,42 @@ Please make sure to add your changes to the appropriate categories:

### Added

- n/a
- Added dedicated top-level `orphans` command (replacing the now removed `--orphans` CLI flag) for detecting orphaned Rust source files within projects.

### Changed

- n/a
- Renamed `generate tree` command to `structure`, promoting it to a top-level command.
- Renamed `generate graph` command to `dependencies`, promoting it to a top-level command.
- Made `structure` command include types, traits, and fns by default.
Use `--no-types`, `--no-traits`, `--no-fns` to opt-out.
- Made `dependencies` command include uses, externs, types, traits, and fns by default.
Use `--no-modules`, `--no-uses`, `--no-externs`, `--no-types`, `--no-traits`, `--no-fns` to opt-out.

### Deprecated

- n/a

### Removed

- n/a
- Removed `generate` top-level CLI command, promoting its sub-commands to top-level commands.
- Removed the `--orphans` CLI flag from `structure` command (née `generate tree`).
- Removed global CLI option `--sysroot` & `--no-sysroot`.
- Removed global CLI option `--no-cfg-test`.
- Removed CLI selection options for `structure` command:
- Removed CLI option `--types`
- Removed CLI option `--traits`
- Removed CLI option `--fns`
- Removed CLI option `--tests`
- Removed CLI option `--no-tests`
- Removed CLI selection options for `dependencies` command:
- Removed CLI option `--modules`
- Removed CLI option `--uses`
- Removed CLI option `--externs`
- Removed CLI option `--types`
- Removed CLI option `--traits`
- Removed CLI option `--fns`
- Removed CLI option `--tests`
- Removed CLI option `--no-tests`

### Fixed

Expand Down
207 changes: 154 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

## Synopsis

A cargo plugin for showing an overview of a crate's modules.
A cargo plugin for visualizing/analyzing a crate's internal structure.

## Motivation

Expand All @@ -27,17 +27,58 @@ cargo install cargo-modules

## Usage

### Print crate as a tree
The `cargo-modules` tool comes with a couple of commands:

```bash
cargo modules generate tree <OPTIONS>
# Print a crate's hierarchical structure as a tree:
cargo modules structure <OPTIONS>

# Print a crate's internal dependencies as a graph:
cargo modules dependencies <OPTIONS>

# Detect unlinked source files within a crate's directory:
cargo modules orphans <OPTIONS>
```

<details>
<summary>Command help</summary>

```terminal
$ cargo modules --help

Visualize/analyze a crate's internal structure.

Usage: cargo-modules <COMMAND>

Commands:
structure Prints a crate's hierarchical structure as a tree.
dependencies Prints a crate's internal dependencies as a graph.
orphans Detects unlinked source files within a crate's directory.
help Print this message or the help of the given subcommand(s)

Options:
-h, --help Print help
```

</details>

### cargo modules structure

Print a crate's hierarchical structure as a tree:

```bash
cargo modules structure <OPTIONS>
```

<details>
<summary>Command help</summary>

```terminal
Usage: cargo-modules generate tree [OPTIONS]
$ cargo modules structure --help

Prints a crate's hierarchical structure as a tree.

Usage: cargo-modules structure [OPTIONS]

Options:
--verbose Use verbose output
Expand All @@ -48,25 +89,15 @@ Options:
--all-features Activate all available features
--features <FEATURES> List of features to activate. This will be ignored if `--cargo-all-features` is provided
--target <TARGET> Analyze for target triple
--cfg-test Analyze with `#[cfg(test)]` enabled
--no-cfg-test Analyze with `#[cfg(test)]` disabled. [default]
--sysroot Include sysroot crates (`std`, `core` & friends) in analysis
--no-sysroot Exclude sysroot crates (`std`, `core` & friends) in analysis. [default]
--manifest-path <MANIFEST_PATH> Path to Cargo.toml [default: .]
--focus-on <FOCUS_ON> Focus the graph on a particular path or use-tree's environment, e.g. "foo::bar::{self, baz, blee::*}"
--max-depth <MAX_DEPTH> The maximum depth of the generated graph relative to the crate's root node, or nodes selected by '--focus-on'
--types Include types (e.g. structs, unions, enums)
--no-types Exclude types (e.g. structs, unions, enums). [default]
--traits Include traits (e.g. trait, unsafe trait)
--no-traits Exclude traits (e.g. trait, unsafe trait). [default]
--fns Include functions (e.g. fns, async fns, const fns)
--no-fns Exclude functions (e.g. fns, async fns, const fns). [default]
--tests Include tests (e.g. `#[test] fn …`)
--no-tests Exclude tests (e.g. `#[test] fn …`). [default]
--no-fns Filter out functions (e.g. fns, async fns, const fns) from tree
--no-traits Filter out traits (e.g. trait, unsafe trait) from tree
--no-types Filter out types (e.g. structs, unions, enums) from tree
--sort-by <SORT_BY> The sorting order to use (e.g. name, visibility, kind) [default: name]
--sort-reversed Reverses the sorting order
--orphans Include orphaned modules (i.e. unused files in /src)
--no-orphans Exclude orphaned modules (i.e. unused files in /src). [default]
--focus-on <FOCUS_ON> Focus the graph on a particular path or use-tree's environment, e.g. "foo::bar::{self, baz, blee::*}"
--max-depth <MAX_DEPTH> The maximum depth of the generated graph relative to the crate's root node, or nodes selected by '--focus-on'
--cfg-test Analyze with `#[cfg(test)]` enabled (i.e as if built via `cargo test`)
-h, --help Print help
```

Expand All @@ -76,12 +107,12 @@ Options:

```bash
cd ./tests/projects/readme_tree_example
cargo-modules generate tree --types --traits --fns --tests
cargo-modules structure --types --traits --fns --tests
```

Output:

![Output of `cargo modules generate tree …`](docs/tree_output.png)
![Output of `cargo modules structure …`](docs/structure_output.png)

```rust
crate readme_tree_example
Expand Down Expand Up @@ -114,25 +145,28 @@ The `<visibility>` ([more info](https://doc.rust-lang.org/reference/visibility-a
| 🟡 yellow | Items visible to the current crate (i.e. `pub(crate)`) |
| 🟠 orange | Items visible to a certain parent module (i.e. `pub(in path)`) |
| 🔴 red | Items visible to the current module (i.e. `pub(self)`, implied by lack of `pub …`) |
| 🟣 purple | Orphaned modules (i.e. a file exists on disk but no corresponding `mod …`) |

The `<keyword>` is highlighted in 🔵 blue to visually separate it from the name.

Test-guarded items (i.e. `#[cfg(test)] …`) and test functions (i.e. `#[test] fn …`) have their corresponding `<test-attributes>` printed next to them in gray and cyan.

### Print crate as a graph
### cargo modules dependencies

Print a crate's internal dependencies as a graph:

```bash
cargo modules generate graph <OPTIONS>
cargo modules dependencies <OPTIONS>
```

<details>
<summary>Command help</summary>

```terminal
Print crate as a graph.
$ cargo modules dependencies --help

Usage: cargo-modules generate graph [OPTIONS]
Prints a crate's internal dependencies as a graph.

Usage: cargo-modules dependencies [OPTIONS]

Options:
--verbose Use verbose output
Expand All @@ -143,34 +177,24 @@ Options:
--all-features Activate all available features
--features <FEATURES> List of features to activate. This will be ignored if `--cargo-all-features` is provided
--target <TARGET> Analyze for target triple
--cfg-test Analyze with `#[cfg(test)]` enabled
--no-cfg-test Analyze with `#[cfg(test)]` disabled. [default]
--sysroot Include sysroot crates (`std`, `core` & friends) in analysis
--no-sysroot Exclude sysroot crates (`std`, `core` & friends) in analysis. [default]
--manifest-path <MANIFEST_PATH> Path to Cargo.toml [default: .]
--focus-on <FOCUS_ON> Focus the graph on a particular path or use-tree's environment, e.g. "foo::bar::{self, baz, blee::*}"
--max-depth <MAX_DEPTH> The maximum depth of the generated graph relative to the crate's root node, or nodes selected by '--focus-on'
--types Include types (e.g. structs, unions, enums)
--no-types Exclude types (e.g. structs, unions, enums). [default]
--traits Include traits (e.g. trait, unsafe trait)
--no-traits Exclude traits (e.g. trait, unsafe trait). [default]
--fns Include functions (e.g. fns, async fns, const fns)
--no-fns Exclude functions (e.g. fns, async fns, const fns). [default]
--tests Include tests (e.g. `#[test] fn …`)
--no-tests Exclude tests (e.g. `#[test] fn …`). [default]
--no-externs Filter out extern items from extern crates from graph
--no-fns Filter out functions (e.g. fns, async fns, const fns) from graph
--no-modules Filter out modules (e.g. `mod foo`, `mod foo {}`) from graph
--no-sysroot Filter out sysroot crates (`std`, `core` & friends) from graph
--no-traits Filter out traits (e.g. trait, unsafe trait) from graph
--no-types Filter out types (e.g. structs, unions, enums) from graph
--no-uses Filter out "use" edges from graph
--acyclic Require graph to be acyclic
--layout <LAYOUT> The graph layout algorithm to use (e.g. none, dot, neato, twopi, circo, fdp, sfdp) [default: neato]
--no-modules Exclude modules (e.g. `mod foo`, `mod foo {}`)
--modules Include modules (e.g. `mod foo`, `mod foo {}`). [default]
--uses Include used modules and types
--no-uses Exclude used modules and types [default]
--externs Include used modules and types from extern crates
--no-externs Exclude used modules and types from extern crates [default]
--focus-on <FOCUS_ON> Focus the graph on a particular path or use-tree's environment, e.g. "foo::bar::{self, baz, blee::*}"
--max-depth <MAX_DEPTH> The maximum depth of the generated graph relative to the crate's root node, or nodes selected by '--focus-on'
--cfg-test Analyze with `#[cfg(test)]` enabled (i.e as if built via `cargo test`)
-h, --help Print help


If you have xdot installed on your system, you can run this using:
`cargo modules generate dependencies | xdot -`
`cargo modules dependencies | xdot -`
```

</details>
Expand All @@ -179,10 +203,14 @@ Options:

```bash
cd ./tests/projects/smoke
cargo-modules generate graph --types --tests --orphans | dot -Tsvg
cargo-modules dependencies --types --tests --orphans | dot -Tsvg
```

![Output of `cargo modules generate graph …`](docs/graph_output.svg)
![Output of `cargo modules dependencies …`](docs/dependencies_output.svg)

```plain
See "./docs/dependencies_output.dot" for the corresponding raw dot file.
```

(Project source code: [readme_graph_example/src/lib.rs](./tests/projects/readme_graph_example/src/lib.rs))

Expand All @@ -209,13 +237,12 @@ The `<visibility>` ([more info](https://doc.rust-lang.org/reference/visibility-a
| 🟡 yellow | Items visible to the current crate (i.e. `pub(crate)`) |
| 🟠 orange | Items visible to a certain parent module (i.e. `pub(in path)`) |
| 🔴 red | Items visible to the current module (i.e. `pub(self)`, implied by lack of `pub …`) |
| 🟣 purple | Orphaned modules (i.e. a file exists on disk but no corresponding `mod …`) |

#### Acyclic Mode

cargo-modules's `generate graph` command checks for the presence of a `--acyclic` flag. If found it will search for cycles in the directed graph and return an error for any cycles it found.
cargo-modules's `dependencies` command checks for the presence of a `--acyclic` flag. If found it will search for cycles in the directed graph and return an error for any cycles it found.

Running `cargo modules generate graph --lib --acyclic` on the source of the tool itself emits the following cycle error:
Running `cargo modules dependencies --lib --acyclic` on the source of the tool itself emits the following cycle error:

```plain
Error: Circular dependency between `cargo_modules::options::general` and `cargo_modules::options::generate`.
Expand All @@ -226,6 +253,80 @@ Error: Circular dependency between `cargo_modules::options::general` and `cargo_
└──────────┘
```

### cargo modules orphans

Detect unlinked source files within a crate's directory:

```bash
cargo modules orphans <OPTIONS>
```

<details>
<summary>Command help</summary>

```terminal
$ cargo modules orphans --help

Detects unlinked source files within a crate's directory.

Usage: cargo-modules orphans [OPTIONS]

Options:
--verbose Use verbose output
--lib Process only this package's library
--bin <BIN> Process only the specified binary
-p, --package <PACKAGE> Package to process (see `cargo help pkgid`)
--no-default-features Do not activate the `default` feature
--all-features Activate all available features
--features <FEATURES> List of features to activate. This will be ignored if `--cargo-all-features` is provided
--target <TARGET> Analyze for target triple
--manifest-path <MANIFEST_PATH> Path to Cargo.toml [default: .]
--deny Returns a failure code if one or more orphans are found
--cfg-test Analyze with `#[cfg(test)]` enabled (i.e as if built via `cargo test`)
-h, --help Print help
```

</details>

#### Example

```bash
cd ./tests/projects/readme_tree_example
cargo-modules structure --types --traits --fns --tests
```

Output:

![Output of `cargo modules structure …`](docs/orphans_output.png)

```plain
2 orphans found:

warning: orphaned module `foo` at src/orphans/foo/mod.rs
--> src/orphans.rs
| ^^^^^^^^^^^^^^ orphan module not loaded from file
|
help: consider loading `foo` from module `orphans::orphans`
|
| mod foo;
| ++++++++
|

warning: orphaned module `bar` at src/orphans/bar.rs
--> src/orphans.rs
| ^^^^^^^^^^^^^^ orphan module not loaded from file
|
help: consider loading `bar` from module `orphans::orphans`
|
| mod bar;
| ++++++++
|

Error: Found 2 orphans in crate 'orphans'
```

(Project source code: [readme_tree_example/src/lib.rs](./tests/projects/readme_orphans_example/src/lib.rs))

### No-Color Mode

cargo-modules checks for the presence of a `NO_COLOR` environment variable that, when present (regardless of its value), prevents the addition of color to the console output (and only the console output!).
Expand Down
Loading
Loading