smashuml 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.
- smashuml-0.1.0/.gitignore +16 -0
- smashuml-0.1.0/LICENSE +21 -0
- smashuml-0.1.0/PKG-INFO +196 -0
- smashuml-0.1.0/README.md +170 -0
- smashuml-0.1.0/pyproject.toml +57 -0
- smashuml-0.1.0/src/smashuml/__init__.py +3 -0
- smashuml-0.1.0/src/smashuml/__main__.py +3 -0
- smashuml-0.1.0/src/smashuml/analysis.py +244 -0
- smashuml-0.1.0/src/smashuml/cli.py +163 -0
- smashuml-0.1.0/src/smashuml/config.py +75 -0
- smashuml-0.1.0/src/smashuml/export.py +68 -0
- smashuml-0.1.0/src/smashuml/languages/__init__.py +13 -0
- smashuml-0.1.0/src/smashuml/languages/base.py +57 -0
- smashuml-0.1.0/src/smashuml/languages/csharp.py +795 -0
- smashuml-0.1.0/src/smashuml/languages/react.py +383 -0
- smashuml-0.1.0/src/smashuml/languages/typescript.py +940 -0
- smashuml-0.1.0/src/smashuml/layout.py +676 -0
- smashuml-0.1.0/src/smashuml/model.py +244 -0
- smashuml-0.1.0/src/smashuml/pipeline.py +107 -0
- smashuml-0.1.0/src/smashuml/projects.py +51 -0
- smashuml-0.1.0/src/smashuml/render/__init__.py +1 -0
- smashuml-0.1.0/src/smashuml/render/drawio.py +652 -0
- smashuml-0.1.0/src/smashuml/render/json_out.py +127 -0
- smashuml-0.1.0/src/smashuml/render/text.py +185 -0
- smashuml-0.1.0/src/smashuml/scanner.py +117 -0
- smashuml-0.1.0/src/smashuml/textsize.py +31 -0
- smashuml-0.1.0/src/smashuml/views.py +519 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
.venv/
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
# generated diagrams (golden files under tests/ are tracked)
|
|
9
|
+
/*.drawio
|
|
10
|
+
/*.pdf
|
|
11
|
+
/*.png
|
|
12
|
+
/out/
|
|
13
|
+
|
|
14
|
+
# .NET build output of ExampleCodebase (IDE restores create it)
|
|
15
|
+
bin/
|
|
16
|
+
obj/
|
smashuml-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Ocheri
|
|
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.
|
smashuml-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: smashuml
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic UML class diagrams (draw.io) generated from source code
|
|
5
|
+
Author: Adam Ocheri
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: class-diagram,csharp,diagram,documentation,drawio,react,typescript,uml
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: pathspec>=0.12
|
|
22
|
+
Requires-Dist: tree-sitter-c-sharp>=0.23
|
|
23
|
+
Requires-Dist: tree-sitter-typescript>=0.23.2
|
|
24
|
+
Requires-Dist: tree-sitter>=0.23
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# SmashUML
|
|
28
|
+
|
|
29
|
+
**Generate complete UML class diagrams from your source code, as a draw.io document.**
|
|
30
|
+
|
|
31
|
+
SmashUML scans a folder, parses every source file and writes one multi-page [draw.io](https://www.drawio.com/) document that documents the whole codebase: packages, classes, interfaces, enums, their members and the relationships between them. Open it in the draw.io desktop app or at [app.diagrams.net](https://app.diagrams.net), or export it to PDF.
|
|
32
|
+
|
|
33
|
+
- **Complete** – every type and member is drawn, nothing is shortened; each run tells you so.
|
|
34
|
+
- **Deterministic** – no AI involved: the same code always produces a byte-identical file, so documents can be committed and diffed.
|
|
35
|
+
- **Laid out for you** – boxes are arranged and lines routed automatically; no manual dragging needed.
|
|
36
|
+
- **Code-oriented** – C# and TypeScript (including React) are documented in their own terms: attributes, decorators, dependency injection, components, hooks, routes and HTTP endpoints.
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
SmashUML needs Python 3.11 or newer. Install it as a command-line tool:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
uv tool install smashuml
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
or with pipx:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
pipx install smashuml
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
or into the current environment:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
pip install smashuml
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Check the installation:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
smashuml --version
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
PDF export additionally needs the free [draw.io desktop app](https://github.com/jgraph/drawio-desktop/releases); `.drawio` and JSON output work without it.
|
|
65
|
+
|
|
66
|
+
## Quick start
|
|
67
|
+
|
|
68
|
+
From the root of your project:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
smashuml generate
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This scans the current folder and all its sub-folders and writes `<folder name>.drawio` into the current folder. The summary tells you what was found and whether everything was drawn:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
Scanned 126 files (csharp), 224 types, 1385 members, 458 relationships -> MyApi.drawio, 30 pages
|
|
78
|
+
Complete: every type and member is drawn.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Usage
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
smashuml generate [path] [options]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`path` is the folder to scan (default: the current folder). Every option is optional.
|
|
88
|
+
|
|
89
|
+
### Choosing what to scan and where to write
|
|
90
|
+
|
|
91
|
+
| Command | Effect |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `smashuml generate` | Documents the current folder into `./<folder name>.drawio`. |
|
|
94
|
+
| `smashuml generate src/MyApp` | Documents another folder; the file is named after it (`./MyApp.drawio`). |
|
|
95
|
+
| `smashuml generate -o docs/architecture.drawio` | Writes to a file of your choice (folders are created). |
|
|
96
|
+
| `smashuml generate -o model.json` | Writes the parsed model as JSON instead of a diagram (the format follows the extension). |
|
|
97
|
+
| `smashuml generate -o architecture.pdf` | Writes a PDF with one page per diagram page (needs the draw.io desktop app). |
|
|
98
|
+
| `smashuml generate -f json -o model.txt` | Chooses the format explicitly: `drawio`, `json` or `pdf`. |
|
|
99
|
+
| `smashuml generate --include "src/**" --include "lib/**"` | Scans only matching files (gitignore-style patterns, repeatable). |
|
|
100
|
+
| `smashuml generate --exclude "**/Legacy/**"` | Skips matching files (repeatable). |
|
|
101
|
+
| `smashuml generate --no-gitignore` | Also scans files that `.gitignore` excludes. |
|
|
102
|
+
| `smashuml generate --no-default-excludes` | Also scans generated code and tests that are skipped by default (`*.Designer.cs`, `*.g.cs`, `Migrations/`, `*.test.ts`, `*.spec.ts`, `__tests__/`, `setupTests.ts`). |
|
|
103
|
+
| `smashuml generate -q` | Prints errors only. |
|
|
104
|
+
|
|
105
|
+
Build output and tool folders (`bin`, `obj`, `node_modules`, `dist`, hidden folders, ...) are never scanned.
|
|
106
|
+
|
|
107
|
+
### Repositories with several projects
|
|
108
|
+
|
|
109
|
+
A folder that *is* a project – it has a project file at its root (`*.csproj`, `package.json`, `tsconfig.json`, `pyproject.toml`, `go.mod`, ...) or source files directly in it – gives one document. A folder that only *holds* projects gives one document per top-level sub-folder:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
my-app/
|
|
113
|
+
├── Backend/ (ASP.NET, has Backend.csproj)
|
|
114
|
+
└── Frontend/ (React, has package.json)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
| Command | Effect |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `smashuml generate my-app` | Writes `Backend.drawio` and `Frontend.drawio`. |
|
|
120
|
+
| `smashuml generate my-app -o docs/uml` | Writes `docs/uml/Backend.drawio` and `docs/uml/Frontend.drawio` (`-o` is a folder here). |
|
|
121
|
+
| `smashuml generate my-app --single` | Writes one `my-app.drawio` covering both projects. |
|
|
122
|
+
| `smashuml generate my-app/Backend` | Writes `Backend.drawio` only. |
|
|
123
|
+
|
|
124
|
+
`.gitignore` files of the outer folder still apply to each project.
|
|
125
|
+
|
|
126
|
+
### Choosing what to draw
|
|
127
|
+
|
|
128
|
+
| Command | Effect |
|
|
129
|
+
|---|---|
|
|
130
|
+
| `smashuml generate --visibility public` | Draws only public members (`public`, `protected`, `package` or `all`; default `all`). |
|
|
131
|
+
| `smashuml generate --no-members` | Draws class names only, without attributes and operations. |
|
|
132
|
+
| `smashuml generate --max-members 20` | Caps each class box section at 20 rows, followed by `… N more` (default: no limit). |
|
|
133
|
+
| `smashuml generate --no-external` | Hides base types that are not part of the scanned code (e.g. `ControllerBase`). |
|
|
134
|
+
| `smashuml generate --pages overview,index,namespaces` | Emits only the listed pages (see below). |
|
|
135
|
+
| `smashuml generate --title "Billing service"` | Sets the document title (default: the folder name). |
|
|
136
|
+
|
|
137
|
+
Whenever an option leaves something out, the summary says so, e.g. `Not drawn because of options: 121 members below --visibility public`.
|
|
138
|
+
|
|
139
|
+
### Configuration file
|
|
140
|
+
|
|
141
|
+
The same settings can be kept in a `smashuml.toml` at the root of the scanned folder. Command-line options override it; `output` is relative to the file.
|
|
142
|
+
|
|
143
|
+
```toml
|
|
144
|
+
[smashuml]
|
|
145
|
+
output = "docs/architecture.drawio"
|
|
146
|
+
visibility = "public"
|
|
147
|
+
exclude = ["**/Tests/**"]
|
|
148
|
+
pages = ["overview", "index", "namespaces"]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## What the document contains
|
|
152
|
+
|
|
153
|
+
Each document has several pages (tabs):
|
|
154
|
+
|
|
155
|
+
| Page (`--pages` name) | Shows |
|
|
156
|
+
|---|---|
|
|
157
|
+
| **Overview** (`overview`) | The top-level packages with their sub-packages nested inside, and the dependencies between them. Thicker arrows mean more references; hover an arrow for the details. Click a package to open its page. |
|
|
158
|
+
| **Namespace dependencies** (`namespace-dependencies`) | Every namespace and every dependency between two namespaces, ungrouped. |
|
|
159
|
+
| **Index** (`index`) | Every scanned file, folder by folder, with the types it declares and a link to the page that documents them. |
|
|
160
|
+
| **Type hierarchy** (`hierarchy`) | All inheritance and interface-implementation trees. |
|
|
161
|
+
| **Dependencies** (`dependencies`) | Constructor-injected dependencies (controllers → services → data access), with dependency-injection lifetimes such as «scoped». |
|
|
162
|
+
| **Component tree** (`components`) | React: which component renders which, from the routes down, labelled with the route paths. |
|
|
163
|
+
| **Class diagrams** (`namespaces`) | One page per namespace (C#) or per top-level folder (TypeScript) with full UML class boxes. |
|
|
164
|
+
|
|
165
|
+
Pages without content (e.g. *Component tree* in a C# project) are left out.
|
|
166
|
+
|
|
167
|
+
Class boxes show:
|
|
168
|
+
|
|
169
|
+
- attributes and operations with visibility (`+` public, `-` private, `#` protected, `~` package); static members underlined, abstract ones in italics
|
|
170
|
+
- types, parameters (with `ref`, `out`, `params`, optional markers and default values), return types, initial values and enum values
|
|
171
|
+
- attributes and decorators in grey, e.g. `[Route("api/courses")]`, `[HttpGet("{id}")]`, `@Injectable()`
|
|
172
|
+
- modifiers as property strings (`{readOnly}`, `{override}`, `{async}`), accessors such as `{get; private set}` and generic constraints
|
|
173
|
+
- associations with role names and multiplicities (`1`, `0..1`, `*`), inheritance, interface implementation, nesting and dependencies
|
|
174
|
+
|
|
175
|
+
C# top-level statements (`Program.cs`) become a «program» box listing the dependency-injection registrations (`AddScoped<IFoo, Foo>()`, ...) and the request pipeline (`app.UseRouting()`, ...).
|
|
176
|
+
|
|
177
|
+
React code is shown as «component», «hook» and «context» boxes with props, state, refs and the hooks used; `renders` arrows follow the JSX, routes come from `<Route>` elements and route tables, and each function lists the HTTP endpoints it calls, e.g. `getAllCourses(): Promise<Course[]> {GET /api/courses}`.
|
|
178
|
+
|
|
179
|
+
Hover over a box to see the file and line it was declared in.
|
|
180
|
+
|
|
181
|
+
## Supported languages
|
|
182
|
+
|
|
183
|
+
| Language | Files | Packages are |
|
|
184
|
+
|---|---|---|
|
|
185
|
+
| C# | `.cs` | namespaces |
|
|
186
|
+
| TypeScript, including React (TSX) | `.ts`, `.tsx`, `.mts`, `.cts` | folders |
|
|
187
|
+
|
|
188
|
+
A folder may mix both languages. Parsing is done with [tree-sitter](https://tree-sitter.github.io/): no compiler or SDK of the scanned language is needed. TypeScript imports are followed through relative paths, `tsconfig.json` `baseUrl` / `paths` and `index.ts` re-exports.
|
|
189
|
+
|
|
190
|
+
## PDF export
|
|
191
|
+
|
|
192
|
+
`-o file.pdf` uses the draw.io desktop app's command line. SmashUML finds it in its default install location or on `PATH`; otherwise set the `SMASHUML_DRAWIO` environment variable to the executable.
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
MIT
|
smashuml-0.1.0/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# SmashUML
|
|
2
|
+
|
|
3
|
+
**Generate complete UML class diagrams from your source code, as a draw.io document.**
|
|
4
|
+
|
|
5
|
+
SmashUML scans a folder, parses every source file and writes one multi-page [draw.io](https://www.drawio.com/) document that documents the whole codebase: packages, classes, interfaces, enums, their members and the relationships between them. Open it in the draw.io desktop app or at [app.diagrams.net](https://app.diagrams.net), or export it to PDF.
|
|
6
|
+
|
|
7
|
+
- **Complete** – every type and member is drawn, nothing is shortened; each run tells you so.
|
|
8
|
+
- **Deterministic** – no AI involved: the same code always produces a byte-identical file, so documents can be committed and diffed.
|
|
9
|
+
- **Laid out for you** – boxes are arranged and lines routed automatically; no manual dragging needed.
|
|
10
|
+
- **Code-oriented** – C# and TypeScript (including React) are documented in their own terms: attributes, decorators, dependency injection, components, hooks, routes and HTTP endpoints.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
SmashUML needs Python 3.11 or newer. Install it as a command-line tool:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
uv tool install smashuml
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
or with pipx:
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
pipx install smashuml
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
or into the current environment:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pip install smashuml
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Check the installation:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
smashuml --version
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
PDF export additionally needs the free [draw.io desktop app](https://github.com/jgraph/drawio-desktop/releases); `.drawio` and JSON output work without it.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
From the root of your project:
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
smashuml generate
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This scans the current folder and all its sub-folders and writes `<folder name>.drawio` into the current folder. The summary tells you what was found and whether everything was drawn:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
Scanned 126 files (csharp), 224 types, 1385 members, 458 relationships -> MyApi.drawio, 30 pages
|
|
52
|
+
Complete: every type and member is drawn.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
smashuml generate [path] [options]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`path` is the folder to scan (default: the current folder). Every option is optional.
|
|
62
|
+
|
|
63
|
+
### Choosing what to scan and where to write
|
|
64
|
+
|
|
65
|
+
| Command | Effect |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `smashuml generate` | Documents the current folder into `./<folder name>.drawio`. |
|
|
68
|
+
| `smashuml generate src/MyApp` | Documents another folder; the file is named after it (`./MyApp.drawio`). |
|
|
69
|
+
| `smashuml generate -o docs/architecture.drawio` | Writes to a file of your choice (folders are created). |
|
|
70
|
+
| `smashuml generate -o model.json` | Writes the parsed model as JSON instead of a diagram (the format follows the extension). |
|
|
71
|
+
| `smashuml generate -o architecture.pdf` | Writes a PDF with one page per diagram page (needs the draw.io desktop app). |
|
|
72
|
+
| `smashuml generate -f json -o model.txt` | Chooses the format explicitly: `drawio`, `json` or `pdf`. |
|
|
73
|
+
| `smashuml generate --include "src/**" --include "lib/**"` | Scans only matching files (gitignore-style patterns, repeatable). |
|
|
74
|
+
| `smashuml generate --exclude "**/Legacy/**"` | Skips matching files (repeatable). |
|
|
75
|
+
| `smashuml generate --no-gitignore` | Also scans files that `.gitignore` excludes. |
|
|
76
|
+
| `smashuml generate --no-default-excludes` | Also scans generated code and tests that are skipped by default (`*.Designer.cs`, `*.g.cs`, `Migrations/`, `*.test.ts`, `*.spec.ts`, `__tests__/`, `setupTests.ts`). |
|
|
77
|
+
| `smashuml generate -q` | Prints errors only. |
|
|
78
|
+
|
|
79
|
+
Build output and tool folders (`bin`, `obj`, `node_modules`, `dist`, hidden folders, ...) are never scanned.
|
|
80
|
+
|
|
81
|
+
### Repositories with several projects
|
|
82
|
+
|
|
83
|
+
A folder that *is* a project – it has a project file at its root (`*.csproj`, `package.json`, `tsconfig.json`, `pyproject.toml`, `go.mod`, ...) or source files directly in it – gives one document. A folder that only *holds* projects gives one document per top-level sub-folder:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
my-app/
|
|
87
|
+
├── Backend/ (ASP.NET, has Backend.csproj)
|
|
88
|
+
└── Frontend/ (React, has package.json)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
| Command | Effect |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `smashuml generate my-app` | Writes `Backend.drawio` and `Frontend.drawio`. |
|
|
94
|
+
| `smashuml generate my-app -o docs/uml` | Writes `docs/uml/Backend.drawio` and `docs/uml/Frontend.drawio` (`-o` is a folder here). |
|
|
95
|
+
| `smashuml generate my-app --single` | Writes one `my-app.drawio` covering both projects. |
|
|
96
|
+
| `smashuml generate my-app/Backend` | Writes `Backend.drawio` only. |
|
|
97
|
+
|
|
98
|
+
`.gitignore` files of the outer folder still apply to each project.
|
|
99
|
+
|
|
100
|
+
### Choosing what to draw
|
|
101
|
+
|
|
102
|
+
| Command | Effect |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `smashuml generate --visibility public` | Draws only public members (`public`, `protected`, `package` or `all`; default `all`). |
|
|
105
|
+
| `smashuml generate --no-members` | Draws class names only, without attributes and operations. |
|
|
106
|
+
| `smashuml generate --max-members 20` | Caps each class box section at 20 rows, followed by `… N more` (default: no limit). |
|
|
107
|
+
| `smashuml generate --no-external` | Hides base types that are not part of the scanned code (e.g. `ControllerBase`). |
|
|
108
|
+
| `smashuml generate --pages overview,index,namespaces` | Emits only the listed pages (see below). |
|
|
109
|
+
| `smashuml generate --title "Billing service"` | Sets the document title (default: the folder name). |
|
|
110
|
+
|
|
111
|
+
Whenever an option leaves something out, the summary says so, e.g. `Not drawn because of options: 121 members below --visibility public`.
|
|
112
|
+
|
|
113
|
+
### Configuration file
|
|
114
|
+
|
|
115
|
+
The same settings can be kept in a `smashuml.toml` at the root of the scanned folder. Command-line options override it; `output` is relative to the file.
|
|
116
|
+
|
|
117
|
+
```toml
|
|
118
|
+
[smashuml]
|
|
119
|
+
output = "docs/architecture.drawio"
|
|
120
|
+
visibility = "public"
|
|
121
|
+
exclude = ["**/Tests/**"]
|
|
122
|
+
pages = ["overview", "index", "namespaces"]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## What the document contains
|
|
126
|
+
|
|
127
|
+
Each document has several pages (tabs):
|
|
128
|
+
|
|
129
|
+
| Page (`--pages` name) | Shows |
|
|
130
|
+
|---|---|
|
|
131
|
+
| **Overview** (`overview`) | The top-level packages with their sub-packages nested inside, and the dependencies between them. Thicker arrows mean more references; hover an arrow for the details. Click a package to open its page. |
|
|
132
|
+
| **Namespace dependencies** (`namespace-dependencies`) | Every namespace and every dependency between two namespaces, ungrouped. |
|
|
133
|
+
| **Index** (`index`) | Every scanned file, folder by folder, with the types it declares and a link to the page that documents them. |
|
|
134
|
+
| **Type hierarchy** (`hierarchy`) | All inheritance and interface-implementation trees. |
|
|
135
|
+
| **Dependencies** (`dependencies`) | Constructor-injected dependencies (controllers → services → data access), with dependency-injection lifetimes such as «scoped». |
|
|
136
|
+
| **Component tree** (`components`) | React: which component renders which, from the routes down, labelled with the route paths. |
|
|
137
|
+
| **Class diagrams** (`namespaces`) | One page per namespace (C#) or per top-level folder (TypeScript) with full UML class boxes. |
|
|
138
|
+
|
|
139
|
+
Pages without content (e.g. *Component tree* in a C# project) are left out.
|
|
140
|
+
|
|
141
|
+
Class boxes show:
|
|
142
|
+
|
|
143
|
+
- attributes and operations with visibility (`+` public, `-` private, `#` protected, `~` package); static members underlined, abstract ones in italics
|
|
144
|
+
- types, parameters (with `ref`, `out`, `params`, optional markers and default values), return types, initial values and enum values
|
|
145
|
+
- attributes and decorators in grey, e.g. `[Route("api/courses")]`, `[HttpGet("{id}")]`, `@Injectable()`
|
|
146
|
+
- modifiers as property strings (`{readOnly}`, `{override}`, `{async}`), accessors such as `{get; private set}` and generic constraints
|
|
147
|
+
- associations with role names and multiplicities (`1`, `0..1`, `*`), inheritance, interface implementation, nesting and dependencies
|
|
148
|
+
|
|
149
|
+
C# top-level statements (`Program.cs`) become a «program» box listing the dependency-injection registrations (`AddScoped<IFoo, Foo>()`, ...) and the request pipeline (`app.UseRouting()`, ...).
|
|
150
|
+
|
|
151
|
+
React code is shown as «component», «hook» and «context» boxes with props, state, refs and the hooks used; `renders` arrows follow the JSX, routes come from `<Route>` elements and route tables, and each function lists the HTTP endpoints it calls, e.g. `getAllCourses(): Promise<Course[]> {GET /api/courses}`.
|
|
152
|
+
|
|
153
|
+
Hover over a box to see the file and line it was declared in.
|
|
154
|
+
|
|
155
|
+
## Supported languages
|
|
156
|
+
|
|
157
|
+
| Language | Files | Packages are |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| C# | `.cs` | namespaces |
|
|
160
|
+
| TypeScript, including React (TSX) | `.ts`, `.tsx`, `.mts`, `.cts` | folders |
|
|
161
|
+
|
|
162
|
+
A folder may mix both languages. Parsing is done with [tree-sitter](https://tree-sitter.github.io/): no compiler or SDK of the scanned language is needed. TypeScript imports are followed through relative paths, `tsconfig.json` `baseUrl` / `paths` and `index.ts` re-exports.
|
|
163
|
+
|
|
164
|
+
## PDF export
|
|
165
|
+
|
|
166
|
+
`-o file.pdf` uses the draw.io desktop app's command line. SmashUML finds it in its default install location or on `PATH`; otherwise set the `SMASHUML_DRAWIO` environment variable to the executable.
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "smashuml"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Deterministic UML class diagrams (draw.io) generated from source code"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Adam Ocheri" }]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
keywords = ["uml", "drawio", "diagram", "class-diagram", "documentation", "csharp", "typescript", "react"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Topic :: Software Development :: Documentation",
|
|
23
|
+
]
|
|
24
|
+
dependencies = [
|
|
25
|
+
"tree-sitter>=0.23",
|
|
26
|
+
"tree-sitter-c-sharp>=0.23",
|
|
27
|
+
"pathspec>=0.12",
|
|
28
|
+
"tree-sitter-typescript>=0.23.2",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
smashuml = "smashuml.cli:main"
|
|
33
|
+
|
|
34
|
+
[dependency-groups]
|
|
35
|
+
dev = ["pytest>=8"]
|
|
36
|
+
|
|
37
|
+
[build-system]
|
|
38
|
+
requires = ["hatchling"]
|
|
39
|
+
build-backend = "hatchling.build"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.wheel]
|
|
42
|
+
packages = ["src/smashuml"]
|
|
43
|
+
|
|
44
|
+
# The published source archive holds the package only (pyproject.toml, the
|
|
45
|
+
# README and license files are always added): no ExampleCodebase, tests or tooling.
|
|
46
|
+
[tool.hatch.build.targets.sdist]
|
|
47
|
+
only-include = ["src/smashuml"]
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
testpaths = ["tests"]
|
|
51
|
+
|
|
52
|
+
[tool.ruff]
|
|
53
|
+
line-length = 120
|
|
54
|
+
src = ["src", "tests"]
|
|
55
|
+
|
|
56
|
+
[tool.ruff.lint]
|
|
57
|
+
select = ["E", "F", "W", "I"]
|