11# FlutterGuard
22
3- > ** IoT Flutter project static analysis CLI — architecture enforcement, code quality, CI gating.**
3+ > IoT Flutter project static analysis CLI for architecture enforcement, code quality, and CI gating.
44
5- FlutterGuard scans Flutter/Dart source code to detect architecture issues, security vulnerabilities, and anti-patterns specific to IoT device applications. Designed for CI integration and team-wide adoption .
5+ FlutterGuard scans Flutter/Dart source code and reports architecture boundary breaches, lifecycle/resource leaks, dependency cycles, and size-related code quality issues. The active path is ` packages/flutterguard_cli/ ` ; the legacy runtime-tracing packages are archived under ` archive/ ` .
66
7- ## Installation
7+ ## What It Is
88
9- ### Prerequisites
9+ - A CLI for static analysis of Flutter/Dart projects
10+ - A YAML-driven architecture enforcement tool
11+ - An IoT/smart-home aware rule set for Flutter codebases
12+ - A CI gate that can fail builds on severity thresholds or score thresholds
1013
11- - [ Dart SDK ] ( https://dart.dev/get-dart ) >=3.3.0
14+ ## What It Is Not
1215
13- ### Option A: Global activation (cross-platform)
16+ - Not a runtime observability or APM SDK
17+ - Not a crash reporter
18+ - Not a general-purpose Dart linter
19+ - Not a web dashboard or Flutter widget library
20+
21+ ## Requirements
22+
23+ - Dart SDK 3.3.0 or newer
24+ - ` melos ` for workspace bootstrap when running from source
25+
26+ ## Install
27+
28+ ### From source
1429
1530``` bash
16- # Clone the repo
1731git clone https://github.com/lizy-coding/flutterguard.git
1832cd flutterguard
1933
20- # Install monorepo dependencies
2134dart pub global activate melos
2235melos bootstrap
2336
24- # Register flutterguard command globally
2537dart pub global activate --source path packages/flutterguard_cli
26-
27- # Verify installation
2838flutterguard --help
2939```
3040
31- > ** Windows** : After activation, ensure ` %USERPROFILE%\AppData\Local\Pub\Cache\bin ` is in your ` PATH ` . Dart SDK installer usually adds it automatically. To verify: ` where flutterguard ` .
41+ > Windows users may need ` %USERPROFILE%\AppData\Local\Pub\Cache\bin ` on ` PATH ` after global activation .
3242
33- ### Option B: Compile native binary
43+ ### Compile a native binary
3444
3545``` bash
3646git clone https://github.com/lizy-coding/flutterguard.git
3747cd flutterguard
48+ dart pub global activate melos
3849melos bootstrap
50+ dart pub get
3951dart compile exe packages/flutterguard_cli/bin/flutterguard.dart -o flutterguard
4052```
4153
42- ### Option C: Pre-compiled binary (macOS/Linux only)
54+ On Windows, compile with an ` .exe ` output name and run the local binary with
55+ ` .\flutterguard.exe ` :
4356
44- ``` bash
45- curl -sL https://github.com/lizy-coding/flutterguard/releases/download/v0.1.0/flutterguard -o /usr/local/bin/flutterguard
46- chmod +x /usr/local/bin/flutterguard
57+ ``` powershell
58+ dart pub get
59+ dart compile exe packages/flutterguard_cli/bin/flutterguard.dart -o flutterguard.exe
60+ .\flutterguard.exe scan -p D:\path\to\flutter_app
61+ ```
62+
63+ If ` flutterguard scan ` prints ` API key required ` or mentions uploading APKs, the
64+ shell is resolving an old globally installed binary instead of this repository's
65+ static-analysis CLI. Check it with ` where flutterguard ` , then either run
66+ ` .\flutterguard.exe ` from the repo directory or reinstall the local CLI:
67+
68+ ``` powershell
69+ dart pub global deactivate flutterguard_cli
70+ dart pub global activate --source path packages\flutterguard_cli
4771```
4872
4973## Quick Start
5074
5175``` bash
5276# Scan a Flutter project
53- flutterguard scan -p /path/to/your/ project
77+ flutterguard scan -p /path/to/project
5478
55- # JSON output for CI
79+ # Write JSON report and fail on HIGH issues
5680flutterguard scan -p . --format json --fail-on high
5781
58- # See all options
82+ # Show help
5983flutterguard --help
6084```
6185
62- ### Demo
86+ ### Demo target
6387
6488``` bash
65- # From the repo root, scan the demo project
6689flutterguard scan -p examples/scan_demo
6790```
6891
69- ---
92+ ## CLI
93+
94+ Commands:
95+
96+ - ` flutterguard scan `
97+ - ` flutterguard --help `
98+ - ` flutterguard --version `
99+
100+ Scan options:
70101
71- ## Available Rules (6)
102+ | Flag | Meaning | Default |
103+ | ------| ---------| ---------|
104+ | ` -p ` , ` --path ` | Project path to scan | ` . ` |
105+ | ` -c ` , ` --config ` | Config file path inside the project root | ` flutterguard.yaml ` |
106+ | ` -f ` , ` --format ` | Output format: ` table ` or ` json ` | ` table ` |
107+ | ` -o ` , ` --output ` | Output directory for generated reports | ` .flutterguard ` |
108+ | ` -v ` , ` --verbose ` | Show issue detail in terminal output | off |
109+ | ` --fail-on ` | CI gate threshold: ` none ` , ` high ` , ` medium ` , ` low ` | ` none ` |
110+ | ` --min-score ` | Minimum acceptable score, 0-100 | unset |
72111
73- | Rule ID | Level | Domain | What it detects |
74- | ---------| -------| --------| ----------------|
75- | ` large_file ` | LOW | standards | Files exceeding maxLines (default 500) |
76- | ` large_class ` | LOW | standards | Classes exceeding maxLines (default 300) |
77- | ` large_build_method ` | MEDIUM | performance | Widget build() exceeding maxLines (default 80) |
78- | ` lifecycle_resource_not_disposed ` | MEDIUM | performance | StreamSubscription, Timer, AnimationController, MqttClient, BluetoothDevice, StreamController without matching cancel/dispose/close |
79- | ` layer_violation ` | HIGH | architecture | Cross-layer import violations (YAML-configured) |
80- | ` module_violation ` | HIGH | architecture | Cross-module import violations (YAML-configured) |
81- | ` circular_dependency ` | MEDIUM | architecture | File-level import cycles |
82- | ` missing_const_constructor ` | LOW | standards | StatelessWidget/StatefulWidget subclasses missing const constructor |
112+ Exit codes:
83113
84- ---
114+ - ` 0 ` success
115+ - ` 1 ` gate failed
116+ - ` 2 ` scan error or invalid input
85117
86118## Configuration
87119
88- Create a ` flutterguard.yaml ` in your project root:
120+ Create ` flutterguard.yaml ` in the project root:
89121
90122``` yaml
91123include :
@@ -113,7 +145,7 @@ rules:
113145 enabled : true
114146
115147architecture :
116- layers : # Layered architecture enforcement
148+ layers :
117149 - name : presentation
118150 path : lib/presentation/**
119151 allowed_deps : [domain, core]
@@ -127,7 +159,7 @@ architecture:
127159 path : lib/core/**
128160 allowed_deps : []
129161
130- modules : # Business module isolation
162+ modules :
131163 - name : device_mqtt
132164 path : lib/device/mqtt/**
133165 allowed_deps : [domain, core]
@@ -142,76 +174,61 @@ architecture:
142174 enabled : true
143175` ` `
144176
145- ---
177+ Notes:
146178
147- ## Output Formats
179+ - If ` flutterguard.yaml` is missing, defaults are used.
180+ - Architecture rules require explicit `layers` and `modules`; they do not auto-discover boundaries.
181+ - ` layer_violation` and `module_violation` only work when the relevant declarations are present.
148182
149- ### Table (default)
183+ # # Checks
150184
151- ` ` `
152- FlutterGuard Report ─ scan_demo
153- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
154- 总评分 : 98/100 优秀 文件总数: 2 问题总数: 2
155- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
156-
157- 代码规范 2 items ▰ LOW
158- ────────────────────────────────────────────────────────────────
159- LOW P2 可选
160- 类过大
161- lib/services/user_service.dart:3
162- 类 "UserService" 49 行(阈值 : 30 行)
163- 修复 : 建议将 "UserService" 的职责提取到更小的类中
164- ` ` `
185+ FlutterGuard currently emits these issue IDs :
165186
166- ### JSON
187+ | Rule ID | Level | Domain | Priority | What it checks |
188+ |---------|-------|--------|----------|----------------|
189+ | `large_file` | LOW | standards | P2 | File line count over `maxLines` |
190+ | `large_class` | LOW | standards | P2 | Class body line count over `maxLines` |
191+ | `large_build_method` | MEDIUM | performance | P1 | `build()` method line count over `maxLines` |
192+ | `lifecycle_resource_not_disposed` | MEDIUM | performance | P1 | Undisposed `StreamSubscription`, `Timer`, `AnimationController`, `TextEditingController`, `ScrollController`, `FocusNode`, `MqttClient`, `BluetoothDevice`, `StreamController` |
193+ | `layer_violation` | HIGH | architecture | P0 | Importing across forbidden architecture layers |
194+ | `module_violation` | HIGH | architecture | P0 | Importing across forbidden business modules |
195+ | `circular_dependency` | MEDIUM | architecture | P1 | File-level import cycles |
196+ | `missing_const_constructor` | LOW | standards | P2 | Widget classes missing a `const` constructor |
167197
168- ` ` ` bash
169- flutterguard scan -p . --format json
170- ```
198+ # # Output
199+
200+ # ## Terminal table
201+
202+ Default output is a colored terminal report grouped by domain. It shows the overall score, file count, issue count, and per-issue detail.
171203
172- Output written to ` .flutterguard/report.json ` :
204+ # ## JSON report
205+
206+ ` --format json` writes `.flutterguard/report.json` under the output directory. The terminal summary is still printed to stdout.
207+
208+ Example shape :
173209
174210` ` ` json
175211{
176212 "version": "1.0.0",
213+ "generatedAt": "2026-05-20T00:00:00.000Z",
214+ "projectPath": "/absolute/path",
177215 "score": 85,
178216 "summary": {
179217 "total": 3,
180218 "high": 1,
181219 "medium": 1,
182220 "low": 1,
183221 "byDomain": {
184- "architecture" : { "high" : 1 , "medium" : 0 , "low" : 0 , "total" : 1 },
185- "performance" : { "high" : 0 , "medium" : 1 , "low" : 0 , "total" : 1 },
186- "standards" : { "high" : 0 , "medium" : 0 , "low" : 1 , "total" : 1 }
222+ "architecture": { "high": 1, "medium": 0, "low": 0, "total": 1 }
187223 }
188224 },
189- "issues" : [... ]
225+ "issues": []
190226}
191227` ` `
192228
193- ---
194-
195- ## CI Integration
196-
197- ``` bash
198- # Fail the build if any HIGH issues exist
199- flutterguard scan -p . --format json --fail-on high
200-
201- # Enforce a minimum score of 80
202- flutterguard scan -p . --format json --min-score 80
203-
204- # Accept only clean scans (no issues at any level)
205- flutterguard scan -p . --fail-on low
206- ```
207-
208- ** Exit codes** : ` 0 ` = pass, ` 1 ` = gate failed, ` 2 ` = error
209-
210- ---
211-
212229# # Scoring
213230
214- ```
231+ ` ` ` text
215232score = max(0, 100 - high*10 - medium*4 - low*1)
216233` ` `
217234
@@ -221,28 +238,39 @@ score = max(0, 100 - high*10 - medium*4 - low*1)
221238| 50-79 | 需关注 (Needs review) |
222239| 0-49 | 需整改 (Needs action) |
223240
224- ---
241+ # # CI Integration
242+
243+ ` ` ` bash
244+ flutterguard scan -p . --format json --fail-on high
245+ flutterguard scan -p . --format json --min-score 80
246+ flutterguard scan -p . --fail-on low
247+ ` ` `
248+
249+ # # Repository Layout
250+
251+ ` ` ` text
252+ flutterguard/
253+ ├── packages/
254+ │ └── flutterguard_cli/ Active CLI implementation
255+ ├── archive/ Frozen legacy runtime-tracing packages
256+ └── examples/
257+ └── scan_demo/ Demo scan target
258+ ` ` `
225259
226260# # Development
227261
228262` ` ` bash
229- # Bootstrap monorepo
230263git clone https://github.com/lizy-coding/flutterguard.git
231264cd flutterguard
265+ dart pub global activate melos
232266melos bootstrap
267+ dart pub get
233268
234- # Analyze
235269dart run melos run analyze
236-
237- # Test (12 tests)
238270dart run melos run test:cli
239-
240- # Compile CLI
241271dart compile exe packages/flutterguard_cli/bin/flutterguard.dart -o flutterguard
242272` ` `
243273
244- ---
245-
246274# # License
247275
248276MIT
0 commit comments