@codacy/tools-dartanalyzer-3 0.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Codacy
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.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ # @codacy/tools-dartanalyzer-3
2
+
3
+ ## Table of Contents
4
+
5
+ - [Overview](#overview)
6
+ - [Updating patterns](#updating-patterns)
7
+ - [Updating the pattern-type table](#updating-the-pattern-type-table)
8
+ - [Updating the Dart SDK version](#updating-the-dart-sdk-version)
9
+ - [Development](#development)
10
+ - [Notes for maintainers](#notes-for-maintainers)
11
+ - [The repository-root config swap](#the-repository-root-config-swap)
12
+ - [Why the generated config looks half-empty](#why-the-generated-config-looks-half-empty)
13
+ - [`--format json`, not `--format machine`](#--format-json-not---format-machine)
14
+ - [Unresolved dependencies](#unresolved-dependencies)
15
+ - [Part files](#part-files)
16
+ - [Known limitations](#known-limitations)
17
+
18
+ ---
19
+
20
+ ## Overview
21
+
22
+ `dart analyze` is the Dart SDK's built-in static analyzer — the same engine behind the Dart IDE
23
+ plugins. It reports two kinds of finding, and this adapter handles both:
24
+
25
+ - **Lint rules** (215 Codacy patterns) — style and best-practice checks. Opt-in: they only run when
26
+ an `analysis_options.yaml` enables them.
27
+ - **Analyzer diagnostics** (962 Codacy patterns) — compile-time errors, type errors, dead code.
28
+ Always on, no configuration needed.
29
+
30
+ | Property | Value |
31
+ | -------------- | ----------------------------------------------- |
32
+ | Tool ID | `dartanalyzer` |
33
+ | Codacy UUID | `d203d615-6cf1-41f9-be5f-e2f660f7850f` |
34
+ | Strategy | CLI (`spawnTool`) |
35
+ | Languages | Dart |
36
+ | File patterns | `**/*.dart` |
37
+ | Runtime | Dart SDK 3.x (~210 MB, auto-installed) |
38
+ | Upstream docs | <https://dart.dev/tools/dart-analyze> |
39
+ | Codacy wrapper | <https://github.com/codacy/codacy-dartanalyzer> |
40
+
41
+ ## Updating patterns
42
+
43
+ ```bash
44
+ # Re-fetch pattern metadata from the Codacy API
45
+ pnpm prefetch
46
+
47
+ # The pattern-type table is derived from patterns.json — always refresh it too
48
+ pnpm fetch-rule-types
49
+
50
+ # Commit both
51
+ git add src/patterns.json src/pattern-types.json
52
+ ```
53
+
54
+ ## Updating the pattern-type table
55
+
56
+ `src/pattern-types.json` maps each bare rule name to `lint`, `diagnostic` or `unknown`. The adapter
57
+ needs it because `analysis_options.yaml` has two separate sections and a rule written to the wrong
58
+ one silently does nothing.
59
+
60
+ `pnpm fetch-rule-types` derives it from the Dart SDK's own machine-readable lint catalog
61
+ (`pkg/linter/tool/machine/rules.json`, overridable with `DART_LINT_RULES_URL`): a name the catalog
62
+ lists is a lint, anything else in Codacy's catalog is a diagnostic. It prints the resulting counts
63
+ plus two gaps worth watching:
64
+
65
+ - **Removed lints** (`unknown`) — still in Codacy's catalog, gone from the SDK. Written to neither
66
+ config section, since the analyzer recognises them in neither. The explicit list lives in
67
+ `isRemovedLint()` in `scripts/fetch-rule-types.mjs`; prune entries Codacy drops.
68
+ - **SDK lints with no Codacy pattern** — currently 47. They can never be enabled from a Codacy
69
+ config, and there is nothing this package can do about it until Codacy's catalog catches up.
70
+
71
+ The Codacy wrapper ships an equivalent table as a hand-written `docs/patterns_type.json`. This one is
72
+ derived instead because that snapshot is already 44 lint rules behind the SDK; the two agree exactly
73
+ on the 1180 patterns they share (215 + 3 removed lints = the wrapper's 218; 962 diagnostics).
74
+
75
+ ## Updating the Dart SDK version
76
+
77
+ 1. Check what Codacy runs: `.tool_version` in `codacy/codacy-dartanalyzer`, or the `version` field
78
+ from `https://app.codacy.com/api/v3/tools`. Track that, not the newest stable release.
79
+ 2. Update `preferredVersion` in `src/metadata.ts`. The download URL is derived from it, so nothing
80
+ else changes.
81
+ 3. Run `pnpm prefetch` and `pnpm fetch-rule-types` to pick up new and removed rules.
82
+ 4. Run `pnpm test`.
83
+ 5. A new Dart **major** version means a new adapter package (`dartanalyzer-4/`).
84
+
85
+ ## Development
86
+
87
+ ```bash
88
+ pnpm build # Build with tsup
89
+ pnpm test # Run tests (SDK-dependent tests skip when no dart is installed)
90
+ ```
91
+
92
+ Installing a Dart SDK locally, so the integration tests run instead of skipping:
93
+
94
+ ```bash
95
+ brew install dart # macOS
96
+ # or install Flutter, which bundles Dart
97
+ # or https://dart.dev/get-dart
98
+ ```
99
+
100
+ `codacy-analysis analyze . --install-dependencies` also works: it downloads the pinned portable SDK
101
+ into `~/.codacy/tools/dartanalyzer/dart-sdk/`.
102
+
103
+ ## Notes for maintainers
104
+
105
+ ### The repository-root config swap
106
+
107
+ **This is the one adapter that writes outside `.codacy/`**, and it is not a shortcut — `dart analyze`
108
+ gives no alternative.
109
+
110
+ Every other tool here takes a `--config <path>`. `dart analyze` has no equivalent: dartdev exposes
111
+ only `--format`, `--packages`, `--cache`, `--sdk-path` and the `--fatal-*` flags. The analyzer finds
112
+ `analysis_options.yaml` by walking **up** the directory tree from the analyzed file
113
+ (`ContextLocator` in `pkg/analyzer`), so a config in `.codacy/generated/` is never seen. The Codacy
114
+ Docker wrapper solves this by writing `/analysis_options.yaml` and mounting the repository at
115
+ `/src` — a parent directory it owns. Locally there is no such directory.
116
+
117
+ So `analyze()` does this, in order:
118
+
119
+ 1. **Recover** — if the root config carries the `codacy-cli-generated-analysis-options` marker, a
120
+ previous run was killed mid-swap: restore `.codacy/generated/dartanalyzer/analysis_options.yaml.orig` if
121
+ present, otherwise delete the file.
122
+ 2. **Write** the generated config to `.codacy/generated/dartanalyzer/analysis_options.yaml` (kept there for
123
+ inspection), back up any existing root config to `…/analysis_options.yaml.orig`, and copy the
124
+ generated file to the repository root.
125
+ 3. **Run** every `dart analyze` chunk under that one config.
126
+ 4. **Restore** in a `finally`: put the backup back, or delete the generated file — and only ever
127
+ delete a file carrying the marker, so a config the user created mid-run survives.
128
+
129
+ The marker is what makes every step safe to repeat. Two paths skip the swap entirely: when the
130
+ project's own config is in use (`useLocalConfigurationFile`), and when the swap fails (read-only
131
+ checkout, permissions) — that is a warning, not a failure, because analyzer diagnostics still work
132
+ without it and only the opt-in lint rules are lost.
133
+
134
+ Results are filtered post-hoc by enabled pattern ID regardless of which path ran, which is what makes
135
+ the local-config path correct too.
136
+
137
+ ### Why the generated config looks half-empty
138
+
139
+ It writes enabled **lints** and ignored **diagnostics**, and nothing else:
140
+
141
+ ```yaml
142
+ analyzer:
143
+ errors:
144
+ unused_import: ignore # every diagnostic NOT selected
145
+ linter:
146
+ rules:
147
+ prefer_single_quotes: true # every lint selected
148
+ ```
149
+
150
+ - Unselected lints get no `false`. The file has no `include:`, so a lint it does not name is already
151
+ off. (Skipping `include:` also avoids the `package:flutter_lints` resolution failure the Docker
152
+ wrapper works around with a container-root `dart pub add`.)
153
+ - Selected diagnostics get no entry. They already fire at their default severity, and `Issue.severity`
154
+ comes from `patterns.json`. Writing a level here would mean translating Codacy's `High` into a
155
+ section that accepts only `ignore|info|warning|error` — the wrapper writes `high`, which is invalid.
156
+
157
+ ### `--format json`, not `--format machine`
158
+
159
+ The wrapper uses `--format machine` with a comment that JSON "returns multiple objects after a given
160
+ limit". That is no longer true in SDK 3.x: `emitJsonFormat` is a single `json.encode` call. JSON is
161
+ strictly better here — it carries `range.end` (→ `endLine`/`endColumn`), `correctionMessage`
162
+ (→ `Issue.suggestion`), and `code` in its original lowercase, where machine format uppercases the
163
+ code and gives only a `length` offset delta that can span lines.
164
+
165
+ `parseDartOutput` still falls back to parsing concatenated documents line by line, in case that
166
+ behaviour ever returns.
167
+
168
+ Exit codes are `0` clean, `1` infos, `2` warnings, `3` errors, `4` crash — only `4` and above is a
169
+ failure.
170
+
171
+ ### Unresolved dependencies
172
+
173
+ `dart analyze` needs `dart pub get` to have run; without `.dart_tool/package_config.json`, every
174
+ `package:` import is unresolvable and reports `uri_does_not_exist` — hundreds of findings on a real
175
+ Flutter repository.
176
+
177
+ The adapter **never runs `pub get`** (it would write `.dart_tool/` and `pubspec.lock` into the
178
+ repository, and needs the network — the same stance the ESLint adapters take on `npm install`).
179
+ Instead it warns, and suppresses `uri_does_not_exist`, `uri_has_not_been_generated` and
180
+ `depend_on_referenced_packages` for that run only. Suppression is post-hoc rather than a config
181
+ `ignore` so it also applies on the local-config path, where nothing is generated.
182
+
183
+ ### Part files
184
+
185
+ A Dart `part` file cannot be analyzed on its own; targeting one makes `dart analyze` report that it
186
+ "is a part and cannot be analyzed". That is a complaint about the invocation, not the code, so those
187
+ messages are dropped (the wrapper filters the same two strings). The library file carrying the `part`
188
+ directive is what should be analyzed. Diagnostics against non-`.dart` files (`pubspec.yaml`,
189
+ `analysis_options.yaml`) are dropped for the same reason.
190
+
191
+ ### Known limitations
192
+
193
+ - **Dart monorepos.** The swap only touches the repository root. A nested package with its own
194
+ `analysis_options.yaml` beats it, so Codacy's pattern selection is ignored for files under that
195
+ package. Tracked in `docs/tech-debt.md`.
196
+ - **Concurrent runs.** Two `codacy-analysis analyze` processes on one repository race on the swap.
197
+ - **One analysis server per chunk.** Each `dart analyze` invocation starts its own analysis server,
198
+ so a file list large enough to be split across argv chunks pays that startup more than once.
@@ -0,0 +1,8 @@
1
+ import * as _codacy_tooling from '@codacy/tooling';
2
+
3
+ /**
4
+ * @codacy/tools-dartanalyzer-3 — Dartanalyzer tool adapter for Codacy analysis.
5
+ */
6
+ declare const _default: Readonly<_codacy_tooling.ToolAdapter>;
7
+
8
+ export { _default as default };