rigor-module-graph 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +119 -1
- data/README.md +152 -129
- data/lib/rigor/module_graph/cli.rb +122 -25
- data/lib/rigor/module_graph/status_reporter.rb +94 -0
- data/lib/rigor/module_graph/templates/vendor/CHECKSUMS +59 -0
- data/lib/rigor/module_graph/templates/vendor/cytoscape.min.js +31 -0
- data/lib/rigor/module_graph/templates/viewer.css +63 -0
- data/lib/rigor/module_graph/templates/viewer.html.erb +32 -0
- data/lib/rigor/module_graph/templates/viewer.js +166 -0
- data/lib/rigor/module_graph/version.rb +1 -1
- data/lib/rigor/module_graph/viewer/html.rb +132 -0
- data/lib/rigor-module-graph.rb +2 -0
- metadata +10 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0ed5f8fe6226376ad089b013b8ad16cecc453da2202cbaf6b3a590e6b64d0c85
|
|
4
|
+
data.tar.gz: 47bdbc75a44a9887a58246783fcc3f57b5f1ad119b3c336c6673e72799678fe2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae0a36d5c2107420b5a3577a2030c5417789f52ed0732f5d67669ac31444e73131135273d067e7f3fb6dfd7cafde845a7ef5183f4abd414bfae8ff446688d68d
|
|
7
|
+
data.tar.gz: 43ad7597db1d1fd945159afb81ee36339450b2ffa487bd94d21fc0da8ed0ae044af02a5b6c482044b510ee1ce0df56c2e215f72707307c8aef803ff0a9eab42e
|
data/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,122 @@ Categories:
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [0.1.3] — 2026-06-20
|
|
21
|
+
|
|
22
|
+
The first release that pairs the published gem with the
|
|
23
|
+
[interactive viewer](docs/how-it-works.md) the README has been
|
|
24
|
+
showcasing, plus the supply-chain hardening that justifies
|
|
25
|
+
shipping a vendored third-party JS file inside the gem.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **Interactive `view --output html` viewer.** Replaces the
|
|
30
|
+
static Mermaid embed with a [Cytoscape.js](https://js.cytoscape.org/)-based
|
|
31
|
+
page that renders 5k+ nodes, filters live by `kind` /
|
|
32
|
+
`confidence`, supports a name-substring search, and copies
|
|
33
|
+
`path:line` to the clipboard on node click. The Cytoscape
|
|
34
|
+
library is vendored into the gem at a sha256-pinned version
|
|
35
|
+
(`lib/rigor/module_graph/templates/vendor/cytoscape.min.js`);
|
|
36
|
+
no CDN, no npm, no Dependabot auto-bump.
|
|
37
|
+
See [`docs/plan.md`](docs/plan.md) "2D interactive viewer"
|
|
38
|
+
for the supply-chain rationale.
|
|
39
|
+
- `--path-mode {relative,absolute,none}` flag on `view` —
|
|
40
|
+
controls how node paths reach the viewer's click-through
|
|
41
|
+
metadata. `none` strips paths from the HTML artefact, which
|
|
42
|
+
is the right setting when sharing the file outside the
|
|
43
|
+
project (PR comment, gist, …).
|
|
44
|
+
- `--open-with vscode` flag on `view` — flips the node-click
|
|
45
|
+
action from clipboard copy to `vscode://file/<path>:<line>`
|
|
46
|
+
so the editor jumps straight to the source location.
|
|
47
|
+
- `bundle exec rake vendor:verify` task — recomputes sha256
|
|
48
|
+
for every file in `vendor/CHECKSUMS` and fails on mismatch.
|
|
49
|
+
Wired into pre-commit on any staged file under
|
|
50
|
+
`lib/**/templates/vendor/**`.
|
|
51
|
+
- `.github/dependabot.yml` — weekly Bundler + GitHub Actions
|
|
52
|
+
bumps; `vendor/**` is explicitly excluded so vendored
|
|
53
|
+
third-party JS never auto-updates.
|
|
54
|
+
- `bundle exec rake vendor:audit` — 4-source cross-check
|
|
55
|
+
(local sha256 / npm tarball `dist.integrity` /
|
|
56
|
+
tarball-internal copy / GitHub raw / every CDN). Reads
|
|
57
|
+
`lib/rigor/module_graph/templates/vendor/MANIFEST.yml` for
|
|
58
|
+
the provenance metadata. Use on bump PRs; not part of the
|
|
59
|
+
regular CI pipeline (network-using).
|
|
60
|
+
- CI now runs `rake vendor:verify` independently of
|
|
61
|
+
pre-commit so an unaudited bump can't land on `main` even
|
|
62
|
+
if local hooks were skipped.
|
|
63
|
+
- CI now regenerates `examples/billing/` via `script/
|
|
64
|
+
check_billing_drift.rb` and fails on drift between the
|
|
65
|
+
freshly-built artefacts and the committed copies.
|
|
66
|
+
Normalises the graphviz version banner so the runner's
|
|
67
|
+
apt-shipped version doesn't trigger a false positive.
|
|
68
|
+
- New `docs/security.md` consolidates the supply-chain story
|
|
69
|
+
(Bundler / Dependabot cooldown, vendored-JS sha256 +
|
|
70
|
+
4-source audit, action SHA pinning, OIDC trusted
|
|
71
|
+
publishing).
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
|
|
75
|
+
- **`view --output html` semantics.** The flag now produces
|
|
76
|
+
the interactive viewer. The previous static Mermaid HTML
|
|
77
|
+
moves behind `--output mermaid-html` (still loads Mermaid
|
|
78
|
+
from a CDN, kept for back-compat).
|
|
79
|
+
- CI workflows read Ruby from `.ruby-version` instead of
|
|
80
|
+
pinning `"4.0.0"` inline, so future `.ruby-version` bumps
|
|
81
|
+
no longer need a `.github/workflows/` chase.
|
|
82
|
+
- RDoc dependency bumped from `~> 6.0` to `~> 7.0` (resolves
|
|
83
|
+
to 7.2.0). `gemspec.rdoc_options` corrected to `--markup
|
|
84
|
+
markdown` to match `.rdoc_options` and the Rakefile, fixing
|
|
85
|
+
the silent inconsistency left when the README rendering
|
|
86
|
+
fix landed in [0.1.2]. No code change; `rake rdoc` emits no
|
|
87
|
+
warnings under 7.x.
|
|
88
|
+
- README hero leads with the Cytoscape viewer screenshot
|
|
89
|
+
(the default output) and the Graphviz SVG follows.
|
|
90
|
+
`examples/billing/preview.png` resized from 1280x860 to
|
|
91
|
+
720x483 so it fits the RDoc darkfish content pane on the
|
|
92
|
+
GitHub Pages site without overflow.
|
|
93
|
+
- README Documentation index re-ordered along the natural
|
|
94
|
+
reading flow: how-it-works → security → limitation →
|
|
95
|
+
development → plan.
|
|
96
|
+
|
|
97
|
+
## [0.1.2] — 2026-06-20
|
|
98
|
+
|
|
99
|
+
First release that exercises the full automated pipeline end
|
|
100
|
+
to end — Trusted Publishing + GitHub Release + asset upload
|
|
101
|
+
all drive off a single `gh workflow run release.yml` after the
|
|
102
|
+
tag is pushed.
|
|
103
|
+
|
|
104
|
+
### Added
|
|
105
|
+
|
|
106
|
+
- `view` and `collect` now emit step-level progress on stderr:
|
|
107
|
+
`==> Running rigor check ...`, post-step counts (`18 edge(s),
|
|
108
|
+
16 node(s)`), and inline elapsed time (`done (428ms)`).
|
|
109
|
+
TTY-aware — the start / done halves render inline on a
|
|
110
|
+
terminal, on separate lines for redirected output, so logs
|
|
111
|
+
stay grep-friendly. `-q` / `--quiet` suppresses the progress
|
|
112
|
+
output for scripted use; the final `wrote N edge(s) to ...`
|
|
113
|
+
summary line stays. Driven by a new `StatusReporter` class
|
|
114
|
+
pinned by `test/rigor/module_graph/status_reporter_test.rb`.
|
|
115
|
+
|
|
116
|
+
### Changed
|
|
117
|
+
|
|
118
|
+
- README restructured along the install → getting started →
|
|
119
|
+
usage → configuration flow. The "How it works" walkthrough
|
|
120
|
+
(pipeline diagram + the "not a call graph" framing) moves to
|
|
121
|
+
`docs/how-it-works.md` so the README stays focused on
|
|
122
|
+
"what do I type". Configuration section now notes that
|
|
123
|
+
`.rigor.yml` is required (rigor reads it to discover the
|
|
124
|
+
plugin), with a two-line minimum example up top and the
|
|
125
|
+
fully-elaborated default form below.
|
|
126
|
+
|
|
127
|
+
### Fixed
|
|
128
|
+
|
|
129
|
+
- RDoc generation now parses Markdown instead of RDoc syntax,
|
|
130
|
+
so `` images in `README.md` / `CHANGELOG.md` /
|
|
131
|
+
`docs/*.md` actually render. `Rake::Task[:rdoc]` is enhanced
|
|
132
|
+
to copy `examples/billing/graph.svg` (and any future
|
|
133
|
+
`RDOC_ASSET_PATHS` entries) into `doc/` so the generated site
|
|
134
|
+
resolves the relative image references the README uses.
|
|
135
|
+
|
|
20
136
|
## [0.1.1] — 2026-06-20
|
|
21
137
|
|
|
22
138
|
First Action-driven publish. The 0.1.0 release happened via the
|
|
@@ -134,6 +250,8 @@ spike through Phase 5 (UML class diagram).
|
|
|
134
250
|
baseline and YJIT, and trailed baseline on Stats and
|
|
135
251
|
CycleDetector — recommendation stays YJIT.
|
|
136
252
|
|
|
137
|
-
[Unreleased]: https://github.com/nozomemein/rigor-module-graph/compare/v0.1.
|
|
253
|
+
[Unreleased]: https://github.com/nozomemein/rigor-module-graph/compare/v0.1.3...HEAD
|
|
254
|
+
[0.1.3]: https://github.com/nozomemein/rigor-module-graph/compare/v0.1.2...v0.1.3
|
|
255
|
+
[0.1.2]: https://github.com/nozomemein/rigor-module-graph/compare/v0.1.1...v0.1.2
|
|
138
256
|
[0.1.1]: https://github.com/nozomemein/rigor-module-graph/compare/v0.1.0...v0.1.1
|
|
139
257
|
[0.1.0]: https://github.com/nozomemein/rigor-module-graph/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -1,64 +1,37 @@
|
|
|
1
1
|
# rigor-module-graph
|
|
2
2
|
|
|
3
|
+
[](https://rubygems.org/gems/rigor-module-graph)
|
|
4
|
+
[](LICENSE.txt)
|
|
5
|
+
[](https://github.com/nozomemein/rigor-module-graph/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/nozomemein/rigor-module-graph/actions/workflows/docs.yml)
|
|
7
|
+
|
|
3
8
|
Class/module/constant dependency graph for Ruby projects, built on
|
|
4
9
|
[Rigor](https://rigor.typedduck.fail/). The class-level counterpart
|
|
5
10
|
to Packwerk/Graphwerk: where those look at package boundaries, this
|
|
6
11
|
looks at the Ruby nominal graph — inheritance, `include`/`prepend`/
|
|
7
12
|
`extend`, and (later) constant references.
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
4. `from` is the lexical owner, assembled by walking
|
|
31
|
-
`context.ancestors` — so `class Billing::Invoice` produces
|
|
32
|
-
`Billing::Invoice`, not just `Invoice`.
|
|
33
|
-
5. `to` is resolved through a confidence ladder: syntax →
|
|
34
|
-
Zeitwerk convention → Rigor type information. Whatever we
|
|
35
|
-
couldn't pin down stays visible in the `confidence` field
|
|
36
|
-
rather than being dropped.
|
|
37
|
-
6. Every edge ships as a Rigor `:info` diagnostic. The `collect`
|
|
38
|
-
subcommand filters them on `rule == "edge"` and writes JSONL.
|
|
39
|
-
7. DOT, SVG, Mermaid, and cycle detection are all derived from
|
|
40
|
-
that JSONL.
|
|
41
|
-
|
|
42
|
-
So we are not watching what Ruby *does at runtime*. We're reading
|
|
43
|
-
Ruby's *named structure* and reconstructing, approximately, "which
|
|
44
|
-
constants depend on which other constants".
|
|
45
|
-
|
|
46
|
-
### This is not a call graph
|
|
47
|
-
|
|
48
|
-
We do not track who `foo.bar` resolves to at runtime. We track
|
|
49
|
-
the fact that the `Billing::Invoice` name depends on the
|
|
50
|
-
`ApplicationRecord` / `Auditable` / `Money` names. That is a
|
|
51
|
-
**nominal dependency graph** — a compiler-front-end-style view
|
|
52
|
-
of the project's syntactic and lexical structure, projected into
|
|
53
|
-
edges with explicit confidence.
|
|
54
|
-
|
|
55
|
-
Not re-implementing Ruby constant lookup is deliberate. For
|
|
56
|
-
understanding a Rails codebase's shape, it's more useful to leave
|
|
57
|
-
each edge tagged `syntax` / `zeitwerk` / `rigor_type` /
|
|
58
|
-
`unresolved` than to fake a `resolved` answer and silently get it
|
|
59
|
-
wrong.
|
|
60
|
-
|
|
61
|
-
## Installation
|
|
14
|
+
**Two ways to look at the same graph.** Static SVG via
|
|
15
|
+
Graphviz for committing into PRs and docs; interactive HTML
|
|
16
|
+
via Cytoscape.js for actually exploring a 1000+-node Rails
|
|
17
|
+
codebase. Both rendered from the same `edges.jsonl` —
|
|
18
|
+
no second analysis pass.
|
|
19
|
+
|
|
20
|
+
### Cytoscape (`--output html`, the default)
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
### Graphviz (`--output svg`)
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
Both screenshots are from `examples/billing/`. Open
|
|
29
|
+
`examples/billing/index.html` directly to try the
|
|
30
|
+
interactive version — pan, zoom, filter by `kind` /
|
|
31
|
+
`confidence`, search by name, click a node to copy
|
|
32
|
+
`path:line`.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
62
35
|
|
|
63
36
|
Via Bundler:
|
|
64
37
|
|
|
@@ -71,87 +44,101 @@ gem "rigor-module-graph"
|
|
|
71
44
|
bundle install
|
|
72
45
|
```
|
|
73
46
|
|
|
74
|
-
Or
|
|
47
|
+
Or system-wide:
|
|
75
48
|
|
|
76
49
|
```sh
|
|
77
50
|
gem install rigor-module-graph
|
|
78
51
|
```
|
|
79
52
|
|
|
80
|
-
Both paths pull in `rigortype` and `rbs ~> 4.0` transitively.
|
|
81
|
-
`rbs ~> 4.0` constraint is the
|
|
82
|
-
`RBS::Environment::ClassEntry#each_decl`, which
|
|
83
|
-
rbs 4.x. The Ruby 4.0 stdlib bundles rbs 3.10
|
|
84
|
-
so installing `rigor-module-graph` (which
|
|
85
|
-
makes RubyGems activate the 4.x gem at
|
|
86
|
-
analyzer stays alive.
|
|
87
|
-
|
|
88
|
-
## Configuration
|
|
53
|
+
Both paths pull in `rigortype` and `rbs ~> 4.0` transitively.
|
|
54
|
+
The `rbs ~> 4.0` constraint is the one that matters: rigortype
|
|
55
|
+
0.2.x calls `RBS::Environment::ClassEntry#each_decl`, which
|
|
56
|
+
only exists in rbs 4.x. The Ruby 4.0 stdlib bundles rbs 3.10
|
|
57
|
+
as a default gem, so installing `rigor-module-graph` (which
|
|
58
|
+
depends on rbs 4.x) makes RubyGems activate the 4.x gem at
|
|
59
|
+
run time and the analyzer stays alive.
|
|
89
60
|
|
|
90
|
-
|
|
61
|
+
For the full pipeline you also want `graphviz` installed so
|
|
62
|
+
`view --output svg` and `dot -Tsvg` can render PNG / SVG from
|
|
63
|
+
the generated DOT:
|
|
91
64
|
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
- app
|
|
96
|
-
- lib
|
|
97
|
-
plugins:
|
|
98
|
-
- gem: rigor-module-graph
|
|
99
|
-
config:
|
|
100
|
-
rails_zeitwerk: true
|
|
101
|
-
autoload_paths:
|
|
102
|
-
- app/models
|
|
103
|
-
- app/controllers
|
|
104
|
-
- app/services
|
|
105
|
-
- app/jobs
|
|
106
|
-
- lib
|
|
107
|
-
concern_dirs:
|
|
108
|
-
- app/models/concerns
|
|
109
|
-
- app/controllers/concerns
|
|
110
|
-
include_constant_refs: false
|
|
65
|
+
```sh
|
|
66
|
+
brew install graphviz # macOS
|
|
67
|
+
apt-get install graphviz # Debian / Ubuntu
|
|
111
68
|
```
|
|
112
69
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
`confidence: "syntax"` and skip path-based owner inference.
|
|
117
|
-
|
|
118
|
-
## Usage
|
|
70
|
+
A working `dot` on `$PATH` is optional — text / Mermaid / HTML
|
|
71
|
+
output paths don't need it. See [How it works](docs/how-it-works.md)
|
|
72
|
+
for the pipeline overview.
|
|
119
73
|
|
|
120
|
-
|
|
74
|
+
## Getting started
|
|
121
75
|
|
|
122
|
-
The default subcommand analyses the current directory, writes
|
|
123
|
-
self-contained Mermaid HTML report under
|
|
124
|
-
and opens it in
|
|
125
|
-
project.
|
|
76
|
+
The default subcommand analyses the current directory, writes
|
|
77
|
+
a self-contained Mermaid HTML report under
|
|
78
|
+
`.rigor/module_graph/`, and opens it in a browser:
|
|
126
79
|
|
|
127
80
|
```sh
|
|
128
81
|
cd path/to/your/project
|
|
129
82
|
bundle exec rigor-module-graph # same as: rigor-module-graph view
|
|
130
83
|
```
|
|
131
84
|
|
|
132
|
-
|
|
85
|
+
A `.rigor.yml` must exist in the project root — that's how
|
|
86
|
+
`rigor` knows to load this plugin. The minimal version is two
|
|
87
|
+
lines:
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
plugins:
|
|
91
|
+
- gem: rigor-module-graph
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
That's enough for `view` to run with all defaults. Everything
|
|
95
|
+
else (`paths:`, `autoload_paths:`, …) goes in the
|
|
96
|
+
[Configuration](#configuration) section below, and every key
|
|
97
|
+
defaults to a sensible Rails-shaped value.
|
|
98
|
+
|
|
99
|
+
## Usage
|
|
100
|
+
|
|
101
|
+
### `view` — one-shot HTML / SVG / Mermaid
|
|
102
|
+
|
|
103
|
+
The default `html` output is an interactive
|
|
104
|
+
[Cytoscape.js](https://js.cytoscape.org/)-based viewer:
|
|
105
|
+
filter checkboxes for `kind` and `confidence`, live name
|
|
106
|
+
search, `fit` button, and node-click → copy `path:line` to
|
|
107
|
+
the clipboard. The Cytoscape library is vendored into the gem
|
|
108
|
+
at a sha256-pinned version, so the generated HTML opens
|
|
109
|
+
offline with no network round-trip.
|
|
133
110
|
|
|
134
111
|
```sh
|
|
135
112
|
# Don't open the browser (just write the HTML)
|
|
136
113
|
rigor-module-graph view --no-open
|
|
137
114
|
|
|
138
|
-
# Pick a different output format
|
|
139
|
-
#
|
|
140
|
-
#
|
|
115
|
+
# Pick a different output format. `html` is the interactive
|
|
116
|
+
# viewer; `mermaid-html` is the legacy static-Mermaid embed
|
|
117
|
+
# (loads Mermaid from a CDN, kept for back-compat). Everything
|
|
118
|
+
# else streams to stdout unless `-o` is given.
|
|
119
|
+
rigor-module-graph view --no-open --output mermaid-html > graph.html
|
|
141
120
|
rigor-module-graph view --no-open --output mermaid > graph.mmd
|
|
142
121
|
rigor-module-graph view --no-open --output dot > graph.dot
|
|
143
122
|
rigor-module-graph view --no-open --output svg > graph.svg
|
|
144
123
|
rigor-module-graph view --no-open --output class-diagram > class.mmd
|
|
145
124
|
rigor-module-graph view --output svg -o graph.svg
|
|
146
125
|
|
|
147
|
-
#
|
|
148
|
-
#
|
|
126
|
+
# Click on a node opens the file in VSCode rather than copying
|
|
127
|
+
# path:line to the clipboard. `--path-mode none` strips the
|
|
128
|
+
# path metadata entirely — useful when sharing the HTML
|
|
129
|
+
# artefact outside the project.
|
|
130
|
+
rigor-module-graph view --open-with vscode
|
|
131
|
+
rigor-module-graph view --path-mode none # share-safe
|
|
132
|
+
rigor-module-graph view --path-mode absolute # cwd-resolved
|
|
133
|
+
|
|
134
|
+
# Focus on what's around one or a few constants
|
|
149
135
|
rigor-module-graph view --from Article --depth 5
|
|
150
136
|
rigor-module-graph view --from Article --depth 5 --direction out
|
|
151
137
|
rigor-module-graph view --from Billing::Invoice,Billing::Payment --depth 2
|
|
152
138
|
|
|
153
139
|
# Pick your own collapse list (default: auto-detect top-level
|
|
154
|
-
# namespaces with ≥ 3 members
|
|
140
|
+
# namespaces with ≥ 3 members; applies to mermaid / dot / svg
|
|
141
|
+
# outputs — the interactive html viewer ignores it).
|
|
155
142
|
rigor-module-graph view --collapse Billing,Auth
|
|
156
143
|
rigor-module-graph view --no-collapse
|
|
157
144
|
|
|
@@ -164,7 +151,7 @@ rigor-module-graph view --package
|
|
|
164
151
|
rigor-module-graph view --package-root /path/to/repo
|
|
165
152
|
```
|
|
166
153
|
|
|
167
|
-
`--direction` controls how the
|
|
154
|
+
`--direction` controls how the `--from` walk follows edges:
|
|
168
155
|
|
|
169
156
|
| direction | meaning |
|
|
170
157
|
|-----------|----------------------------------------|
|
|
@@ -179,17 +166,19 @@ rigor-module-graph view --package-root /path/to/repo
|
|
|
179
166
|
| `cluster` | keep every edge whose endpoints both fall in the reachable set (default — good for "show me the Article neighbourhood as a cluster") |
|
|
180
167
|
| `walk` | keep only the edges the BFS actually traversed (good for "show me what depends on Article and nothing else"; drops sibling edges like `Foo inherits ApplicationRecord` that just happen to share a base class with reachable nodes) |
|
|
181
168
|
|
|
182
|
-
A 1-hop `--from Article --direction out --edge-scope walk`
|
|
183
|
-
exactly the edges whose `from` is `Article`, never the
|
|
184
|
-
`inherits ApplicationRecord` of a reached node.
|
|
169
|
+
A 1-hop `--from Article --direction out --edge-scope walk`
|
|
170
|
+
returns exactly the edges whose `from` is `Article`, never the
|
|
171
|
+
sibling `inherits ApplicationRecord` of a reached node.
|
|
185
172
|
|
|
186
173
|
### Lower-level pipeline
|
|
187
174
|
|
|
188
|
-
The pipeline `view` runs is also exposed as discrete
|
|
189
|
-
when you want JSONL on disk or a pipeable text
|
|
175
|
+
The pipeline `view` runs is also exposed as discrete
|
|
176
|
+
subcommands when you want JSONL on disk or a pipeable text
|
|
177
|
+
output:
|
|
190
178
|
|
|
191
179
|
```sh
|
|
192
|
-
# Run `rigor check` and write edges JSONL
|
|
180
|
+
# Run `rigor check` and write edges JSONL
|
|
181
|
+
# (default: .rigor/module_graph/edges.jsonl)
|
|
193
182
|
bundle exec rigor-module-graph collect
|
|
194
183
|
|
|
195
184
|
# Render the graph
|
|
@@ -210,18 +199,19 @@ bundle exec rigor-module-graph class-diagram .rigor/module_graph/edges.jsonl > c
|
|
|
210
199
|
bundle exec rigor-module-graph class-diagram --no-private --no-attributes edges.jsonl
|
|
211
200
|
```
|
|
212
201
|
|
|
213
|
-
`collect` shells out to `rigor check --format json --no-cache`
|
|
214
|
-
filters diagnostics on
|
|
215
|
-
`
|
|
216
|
-
|
|
202
|
+
`collect` shells out to `rigor check --format json --no-cache`
|
|
203
|
+
and filters diagnostics on
|
|
204
|
+
`source_family == "plugin.module-graph"` + `rule == "edge"`,
|
|
205
|
+
so re-running is deterministic and there's no on-disk
|
|
206
|
+
side-effect from the plugin itself.
|
|
217
207
|
|
|
218
208
|
`dot` / `mermaid` / `cycles` accept a file argument or read stdin.
|
|
219
209
|
|
|
220
210
|
### Filters and collapse
|
|
221
211
|
|
|
222
|
-
All
|
|
223
|
-
|
|
224
|
-
|
|
212
|
+
All reader subcommands accept the same filter flags. They prune
|
|
213
|
+
the edge set before rendering / detecting; the JSONL on disk is
|
|
214
|
+
untouched.
|
|
225
215
|
|
|
226
216
|
```sh
|
|
227
217
|
# Drop noisy const_ref / unresolved edges
|
|
@@ -230,7 +220,8 @@ bundle exec rigor-module-graph dot --kind inherits,include,prepend,extend edges.
|
|
|
230
220
|
# Only the edges we're sure about
|
|
231
221
|
bundle exec rigor-module-graph dot --confidence syntax,zeitwerk,rigor_type edges.jsonl
|
|
232
222
|
|
|
233
|
-
# Fold every Billing::* node into one cluster
|
|
223
|
+
# Fold every Billing::* node into one cluster
|
|
224
|
+
# (Dot: subgraph_cluster_; Mermaid: subgraph)
|
|
234
225
|
bundle exec rigor-module-graph dot --collapse Billing,Auth edges.jsonl
|
|
235
226
|
bundle exec rigor-module-graph mermaid --collapse Billing edges.jsonl
|
|
236
227
|
|
|
@@ -247,21 +238,45 @@ bundle exec rigor-module-graph mermaid --package-root /path/to/repo edges.jsonl
|
|
|
247
238
|
bundle exec rigor-module-graph cycles --kind inherits,include edges.jsonl
|
|
248
239
|
```
|
|
249
240
|
|
|
250
|
-
##
|
|
241
|
+
## Configuration
|
|
251
242
|
|
|
252
|
-
|
|
243
|
+
`.rigor.yml` lives in the project root and is **required** —
|
|
244
|
+
`rigor` reads it to discover this plugin. `rigor init` scaffolds
|
|
245
|
+
a `.rigor.dist.yml` you can rename, or write it by hand. The
|
|
246
|
+
two-line minimum from [Getting started](#getting-started) is
|
|
247
|
+
enough; the full form below is for tuning.
|
|
253
248
|
|
|
254
|
-
```
|
|
255
|
-
|
|
249
|
+
```yaml
|
|
250
|
+
target_ruby: '4.0'
|
|
251
|
+
paths:
|
|
252
|
+
- app
|
|
253
|
+
- lib
|
|
254
|
+
plugins:
|
|
255
|
+
- gem: rigor-module-graph
|
|
256
|
+
config:
|
|
257
|
+
rails_zeitwerk: true
|
|
258
|
+
autoload_paths:
|
|
259
|
+
- app/models
|
|
260
|
+
- app/controllers
|
|
261
|
+
- app/services
|
|
262
|
+
- app/jobs
|
|
263
|
+
- lib
|
|
264
|
+
concern_dirs:
|
|
265
|
+
- app/models/concerns
|
|
266
|
+
- app/controllers/concerns
|
|
267
|
+
include_constant_refs: false
|
|
256
268
|
```
|
|
257
269
|
|
|
258
|
-
|
|
259
|
-
`const_ref` (the last one is reserved for Phase 2).
|
|
260
|
-
- `confidence`: `syntax` / `zeitwerk` / `rigor_type` /
|
|
261
|
-
`unresolved`. MVP only emits `syntax`.
|
|
270
|
+
Every key shown is the default. Two switches worth knowing:
|
|
262
271
|
|
|
263
|
-
|
|
264
|
-
|
|
272
|
+
- `include_constant_refs: true` — emit `const_ref` edges from
|
|
273
|
+
bare constant references inside method bodies. Off by default
|
|
274
|
+
because the volume of edges grows fast on a typical Rails app
|
|
275
|
+
and the noise can drown the structural picture.
|
|
276
|
+
- `rails_zeitwerk: false` — keep every edge at
|
|
277
|
+
`confidence: "syntax"` and skip the path-based owner
|
|
278
|
+
inference. Useful when the project doesn't follow Zeitwerk's
|
|
279
|
+
autoload convention.
|
|
265
280
|
|
|
266
281
|
## Compatibility
|
|
267
282
|
|
|
@@ -279,14 +294,22 @@ published to GitHub Pages on every push to `main`.
|
|
|
279
294
|
built from `main`, mirrors the current source.
|
|
280
295
|
- [API reference (RubyGems)](https://rubydoc.info/gems/rigor-module-graph) —
|
|
281
296
|
the last released gem on rubydoc.info.
|
|
297
|
+
- [How it works](docs/how-it-works.md) — the static-analysis
|
|
298
|
+
pipeline (Prism → node rules → confidence ladder → JSONL →
|
|
299
|
+
renderers), and why this is a nominal dependency graph and
|
|
300
|
+
not a call graph.
|
|
301
|
+
- [Security](docs/security.md) — supply-chain controls
|
|
302
|
+
(Bundler cooldown, vendored-JS sha256 + 4-source audit,
|
|
303
|
+
action SHA pinning, trusted publishing) and the layered
|
|
304
|
+
pre-commit / CI gates that enforce them.
|
|
305
|
+
- [Known limitations](docs/limitation.md) — rough edges shipped
|
|
306
|
+
with the current release (visibility tracker gaps, the
|
|
307
|
+
bundled inflector, Mermaid 10.x quirks).
|
|
282
308
|
- [Development guide](docs/development.md) — local setup, git
|
|
283
309
|
hooks, CI / Release workflows, test suite layout.
|
|
284
310
|
- [Design plan](docs/plan.md) — the decisions still
|
|
285
311
|
load-bearing for the code (edge model, confidence ladder,
|
|
286
312
|
output channel, owner resolution, architecture map).
|
|
287
|
-
- [Known limitations](docs/limitation.md) — rough edges shipped
|
|
288
|
-
with the current release (visibility tracker gaps, the
|
|
289
|
-
bundled inflector, Mermaid 10.x quirks).
|
|
290
313
|
- [Changelog](CHANGELOG.md) — per-version changes, formatted
|
|
291
314
|
per [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
292
315
|
with [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|