ros2inspector 0.1.0__tar.gz
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.
- ros2inspector-0.1.0/LICENSE +21 -0
- ros2inspector-0.1.0/PKG-INFO +312 -0
- ros2inspector-0.1.0/README.md +273 -0
- ros2inspector-0.1.0/pyproject.toml +93 -0
- ros2inspector-0.1.0/ros2inspector/__init__.py +10 -0
- ros2inspector-0.1.0/ros2inspector/cache/__init__.py +0 -0
- ros2inspector-0.1.0/ros2inspector/cache/analysis_cache.py +110 -0
- ros2inspector-0.1.0/ros2inspector/cli/__init__.py +0 -0
- ros2inspector-0.1.0/ros2inspector/cli/_output.py +15 -0
- ros2inspector-0.1.0/ros2inspector/cli/_state.py +5 -0
- ros2inspector-0.1.0/ros2inspector/cli/_workspace.py +56 -0
- ros2inspector-0.1.0/ros2inspector/cli/app.py +55 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_audit.py +362 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_graph.py +77 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_nodes.py +274 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_packages.py +119 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_scan.py +88 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_validate.py +175 -0
- ros2inspector-0.1.0/ros2inspector/cli/cmd_viz.py +59 -0
- ros2inspector-0.1.0/ros2inspector/discovery/__init__.py +23 -0
- ros2inspector-0.1.0/ros2inspector/discovery/errors.py +34 -0
- ros2inspector-0.1.0/ros2inspector/discovery/interface_finder.py +8 -0
- ros2inspector-0.1.0/ros2inspector/discovery/package_finder.py +93 -0
- ros2inspector-0.1.0/ros2inspector/discovery/workspace.py +48 -0
- ros2inspector-0.1.0/ros2inspector/graph/__init__.py +3 -0
- ros2inspector-0.1.0/ros2inspector/graph/renderer.py +178 -0
- ros2inspector-0.1.0/ros2inspector/model/__init__.py +25 -0
- ros2inspector-0.1.0/ros2inspector/model/schemas.py +105 -0
- ros2inspector-0.1.0/ros2inspector/model/uam.py +694 -0
- ros2inspector-0.1.0/ros2inspector/output/__init__.py +0 -0
- ros2inspector-0.1.0/ros2inspector/policy/__init__.py +3 -0
- ros2inspector-0.1.0/ros2inspector/policy/engine.py +141 -0
- ros2inspector-0.1.0/ros2inspector/policy/rules.py +482 -0
- ros2inspector-0.1.0/ros2inspector/static/__init__.py +18 -0
- ros2inspector-0.1.0/ros2inspector/static/cpp_parser.py +316 -0
- ros2inspector-0.1.0/ros2inspector/static/health_scorer.py +100 -0
- ros2inspector-0.1.0/ros2inspector/static/interface_parser.py +39 -0
- ros2inspector-0.1.0/ros2inspector/static/launch_analyzer.py +229 -0
- ros2inspector-0.1.0/ros2inspector/static/package_xml.py +80 -0
- ros2inspector-0.1.0/ros2inspector/static/python_parser.py +257 -0
- ros2inspector-0.1.0/ros2inspector/utils/__init__.py +0 -0
- ros2inspector-0.1.0/ros2inspector/utils/enums.py +10 -0
- ros2inspector-0.1.0/ros2inspector/viz/__init__.py +3 -0
- ros2inspector-0.1.0/ros2inspector/viz/_cytoscape.min.js +32 -0
- ros2inspector-0.1.0/ros2inspector/viz/renderer.py +868 -0
- ros2inspector-0.1.0/ros2inspector.egg-info/PKG-INFO +312 -0
- ros2inspector-0.1.0/ros2inspector.egg-info/SOURCES.txt +50 -0
- ros2inspector-0.1.0/ros2inspector.egg-info/dependency_links.txt +1 -0
- ros2inspector-0.1.0/ros2inspector.egg-info/entry_points.txt +2 -0
- ros2inspector-0.1.0/ros2inspector.egg-info/requires.txt +15 -0
- ros2inspector-0.1.0/ros2inspector.egg-info/top_level.txt +1 -0
- ros2inspector-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amine Bensaid
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ros2inspector
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Static ROS 2 architecture analysis, visualization, and policy checking
|
|
5
|
+
Author-email: Amine Bensaid <aminebensaid66@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aminebensaid66/ros2_inspector
|
|
8
|
+
Project-URL: Documentation, https://github.com/aminebensaid66/ros2_inspector_website
|
|
9
|
+
Project-URL: Repository, https://github.com/aminebensaid66/ros2_inspector
|
|
10
|
+
Project-URL: Issues, https://github.com/aminebensaid66/ros2_inspector/issues
|
|
11
|
+
Keywords: ros2,robotics,architecture,static-analysis,cli
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: typer>=0.12
|
|
25
|
+
Requires-Dist: rich>=13.7
|
|
26
|
+
Requires-Dist: networkx<3.5,>=3.3
|
|
27
|
+
Requires-Dist: pydantic>=2.7
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: orjson>=3.10
|
|
30
|
+
Requires-Dist: tree-sitter>=0.22
|
|
31
|
+
Requires-Dist: tree-sitter-cpp>=0.22
|
|
32
|
+
Requires-Dist: diskcache>=5.6
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=8.2; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
36
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# ros2inspector
|
|
41
|
+
|
|
42
|
+
**Static ROS 2 architecture analysis, visualization, and policy checks.**
|
|
43
|
+
|
|
44
|
+
`ros2inspector` scans supported Python, C++, interface, and launch-file patterns in a ROS 2 workspace. It builds an evidence-backed architecture graph, renders that graph in several formats, and enforces architecture policies in CI.
|
|
45
|
+
|
|
46
|
+
This first release ships seven commands: `scan`, `packages`, `nodes`, `graph`, `viz`, `audit`, and `validate`.
|
|
47
|
+
|
|
48
|
+
## Features
|
|
49
|
+
|
|
50
|
+
- Static node and endpoint discovery with Python AST and Tree-sitter C++ parsers
|
|
51
|
+
- `.msg`, `.srv`, and `.action` interface parsing and type resolution
|
|
52
|
+
- Python, XML, and YAML launch-file analysis with per-node remapping
|
|
53
|
+
- NetworkX Unified Architecture Model for packages, nodes, topics, services, actions, and interfaces
|
|
54
|
+
- Content-fingerprinted incremental analysis cache backed by diskcache
|
|
55
|
+
- Rich table, JSON, YAML, Mermaid, DOT, and interactive HTML output
|
|
56
|
+
- Built-in connectivity audit and YAML policy enforcement
|
|
57
|
+
|
|
58
|
+
## Analysis scope
|
|
59
|
+
|
|
60
|
+
ROS 2 Inspector analyzes source files without executing or building the workspace. Unsupported or ambiguous constructs are reported through evidence, confidence, dynamic-name flags, or diagnostics rather than presented as complete architectural truth.
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
Requires Python 3.10 or newer. A ROS 2 installation is not required for source analysis.
|
|
65
|
+
|
|
66
|
+
For a globally available CLI in an isolated environment, use `pipx`:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pipx install ros2inspector
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Run it once without keeping it installed:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pipx run ros2inspector --help
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Inside an existing Python virtual environment, use `pip`:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install ros2inspector
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Install from source for development:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://github.com/aminebensaid66/ros2_inspector
|
|
88
|
+
cd ros2_inspector
|
|
89
|
+
pip install -e ".[dev]"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Quickstart
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Workspace summary
|
|
96
|
+
ros2inspector scan
|
|
97
|
+
|
|
98
|
+
# Package metadata and dependencies
|
|
99
|
+
ros2inspector packages --show-deps
|
|
100
|
+
|
|
101
|
+
# Nodes and their connections
|
|
102
|
+
ros2inspector nodes --show-connections
|
|
103
|
+
|
|
104
|
+
# Communication graph as Mermaid
|
|
105
|
+
ros2inspector graph comms --format mermaid
|
|
106
|
+
|
|
107
|
+
# Interactive HTML graph
|
|
108
|
+
ros2inspector viz --no-open
|
|
109
|
+
|
|
110
|
+
# Built-in architecture checks
|
|
111
|
+
ros2inspector audit
|
|
112
|
+
|
|
113
|
+
# Policy enforcement
|
|
114
|
+
ros2inspector validate --policy ros2inspector_policy.yaml
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Commands
|
|
118
|
+
|
|
119
|
+
### `scan`
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
ros2inspector scan [PATH] [--format table|json|yaml]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Discovers ROS 2 packages and displays a health-scored workspace summary.
|
|
126
|
+
|
|
127
|
+
### `packages`
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
ros2inspector packages [-C PATH] [--filter cpp|python|meta] [--sort name|score|version] [--show-deps] [--format table|json|yaml]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Shows package metadata, type, license, maintainers, health score, and optional dependency details.
|
|
134
|
+
|
|
135
|
+
### `nodes`
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
ros2inspector nodes [-C PATH] [--format table|json|yaml] [-p PACKAGE] [-o FILE] [--show-connections] [--no-cache]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Lists discovered nodes and their publishers, subscriptions, services, clients, action servers, and action clients. `--show-connections` includes resolved peer connections and interface types.
|
|
142
|
+
|
|
143
|
+
### `graph`
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
ros2inspector graph [deps|comms|full] [-C PATH] [--format mermaid|dot|json] [-p PACKAGE] [-o FILE] [--no-cache]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Graph views:
|
|
150
|
+
|
|
151
|
+
| View | Contents |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `deps` | Package dependencies |
|
|
154
|
+
| `comms` | Node-to-topic, service, and action communication |
|
|
155
|
+
| `full` | Dependency and communication relationships together |
|
|
156
|
+
|
|
157
|
+
Examples:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
ros2inspector graph deps --format json
|
|
161
|
+
ros2inspector graph comms --format mermaid -o architecture.mmd
|
|
162
|
+
ros2inspector graph full --format dot | dot -Tsvg -o architecture.svg
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `viz`
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
ros2inspector viz [-C PATH] [-o FILE] [--open|--no-open] [--no-cache]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Generates a self-contained interactive Cytoscape.js HTML graph.
|
|
172
|
+
|
|
173
|
+
### `audit`
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
ros2inspector audit [PATH] [--format table|json|yaml] [--fail-on error|warning|info] [--strict] [--exclude NAME] [--no-cache]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Runs built-in connectivity checks for orphan topics, dead outputs, isolated nodes, and unmatched service or action endpoints.
|
|
180
|
+
|
|
181
|
+
### `validate`
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
ros2inspector validate [PATH] --policy FILE [--fail-on error|warning|info] [--format table|json|yaml] [--no-cache]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Validates the workspace against a YAML policy file.
|
|
188
|
+
|
|
189
|
+
## Global options
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
ros2inspector --version
|
|
193
|
+
ros2inspector --quiet scan
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`--version` prints the package version. `--quiet` suppresses diagnostic headers and progress output.
|
|
197
|
+
|
|
198
|
+
## Output formats
|
|
199
|
+
|
|
200
|
+
`scan`, `packages`, `nodes`, `audit`, and `validate` support table, JSON, and YAML output where applicable. `graph` supports Mermaid, DOT, and JSON. `viz` writes interactive HTML.
|
|
201
|
+
|
|
202
|
+
Machine-readable records go to standard output while diagnostics go to standard error, which keeps pipelines clean:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
ros2inspector nodes --format json | jq '.[] | select(.package == "my_pkg")'
|
|
206
|
+
ros2inspector audit --format yaml > audit.yaml
|
|
207
|
+
ros2inspector graph comms --format mermaid -o architecture.mmd
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Policy files
|
|
211
|
+
|
|
212
|
+
Create a `ros2inspector_policy.yaml` file:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
version: 1
|
|
216
|
+
rules:
|
|
217
|
+
- type: health_threshold
|
|
218
|
+
min_score: 70
|
|
219
|
+
severity: warning
|
|
220
|
+
|
|
221
|
+
- type: license
|
|
222
|
+
allowed: [Apache-2.0, MIT]
|
|
223
|
+
severity: error
|
|
224
|
+
|
|
225
|
+
- type: naming
|
|
226
|
+
packages:
|
|
227
|
+
pattern: '^[a-z][a-z0-9_]*$'
|
|
228
|
+
severity: warning
|
|
229
|
+
nodes:
|
|
230
|
+
pattern: '^[A-Z][a-zA-Z0-9]*Node$'
|
|
231
|
+
severity: info
|
|
232
|
+
|
|
233
|
+
- type: dependency
|
|
234
|
+
forbidden:
|
|
235
|
+
- { from: perception, to: planner, severity: error }
|
|
236
|
+
required:
|
|
237
|
+
- { package: navigation, depends_on: nav_core, severity: warning }
|
|
238
|
+
|
|
239
|
+
- type: no_circular_deps
|
|
240
|
+
severity: error
|
|
241
|
+
|
|
242
|
+
- type: topic_connectivity
|
|
243
|
+
no_publisher: true
|
|
244
|
+
no_subscriber: true
|
|
245
|
+
exclude: [/rosout, /clock]
|
|
246
|
+
|
|
247
|
+
- type: maintainer_required
|
|
248
|
+
require_email: true
|
|
249
|
+
severity: warning
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Supported rule types are `health_threshold`, `license`, `naming`, `dependency`, `no_circular_deps`, `topic_connectivity`, `node_isolation`, `service_connectivity`, `action_connectivity`, `maintainer_required`, and `version_not_default`.
|
|
253
|
+
|
|
254
|
+
## CI integration
|
|
255
|
+
|
|
256
|
+
```yaml
|
|
257
|
+
- name: Install ROS 2 Inspector
|
|
258
|
+
run: pip install ros2inspector
|
|
259
|
+
|
|
260
|
+
- name: Architecture audit
|
|
261
|
+
run: ros2inspector audit --fail-on warning --format json > audit.json
|
|
262
|
+
|
|
263
|
+
- name: Policy validation
|
|
264
|
+
run: ros2inspector validate --policy .ros2inspector_policy.yaml --fail-on error
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Relevant exit codes:
|
|
268
|
+
|
|
269
|
+
| Code | Meaning |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `0` | Success or no findings at the configured threshold |
|
|
272
|
+
| `1` | Findings at or above the configured threshold |
|
|
273
|
+
| `2` | Invalid invocation or policy configuration |
|
|
274
|
+
| `3` | Workspace or policy file not found |
|
|
275
|
+
|
|
276
|
+
## Architecture
|
|
277
|
+
|
|
278
|
+
```text
|
|
279
|
+
ros2inspector/
|
|
280
|
+
├── cli/ # scan, packages, nodes, graph, viz, audit, validate
|
|
281
|
+
├── discovery/ # workspace, package, and interface discovery
|
|
282
|
+
├── static/ # Python, C++, interface, launch, package, and health parsers
|
|
283
|
+
├── model/ # Pydantic schemas and the NetworkX UAM
|
|
284
|
+
├── graph/ # Mermaid, DOT, and JSON renderers
|
|
285
|
+
├── viz/ # interactive HTML renderer and bundled Cytoscape.js
|
|
286
|
+
├── policy/ # policy loader, engine, and rules
|
|
287
|
+
├── cache/ # diskcache-backed incremental analysis
|
|
288
|
+
├── output/ # output package plumbing
|
|
289
|
+
└── utils/ # shared utilities
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
The Unified Architecture Model is a `networkx.MultiDiGraph`. Graph nodes represent packages, ROS nodes, topics, services, actions, and interfaces. Edges carry relationships such as `depends_on`, `publishes`, `subscribes`, `provides`, `calls`, `defined_in`, and `uses_interface`.
|
|
293
|
+
|
|
294
|
+
## Development
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
pip install -e ".[dev]"
|
|
298
|
+
pytest
|
|
299
|
+
ruff check ros2inspector/
|
|
300
|
+
mypy ros2inspector/
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
The test suite uses fixture workspaces under `tests/fixtures/` and does not require a live ROS 2 environment.
|
|
304
|
+
|
|
305
|
+
## Publishing
|
|
306
|
+
|
|
307
|
+
Maintainers should follow [`RELEASING.md`](RELEASING.md). Publishing is performed by
|
|
308
|
+
GitHub Actions through PyPI Trusted Publishing when a GitHub Release is published.
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT. See [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# ros2inspector
|
|
2
|
+
|
|
3
|
+
**Static ROS 2 architecture analysis, visualization, and policy checks.**
|
|
4
|
+
|
|
5
|
+
`ros2inspector` scans supported Python, C++, interface, and launch-file patterns in a ROS 2 workspace. It builds an evidence-backed architecture graph, renders that graph in several formats, and enforces architecture policies in CI.
|
|
6
|
+
|
|
7
|
+
This first release ships seven commands: `scan`, `packages`, `nodes`, `graph`, `viz`, `audit`, and `validate`.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Static node and endpoint discovery with Python AST and Tree-sitter C++ parsers
|
|
12
|
+
- `.msg`, `.srv`, and `.action` interface parsing and type resolution
|
|
13
|
+
- Python, XML, and YAML launch-file analysis with per-node remapping
|
|
14
|
+
- NetworkX Unified Architecture Model for packages, nodes, topics, services, actions, and interfaces
|
|
15
|
+
- Content-fingerprinted incremental analysis cache backed by diskcache
|
|
16
|
+
- Rich table, JSON, YAML, Mermaid, DOT, and interactive HTML output
|
|
17
|
+
- Built-in connectivity audit and YAML policy enforcement
|
|
18
|
+
|
|
19
|
+
## Analysis scope
|
|
20
|
+
|
|
21
|
+
ROS 2 Inspector analyzes source files without executing or building the workspace. Unsupported or ambiguous constructs are reported through evidence, confidence, dynamic-name flags, or diagnostics rather than presented as complete architectural truth.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Requires Python 3.10 or newer. A ROS 2 installation is not required for source analysis.
|
|
26
|
+
|
|
27
|
+
For a globally available CLI in an isolated environment, use `pipx`:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pipx install ros2inspector
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Run it once without keeping it installed:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pipx run ros2inspector --help
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Inside an existing Python virtual environment, use `pip`:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install ros2inspector
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Install from source for development:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/aminebensaid66/ros2_inspector
|
|
49
|
+
cd ros2_inspector
|
|
50
|
+
pip install -e ".[dev]"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Workspace summary
|
|
57
|
+
ros2inspector scan
|
|
58
|
+
|
|
59
|
+
# Package metadata and dependencies
|
|
60
|
+
ros2inspector packages --show-deps
|
|
61
|
+
|
|
62
|
+
# Nodes and their connections
|
|
63
|
+
ros2inspector nodes --show-connections
|
|
64
|
+
|
|
65
|
+
# Communication graph as Mermaid
|
|
66
|
+
ros2inspector graph comms --format mermaid
|
|
67
|
+
|
|
68
|
+
# Interactive HTML graph
|
|
69
|
+
ros2inspector viz --no-open
|
|
70
|
+
|
|
71
|
+
# Built-in architecture checks
|
|
72
|
+
ros2inspector audit
|
|
73
|
+
|
|
74
|
+
# Policy enforcement
|
|
75
|
+
ros2inspector validate --policy ros2inspector_policy.yaml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Commands
|
|
79
|
+
|
|
80
|
+
### `scan`
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
ros2inspector scan [PATH] [--format table|json|yaml]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Discovers ROS 2 packages and displays a health-scored workspace summary.
|
|
87
|
+
|
|
88
|
+
### `packages`
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
ros2inspector packages [-C PATH] [--filter cpp|python|meta] [--sort name|score|version] [--show-deps] [--format table|json|yaml]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Shows package metadata, type, license, maintainers, health score, and optional dependency details.
|
|
95
|
+
|
|
96
|
+
### `nodes`
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
ros2inspector nodes [-C PATH] [--format table|json|yaml] [-p PACKAGE] [-o FILE] [--show-connections] [--no-cache]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Lists discovered nodes and their publishers, subscriptions, services, clients, action servers, and action clients. `--show-connections` includes resolved peer connections and interface types.
|
|
103
|
+
|
|
104
|
+
### `graph`
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
ros2inspector graph [deps|comms|full] [-C PATH] [--format mermaid|dot|json] [-p PACKAGE] [-o FILE] [--no-cache]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Graph views:
|
|
111
|
+
|
|
112
|
+
| View | Contents |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `deps` | Package dependencies |
|
|
115
|
+
| `comms` | Node-to-topic, service, and action communication |
|
|
116
|
+
| `full` | Dependency and communication relationships together |
|
|
117
|
+
|
|
118
|
+
Examples:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
ros2inspector graph deps --format json
|
|
122
|
+
ros2inspector graph comms --format mermaid -o architecture.mmd
|
|
123
|
+
ros2inspector graph full --format dot | dot -Tsvg -o architecture.svg
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `viz`
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
ros2inspector viz [-C PATH] [-o FILE] [--open|--no-open] [--no-cache]
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Generates a self-contained interactive Cytoscape.js HTML graph.
|
|
133
|
+
|
|
134
|
+
### `audit`
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
ros2inspector audit [PATH] [--format table|json|yaml] [--fail-on error|warning|info] [--strict] [--exclude NAME] [--no-cache]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Runs built-in connectivity checks for orphan topics, dead outputs, isolated nodes, and unmatched service or action endpoints.
|
|
141
|
+
|
|
142
|
+
### `validate`
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
ros2inspector validate [PATH] --policy FILE [--fail-on error|warning|info] [--format table|json|yaml] [--no-cache]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Validates the workspace against a YAML policy file.
|
|
149
|
+
|
|
150
|
+
## Global options
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
ros2inspector --version
|
|
154
|
+
ros2inspector --quiet scan
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`--version` prints the package version. `--quiet` suppresses diagnostic headers and progress output.
|
|
158
|
+
|
|
159
|
+
## Output formats
|
|
160
|
+
|
|
161
|
+
`scan`, `packages`, `nodes`, `audit`, and `validate` support table, JSON, and YAML output where applicable. `graph` supports Mermaid, DOT, and JSON. `viz` writes interactive HTML.
|
|
162
|
+
|
|
163
|
+
Machine-readable records go to standard output while diagnostics go to standard error, which keeps pipelines clean:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
ros2inspector nodes --format json | jq '.[] | select(.package == "my_pkg")'
|
|
167
|
+
ros2inspector audit --format yaml > audit.yaml
|
|
168
|
+
ros2inspector graph comms --format mermaid -o architecture.mmd
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Policy files
|
|
172
|
+
|
|
173
|
+
Create a `ros2inspector_policy.yaml` file:
|
|
174
|
+
|
|
175
|
+
```yaml
|
|
176
|
+
version: 1
|
|
177
|
+
rules:
|
|
178
|
+
- type: health_threshold
|
|
179
|
+
min_score: 70
|
|
180
|
+
severity: warning
|
|
181
|
+
|
|
182
|
+
- type: license
|
|
183
|
+
allowed: [Apache-2.0, MIT]
|
|
184
|
+
severity: error
|
|
185
|
+
|
|
186
|
+
- type: naming
|
|
187
|
+
packages:
|
|
188
|
+
pattern: '^[a-z][a-z0-9_]*$'
|
|
189
|
+
severity: warning
|
|
190
|
+
nodes:
|
|
191
|
+
pattern: '^[A-Z][a-zA-Z0-9]*Node$'
|
|
192
|
+
severity: info
|
|
193
|
+
|
|
194
|
+
- type: dependency
|
|
195
|
+
forbidden:
|
|
196
|
+
- { from: perception, to: planner, severity: error }
|
|
197
|
+
required:
|
|
198
|
+
- { package: navigation, depends_on: nav_core, severity: warning }
|
|
199
|
+
|
|
200
|
+
- type: no_circular_deps
|
|
201
|
+
severity: error
|
|
202
|
+
|
|
203
|
+
- type: topic_connectivity
|
|
204
|
+
no_publisher: true
|
|
205
|
+
no_subscriber: true
|
|
206
|
+
exclude: [/rosout, /clock]
|
|
207
|
+
|
|
208
|
+
- type: maintainer_required
|
|
209
|
+
require_email: true
|
|
210
|
+
severity: warning
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Supported rule types are `health_threshold`, `license`, `naming`, `dependency`, `no_circular_deps`, `topic_connectivity`, `node_isolation`, `service_connectivity`, `action_connectivity`, `maintainer_required`, and `version_not_default`.
|
|
214
|
+
|
|
215
|
+
## CI integration
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
- name: Install ROS 2 Inspector
|
|
219
|
+
run: pip install ros2inspector
|
|
220
|
+
|
|
221
|
+
- name: Architecture audit
|
|
222
|
+
run: ros2inspector audit --fail-on warning --format json > audit.json
|
|
223
|
+
|
|
224
|
+
- name: Policy validation
|
|
225
|
+
run: ros2inspector validate --policy .ros2inspector_policy.yaml --fail-on error
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Relevant exit codes:
|
|
229
|
+
|
|
230
|
+
| Code | Meaning |
|
|
231
|
+
|---|---|
|
|
232
|
+
| `0` | Success or no findings at the configured threshold |
|
|
233
|
+
| `1` | Findings at or above the configured threshold |
|
|
234
|
+
| `2` | Invalid invocation or policy configuration |
|
|
235
|
+
| `3` | Workspace or policy file not found |
|
|
236
|
+
|
|
237
|
+
## Architecture
|
|
238
|
+
|
|
239
|
+
```text
|
|
240
|
+
ros2inspector/
|
|
241
|
+
├── cli/ # scan, packages, nodes, graph, viz, audit, validate
|
|
242
|
+
├── discovery/ # workspace, package, and interface discovery
|
|
243
|
+
├── static/ # Python, C++, interface, launch, package, and health parsers
|
|
244
|
+
├── model/ # Pydantic schemas and the NetworkX UAM
|
|
245
|
+
├── graph/ # Mermaid, DOT, and JSON renderers
|
|
246
|
+
├── viz/ # interactive HTML renderer and bundled Cytoscape.js
|
|
247
|
+
├── policy/ # policy loader, engine, and rules
|
|
248
|
+
├── cache/ # diskcache-backed incremental analysis
|
|
249
|
+
├── output/ # output package plumbing
|
|
250
|
+
└── utils/ # shared utilities
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The Unified Architecture Model is a `networkx.MultiDiGraph`. Graph nodes represent packages, ROS nodes, topics, services, actions, and interfaces. Edges carry relationships such as `depends_on`, `publishes`, `subscribes`, `provides`, `calls`, `defined_in`, and `uses_interface`.
|
|
254
|
+
|
|
255
|
+
## Development
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
pip install -e ".[dev]"
|
|
259
|
+
pytest
|
|
260
|
+
ruff check ros2inspector/
|
|
261
|
+
mypy ros2inspector/
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
The test suite uses fixture workspaces under `tests/fixtures/` and does not require a live ROS 2 environment.
|
|
265
|
+
|
|
266
|
+
## Publishing
|
|
267
|
+
|
|
268
|
+
Maintainers should follow [`RELEASING.md`](RELEASING.md). Publishing is performed by
|
|
269
|
+
GitHub Actions through PyPI Trusted Publishing when a GitHub Release is published.
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT. See [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77.0.3", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ros2inspector"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Static ROS 2 architecture analysis, visualization, and policy checking"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Amine Bensaid", email = "aminebensaid66@gmail.com" }]
|
|
14
|
+
keywords = ["ros2", "robotics", "architecture", "static-analysis", "cli"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
dependencies = [
|
|
28
|
+
"typer>=0.12",
|
|
29
|
+
"rich>=13.7",
|
|
30
|
+
"networkx>=3.3,<3.5",
|
|
31
|
+
"pydantic>=2.7",
|
|
32
|
+
"pyyaml>=6.0",
|
|
33
|
+
"orjson>=3.10",
|
|
34
|
+
"tree-sitter>=0.22",
|
|
35
|
+
"tree-sitter-cpp>=0.22",
|
|
36
|
+
"diskcache>=5.6",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/aminebensaid66/ros2_inspector"
|
|
41
|
+
Documentation = "https://github.com/aminebensaid66/ros2_inspector_website"
|
|
42
|
+
Repository = "https://github.com/aminebensaid66/ros2_inspector"
|
|
43
|
+
Issues = "https://github.com/aminebensaid66/ros2_inspector/issues"
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
dev = [
|
|
47
|
+
"pytest>=8.2",
|
|
48
|
+
"pytest-cov>=5.0",
|
|
49
|
+
"ruff>=0.4",
|
|
50
|
+
"mypy>=1.10",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[project.scripts]
|
|
54
|
+
ros2inspector = "ros2inspector.cli.app:run"
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.packages.find]
|
|
57
|
+
where = ["."]
|
|
58
|
+
include = ["ros2inspector*"]
|
|
59
|
+
|
|
60
|
+
[tool.setuptools.package-data]
|
|
61
|
+
"ros2inspector.viz" = ["_cytoscape.min.js"]
|
|
62
|
+
|
|
63
|
+
[tool.pytest.ini_options]
|
|
64
|
+
testpaths = ["tests"]
|
|
65
|
+
markers = [
|
|
66
|
+
"requires_ros2: marks tests that need a live ROS 2 environment",
|
|
67
|
+
"integration: marks portable full-pipeline integration tests",
|
|
68
|
+
]
|
|
69
|
+
addopts = "--cov=ros2inspector --cov-report=term-missing"
|
|
70
|
+
|
|
71
|
+
[tool.ruff]
|
|
72
|
+
line-length = 100
|
|
73
|
+
target-version = "py310"
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint]
|
|
76
|
+
select = ["E", "F", "I", "UP", "B"]
|
|
77
|
+
|
|
78
|
+
[tool.ruff.lint.per-file-ignores]
|
|
79
|
+
# This file embeds HTML/CSS/JS templates where long lines are unavoidable.
|
|
80
|
+
"ros2inspector/viz/renderer.py" = ["E501"]
|
|
81
|
+
|
|
82
|
+
[tool.mypy]
|
|
83
|
+
python_version = "3.10"
|
|
84
|
+
strict = true
|
|
85
|
+
ignore_missing_imports = true
|
|
86
|
+
|
|
87
|
+
[dependency-groups]
|
|
88
|
+
dev = [
|
|
89
|
+
"mypy>=2.1.0",
|
|
90
|
+
"pytest>=9.1.0",
|
|
91
|
+
"pytest-cov>=7.1.0",
|
|
92
|
+
"ruff>=0.15.17",
|
|
93
|
+
]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""ROS2 Inspector — architectural analysis and governance for ROS 2 workspaces."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
__version__ = version("ros2inspector")
|
|
7
|
+
except PackageNotFoundError: # pragma: no cover - only when run from an uninstalled checkout
|
|
8
|
+
__version__ = "0.0.0+unknown"
|
|
9
|
+
|
|
10
|
+
__all__ = ["__version__"]
|
|
File without changes
|