@blundergoat/gruff-ts 0.1.0 → 0.1.1
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/CHANGELOG.md +14 -2
- package/CONTRIBUTING.md +3 -3
- package/README.md +140 -182
- package/docs/README.md +23 -0
- package/docs/ci-integration.md +63 -0
- package/docs/{CONFIGURATION.md → configuration.md} +2 -19
- package/docs/dashboard.md +29 -0
- package/docs/output-formats.md +65 -0
- package/docs/{RELEASING.md → releasing.md} +12 -10
- package/docs/rules.md +177 -0
- package/package.json +2 -2
- package/scripts/bump-version.sh +67 -18
- package/scripts/dependency-install.sh +96 -0
- package/scripts/dependency-update.sh +177 -0
- package/scripts/preflight-checks.sh +75 -0
- package/src/analyser.ts +5 -20
- package/src/blocks.ts +4 -4
- package/src/class-rules.ts +5 -6
- package/src/cli-program.ts +125 -12
- package/src/cli.ts +4 -1
- package/src/comment-rules.ts +2 -0
- package/src/config.ts +2 -4
- package/src/constants.ts +1 -1
- package/src/dead-code-rules.ts +2 -2
- package/src/init-config.ts +248 -0
- package/src/line-rules.ts +6 -8
- package/src/naming-pushers.ts +0 -31
- package/src/project-config-rules.ts +1 -1
- package/src/report-renderers.ts +60 -11
- package/src/rule-list.ts +1 -0
- package/src/rules.ts +14 -16
- package/src/safety-rules.ts +3 -3
- package/src/scoring.ts +4 -4
- package/src/test-fixtures.ts +0 -2
- package/src/text-scans.ts +1 -152
- package/src/types.ts +1 -2
- /package/docs/{REPORTS_AND_CI.md → reports-and-ci.md} +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Output Formats
|
|
2
|
+
|
|
3
|
+
`gruff-ts analyse --format <format>` renders the same analysis data for
|
|
4
|
+
different consumers. The combined legacy page remains at
|
|
5
|
+
[Reports And CI](reports-and-ci.md).
|
|
6
|
+
|
|
7
|
+
## Text
|
|
8
|
+
|
|
9
|
+
Use `text` for local terminal scans:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
./bin/gruff-ts analyse src --format text --fail-on=warning
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## JSON
|
|
16
|
+
|
|
17
|
+
Use `json` for automation. JSON reports use `gruff.analysis.v1`.
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
./bin/gruff-ts analyse src --format=json --fail-on=none > gruff-ts.json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## HTML
|
|
24
|
+
|
|
25
|
+
Use `html` for archived human review or dashboard scan output:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
./bin/gruff-ts report src --format=html --output gruff-ts.html
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Markdown
|
|
32
|
+
|
|
33
|
+
Use `markdown` for pull request comments and release notes.
|
|
34
|
+
|
|
35
|
+
## GitHub
|
|
36
|
+
|
|
37
|
+
Use `github` inside GitHub Actions to emit workflow annotations.
|
|
38
|
+
|
|
39
|
+
## Hotspot
|
|
40
|
+
|
|
41
|
+
Use `hotspot` for compact score and offender analysis.
|
|
42
|
+
|
|
43
|
+
## SARIF
|
|
44
|
+
|
|
45
|
+
Use `sarif` for GitHub code scanning or other SARIF consumers:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
./bin/gruff-ts analyse src --format=sarif --fail-on=none > gruff-ts.sarif
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Summary
|
|
52
|
+
|
|
53
|
+
`summary` has its own compact text/JSON contract:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
./bin/gruff-ts summary src --format=json --top=5 --fail-on=none
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
TypeScript keeps the existing `summary` analysis flags such as `--diff`,
|
|
60
|
+
`--baseline`, and `--generate-baseline` as extensions.
|
|
61
|
+
|
|
62
|
+
## Exit Codes
|
|
63
|
+
|
|
64
|
+
`analyse` exits `1` when at least one finding meets `--fail-on`. Use
|
|
65
|
+
`--fail-on none` for report-only jobs.
|
|
@@ -5,11 +5,11 @@ subsequent `0.1.x` patch releases.
|
|
|
5
5
|
|
|
6
6
|
## Bump The Version
|
|
7
7
|
|
|
8
|
-
`scripts/bump-version.sh <semver>` updates `package.json
|
|
9
|
-
`src/constants.ts` together so the CLI `--version`
|
|
10
|
-
`@blundergoat/gruff-ts` package version cannot drift
|
|
11
|
-
`0.1.0` release, the version should already be `0.1.0`;
|
|
12
|
-
of bumping unless the release version changes.
|
|
8
|
+
`scripts/bump-version.sh <semver>` updates `package.json`,
|
|
9
|
+
`package-lock.json`, and `src/constants.ts` together so the CLI `--version`
|
|
10
|
+
output and the published `@blundergoat/gruff-ts` package version cannot drift
|
|
11
|
+
apart. For the initial `0.1.0` release, the version should already be `0.1.0`;
|
|
12
|
+
use `--check` instead of bumping unless the release version changes.
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
scripts/bump-version.sh --check
|
|
@@ -30,9 +30,10 @@ update `CHANGELOG.md` and run `npm run check`.
|
|
|
30
30
|
explicitly accepted `human-verification-pending` milestones.
|
|
31
31
|
- [ ] `LICENSE` is present and `package.json` `license` field matches.
|
|
32
32
|
- [ ] `npm run check` passes.
|
|
33
|
-
- [ ] `scripts/preflight-checks.sh` passes (
|
|
34
|
-
|
|
35
|
-
`shellcheck`
|
|
33
|
+
- [ ] `scripts/preflight-checks.sh` passes (checks version lockstep and npm
|
|
34
|
+
publication status, runs `npm audit --audit-level=moderate`,
|
|
35
|
+
`npm run check`, a full `gruff-ts` self-scan, and `shellcheck` on
|
|
36
|
+
`scripts/*.sh` when `shellcheck` is installed).
|
|
36
37
|
- [ ] `npm pack --dry-run` shows only publishable runtime, docs, scripts, and
|
|
37
38
|
metadata files.
|
|
38
39
|
- [ ] Local smoke scan succeeds:
|
|
@@ -58,8 +59,9 @@ The package should include:
|
|
|
58
59
|
- `bin/gruff-ts`
|
|
59
60
|
- `src/` (all runtime `.ts` files; `src/**/*.test.ts` files are excluded by
|
|
60
61
|
`.npmignore`)
|
|
61
|
-
- `scripts/` (`bump-version.sh`, `check.sh`, `
|
|
62
|
-
`
|
|
62
|
+
- `scripts/` (`bump-version.sh`, `check.sh`, `dependency-install.sh`,
|
|
63
|
+
`dependency-update.sh`, `preflight-checks.sh`, `npm-publish.sh`,
|
|
64
|
+
`start-dev.sh`, `test-performance.sh`)
|
|
63
65
|
- `fixtures/sample.ts`
|
|
64
66
|
- `README.md`
|
|
65
67
|
- `CHANGELOG.md`
|
package/docs/rules.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Rules
|
|
2
|
+
|
|
3
|
+
`gruff-ts` exposes 119 rules across 11 pillars. This list is generated from the
|
|
4
|
+
public rule catalogue used by `gruff-ts list-rules`; severity, confidence,
|
|
5
|
+
thresholds, and option names are the defaults before project config overrides.
|
|
6
|
+
|
|
7
|
+
Use the CLI when you need machine-readable metadata:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
gruff-ts list-rules --format=json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Pillar Counts
|
|
14
|
+
|
|
15
|
+
- complexity: 3
|
|
16
|
+
- dead-code: 1
|
|
17
|
+
- design: 6
|
|
18
|
+
- documentation: 17
|
|
19
|
+
- maintainability: 14
|
|
20
|
+
- modernisation: 14
|
|
21
|
+
- naming: 10
|
|
22
|
+
- security: 27
|
|
23
|
+
- sensitive-data: 8
|
|
24
|
+
- size: 4
|
|
25
|
+
- test-quality: 15
|
|
26
|
+
|
|
27
|
+
## Complexity
|
|
28
|
+
|
|
29
|
+
- `complexity.cognitive` (warning; high confidence; threshold 15): Flags functions with high combined branch and nesting complexity.
|
|
30
|
+
- `complexity.cyclomatic` (warning; high confidence; threshold 15): Flags functions with many independent branch paths.
|
|
31
|
+
- `complexity.npath` (warning; medium confidence; threshold 200): Flags functions with high approximate NPath complexity.
|
|
32
|
+
|
|
33
|
+
## Dead Code
|
|
34
|
+
|
|
35
|
+
- `dead-code.unused-private-method` (advisory; low confidence): Flags private methods without an apparent same-file call site.
|
|
36
|
+
|
|
37
|
+
## Design
|
|
38
|
+
|
|
39
|
+
- `design.circular-import` (warning; medium confidence): Flags simple relative import cycles inside the discovered source set.
|
|
40
|
+
- `design.deep-relative-import` (advisory; medium confidence; threshold 2): Flags relative imports that climb too many parent directories.
|
|
41
|
+
- `design.god-function` (warning; high confidence): Flags functions that are both long and complex.
|
|
42
|
+
- `design.large-module-concentration` (advisory; medium confidence; threshold 55; options: minFiles, minLines): Flags a production module that dominates project source lines.
|
|
43
|
+
- `design.package-bin-missing` (warning; high confidence): Flags package bin entries that point at missing files.
|
|
44
|
+
- `design.package-bin-not-executable` (warning; high confidence): Flags package bin targets that are not executable.
|
|
45
|
+
|
|
46
|
+
## Documentation
|
|
47
|
+
|
|
48
|
+
- `docs.fixture-purpose-missing` (advisory; medium confidence): Flags large or scanner-relevant fixtures without a nearby purpose comment.
|
|
49
|
+
- `docs.magic-threshold-without-rationale` (advisory; medium confidence): Flags threshold-like numeric values without a nearby rationale comment.
|
|
50
|
+
- `docs.missing-error-behavior-doc` (advisory; medium confidence): Flags commented functions whose error behavior is not described.
|
|
51
|
+
- `docs.missing-file-overview` (advisory; medium confidence): Flags source files without a top-of-file purpose comment.
|
|
52
|
+
- `docs.missing-function-doc` (advisory; medium confidence): Flags functions without a leading maintainer comment.
|
|
53
|
+
- `docs.missing-interface-doc` (advisory; medium confidence): Flags interfaces without a leading maintainer comment.
|
|
54
|
+
- `docs.missing-invariant-doc` (advisory; medium confidence): Flags commented declarations that own schema, fingerprint, baseline, or determinism contracts without saying so.
|
|
55
|
+
- `docs.missing-param-tag` (advisory; medium confidence): Flags documented exports with parameters missing @param tags.
|
|
56
|
+
- `docs.missing-public-doc` (advisory; medium confidence): Flags exported class, type, and enum APIs without a nearby doc comment.
|
|
57
|
+
- `docs.missing-return-tag` (advisory; medium confidence): Flags documented non-void exports without @returns.
|
|
58
|
+
- `docs.missing-side-effect-doc` (advisory; medium confidence): Flags commented functions that perform observable side effects without naming them.
|
|
59
|
+
- `docs.missing-why-for-complex-code` (advisory; medium confidence): Flags comments on complex functions that do not explain why the shape exists.
|
|
60
|
+
- `docs.stale-comment` (advisory; medium confidence): Flags comments that reference missing files, unknown rules, stale CLI flags, or the wrong declaration.
|
|
61
|
+
- `docs.stale-param-tag` (advisory; medium confidence): Flags @param tags for parameters no longer in the signature.
|
|
62
|
+
- `docs.suppression-without-rationale` (advisory; medium confidence): Flags lint, formatter, coverage, or tool suppressions without a maintainer rationale.
|
|
63
|
+
- `docs.todo-without-tracking` (advisory; high confidence): Flags TODO, FIXME, HACK, and XXX comments without tracking context.
|
|
64
|
+
- `docs.useless-docblock` (advisory; medium confidence): Flags comments or docblocks that only restate the symbol name.
|
|
65
|
+
|
|
66
|
+
## Modernisation
|
|
67
|
+
|
|
68
|
+
- `modernisation.date-now-candidate` (advisory; high confidence): Flags verbose current-time expressions that can use Date.now().
|
|
69
|
+
- `modernisation.double-cast` (warning; medium confidence): Flags casts through unknown or any into another type.
|
|
70
|
+
- `modernisation.loose-equality` (advisory; medium confidence): Flags loose equality comparisons that may coerce values.
|
|
71
|
+
- `modernisation.non-null-assertion` (warning; medium confidence): Flags non-null assertions that bypass null checks.
|
|
72
|
+
- `modernisation.nullish-coalescing-candidate` (advisory; medium confidence): Flags || fallbacks that may erase valid falsy values.
|
|
73
|
+
- `modernisation.object-spread-candidate` (advisory; medium confidence): Flags Object.assign({}, ...) cloning that can use object spread.
|
|
74
|
+
- `modernisation.optional-chaining-candidate` (advisory; medium confidence): Flags repeated guard-and-property access patterns.
|
|
75
|
+
- `modernisation.public-property` (advisory; high confidence): Flags public class properties that expose representation.
|
|
76
|
+
- `modernisation.readonly-property-candidate` (advisory; medium confidence): Flags class properties that appear readonly-worthy.
|
|
77
|
+
- `modernisation.ts-comment-without-rationale` (warning; medium confidence): Flags TypeScript suppression comments without a rationale.
|
|
78
|
+
- `modernisation.tsconfig-exact-optional-disabled` (warning; high confidence): Flags tsconfig files without exactOptionalPropertyTypes enabled.
|
|
79
|
+
- `modernisation.tsconfig-index-safety-disabled` (warning; high confidence): Flags tsconfig files without noUncheckedIndexedAccess enabled.
|
|
80
|
+
- `modernisation.tsconfig-strict-disabled` (warning; high confidence): Flags tsconfig files without strict mode enabled.
|
|
81
|
+
- `modernisation.var-declaration` (advisory; high confidence): Flags var declarations.
|
|
82
|
+
|
|
83
|
+
## Naming
|
|
84
|
+
|
|
85
|
+
- `naming.acronym-case` (advisory; medium confidence): Flags mixed casings of a known acronym in one file.
|
|
86
|
+
- `naming.boolean-prefix` (advisory; medium confidence): Flags boolean names without intent-revealing prefixes on declarations, function parameters (typed `: boolean` or with `= true|false` default), and interface/type-literal fields.
|
|
87
|
+
- `naming.class-file-mismatch` (advisory; medium confidence): Flags exported classes whose name differs from the file name.
|
|
88
|
+
- `naming.generic-function` (advisory; high confidence): Flags generic function names that hide intent.
|
|
89
|
+
- `naming.generic-parameter` (advisory; medium confidence; options: minCyclomatic, minLineCount, minParameters): Flags placeholder parameter names in multi-parameter, long, exported, or complex functions.
|
|
90
|
+
- `naming.hungarian-notation` (advisory; medium confidence): Flags identifiers named after storage type prefixes.
|
|
91
|
+
- `naming.identifier-quality` (advisory; medium confidence): Flags placeholder or numbered identifiers on declarations, function parameters, and destructured locals.
|
|
92
|
+
- `naming.inconsistent-casing` (advisory; medium confidence): Flags the same canonical identifier appearing in two different surface forms (for example CONSTANT_CASE and camelCase) in one file.
|
|
93
|
+
- `naming.negative-boolean` (advisory; medium confidence): Flags boolean identifiers framed as a negation on declarations, parameters, and interface fields.
|
|
94
|
+
- `naming.short-variable` (advisory; medium confidence): Flags very short variable names outside common loop counters; covers declarations, function parameters, and destructured locals.
|
|
95
|
+
|
|
96
|
+
## Security
|
|
97
|
+
|
|
98
|
+
- `security.async-foreach` (warning; medium confidence): Flags async callbacks passed to forEach.
|
|
99
|
+
- `security.disabled-tls-verification` (error; high confidence): Flags code that disables TLS certificate verification.
|
|
100
|
+
- `security.document-write` (warning; high confidence): Flags document.write usage.
|
|
101
|
+
- `security.dynamic-regexp` (warning; medium confidence): Flags external input used to construct regular expressions.
|
|
102
|
+
- `security.eval-call` (error; high confidence): Flags eval() dynamic code execution.
|
|
103
|
+
- `security.floating-promise` (warning; medium confidence): Flags promise-like calls without await, return, or void.
|
|
104
|
+
- `security.github-actions-broad-permissions` (warning; medium confidence): Flags GitHub Actions workflows that grant broad write permissions.
|
|
105
|
+
- `security.github-actions-pull-request-target` (warning; medium confidence): Flags pull_request_target workflows paired with risky execution or trust context.
|
|
106
|
+
- `security.github-actions-remote-shell` (warning; medium confidence): Flags workflow run steps that pipe remote downloads to a shell.
|
|
107
|
+
- `security.github-actions-secrets-in-pr` (warning; medium confidence): Flags pull request workflows that reference GitHub secrets.
|
|
108
|
+
- `security.github-actions-unpinned-action` (warning; medium confidence): Flags third-party GitHub Actions that are not pinned to a full commit SHA.
|
|
109
|
+
- `security.inner-html` (warning; high confidence): Flags innerHTML assignment.
|
|
110
|
+
- `security.insecure-random` (warning; high confidence): Flags Math.random usage in source.
|
|
111
|
+
- `security.javascript-url` (error; high confidence): Flags javascript: URL literals that execute script.
|
|
112
|
+
- `security.new-function` (error; high confidence): Flags Function constructor dynamic code execution.
|
|
113
|
+
- `security.open-redirect-candidate` (warning; medium confidence): Flags external input sent to redirect or navigation sinks.
|
|
114
|
+
- `security.path-traversal-candidate` (warning; medium confidence): Flags external input sent to filesystem path sinks.
|
|
115
|
+
- `security.process-exec` (warning; high confidence): Flags child-process execution calls.
|
|
116
|
+
- `security.proto-access` (warning; medium confidence): Flags direct __proto__ access that can enable prototype pollution.
|
|
117
|
+
- `security.remote-install-script` (error; medium confidence): Flags package scripts that pipe remote content to a shell.
|
|
118
|
+
- `security.risky-lifecycle-script` (warning; medium confidence): Flags package lifecycle scripts that run automatically.
|
|
119
|
+
- `security.sql-concatenation` (warning; high confidence): Flags SQL text composed with runtime string interpolation.
|
|
120
|
+
- `security.ssrf-candidate` (warning; medium confidence): Flags external input sent to network request sinks.
|
|
121
|
+
- `security.string-timer` (warning; high confidence): Flags string callbacks passed to timers.
|
|
122
|
+
- `security.throw-non-error` (warning; medium confidence): Flags thrown non-Error values.
|
|
123
|
+
- `security.url-dependency` (warning; medium confidence): Flags dependencies installed from URL or git specs.
|
|
124
|
+
- `security.weak-crypto` (warning; high confidence): Flags weak crypto primitives such as md5, sha1, or createCipher.
|
|
125
|
+
|
|
126
|
+
## Sensitive Data
|
|
127
|
+
|
|
128
|
+
- `sensitive-data.api-key-pattern` (error; high confidence): Flags vendor API key patterns.
|
|
129
|
+
- `sensitive-data.aws-access-key` (error; high confidence): Flags AWS access key looking values.
|
|
130
|
+
- `sensitive-data.database-url-password` (error; high confidence): Flags database URLs that include passwords.
|
|
131
|
+
- `sensitive-data.hardcoded-env-value` (error; medium confidence; threshold 16): Flags environment-style secret values committed in text.
|
|
132
|
+
- `sensitive-data.high-entropy-string` (error; medium confidence; threshold 32): Flags high-entropy string literals that may be secrets.
|
|
133
|
+
- `sensitive-data.jwt-token` (error; high confidence): Flags JWT-looking token literals.
|
|
134
|
+
- `sensitive-data.pii-pattern` (error; high confidence): Flags PII-like identifier patterns.
|
|
135
|
+
- `sensitive-data.private-key` (error; high confidence): Flags private key block markers.
|
|
136
|
+
|
|
137
|
+
## Size
|
|
138
|
+
|
|
139
|
+
- `size.file-length` (warning; high confidence; threshold 750): Flags files longer than the configured threshold.
|
|
140
|
+
- `size.function-length` (warning; high confidence; threshold 200): Flags functions longer than the configured threshold.
|
|
141
|
+
- `size.parameter-count` (warning; high confidence; threshold 7): Flags functions with too many parameters.
|
|
142
|
+
- `size.stylesheet-length` (warning; high confidence; threshold 1500): Flags stylesheets longer than the configured threshold.
|
|
143
|
+
|
|
144
|
+
## Test Quality
|
|
145
|
+
|
|
146
|
+
- `test-quality.conditional-logic` (advisory; high confidence): Flags tests with conditional logic.
|
|
147
|
+
- `test-quality.exception-type-only` (advisory; high confidence): Flags tests that only assert exception type.
|
|
148
|
+
- `test-quality.global-state-mutation` (warning; high confidence): Flags tests mutating process or global runtime state.
|
|
149
|
+
- `test-quality.loop-in-test` (advisory; high confidence): Flags loops inside test bodies.
|
|
150
|
+
- `test-quality.magic-number-assertion` (advisory; medium confidence): Flags assertions against unexplained numeric literals.
|
|
151
|
+
- `test-quality.missing-nearby-test` (advisory; medium confidence): Flags exported production files without nearby tests.
|
|
152
|
+
- `test-quality.mock-only-test` (advisory; high confidence): Flags tests that only verify mock interaction.
|
|
153
|
+
- `test-quality.no-assertions` (warning; high confidence): Flags tests without apparent assertions.
|
|
154
|
+
- `test-quality.no-throw-only-test` (advisory; high confidence): Flags tests that only assert code does not throw.
|
|
155
|
+
- `test-quality.only-skip` (advisory; high confidence): Flags focused or skipped test markers.
|
|
156
|
+
- `test-quality.setup-bloat` (advisory; medium confidence; threshold 12): Flags tests with too much setup before the first assertion.
|
|
157
|
+
- `test-quality.sleep-in-test` (advisory; high confidence): Flags sleeps in tests.
|
|
158
|
+
- `test-quality.snapshot-only-test` (advisory; high confidence): Flags tests that rely only on snapshots.
|
|
159
|
+
- `test-quality.trivial-assertion` (warning; high confidence): Flags tautological assertions.
|
|
160
|
+
- `test-quality.unused-mock` (advisory; medium confidence): Flags mocks created but not used.
|
|
161
|
+
|
|
162
|
+
## Maintainability
|
|
163
|
+
|
|
164
|
+
- `waste.any-type` (warning; high confidence): Flags any type usage.
|
|
165
|
+
- `waste.broad-runtime-version` (advisory; medium confidence): Flags broad runtime dependency version ranges.
|
|
166
|
+
- `waste.commented-out-code` (advisory; high confidence): Flags comments that appear to contain disabled code.
|
|
167
|
+
- `waste.console-log` (advisory; high confidence): Flags console log/debug calls in source.
|
|
168
|
+
- `waste.empty-function` (advisory; high confidence): Flags functions with no executable body.
|
|
169
|
+
- `waste.exported-any` (warning; medium confidence): Flags exported APIs exposing any.
|
|
170
|
+
- `waste.redundant-boolean-cast` (advisory; medium confidence): Flags redundant boolean casts in condition expressions.
|
|
171
|
+
- `waste.redundant-variable` (advisory; medium confidence): Flags variables returned immediately after assignment.
|
|
172
|
+
- `waste.swallowed-catch` (warning; medium confidence): Flags empty catch blocks.
|
|
173
|
+
- `waste.unreachable-code` (warning; high confidence): Flags statements after terminating statements.
|
|
174
|
+
- `waste.unused-import` (advisory; medium confidence): Flags named imports with no apparent usage.
|
|
175
|
+
- `waste.unused-parameter` (advisory; medium confidence): Flags parameters with no apparent usage.
|
|
176
|
+
- `waste.useless-catch` (advisory; high confidence): Flags catch blocks that only rethrow the caught value.
|
|
177
|
+
- `waste.useless-return` (advisory; medium confidence): Flags terminal bare return statements in void functions.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blundergoat/gruff-ts",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Static analyzer for TypeScript and JavaScript projects -
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Static analyzer for TypeScript and JavaScript projects - 119 rules across 11 quality pillars, SARIF output, baselines, and a local dashboard.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Matthew Hansen (https://www.blundergoat.com/about)",
|
|
7
7
|
"homepage": "https://github.com/blundergoat/gruff-ts#readme",
|
package/scripts/bump-version.sh
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
-
# Bump gruff-ts to a new semver in package.json and src/constants.ts
|
|
5
|
-
# The CLI surfaces VERSION from src/constants.ts; package
|
|
6
|
-
# Keeping
|
|
4
|
+
# Bump gruff-ts to a new semver in package.json, package-lock.json, and src/constants.ts.
|
|
5
|
+
# The CLI surfaces VERSION from src/constants.ts; package metadata drives `npm publish`.
|
|
6
|
+
# Keeping all release version surfaces in lockstep is a release invariant.
|
|
7
7
|
|
|
8
8
|
usage() {
|
|
9
9
|
cat <<'USAGE'
|
|
@@ -15,7 +15,7 @@ Arguments:
|
|
|
15
15
|
<new-version> Target semver, e.g. 0.1.1, 0.2.0, 1.0.0-rc.1.
|
|
16
16
|
|
|
17
17
|
Options:
|
|
18
|
-
--check Verify package.json and src/constants.ts already agree.
|
|
18
|
+
--check Verify package.json, package-lock.json, and src/constants.ts already agree.
|
|
19
19
|
--help, -h Show this help.
|
|
20
20
|
|
|
21
21
|
Notes:
|
|
@@ -42,6 +42,14 @@ read_constants_version() {
|
|
|
42
42
|
awk -F'"' '/^const VERSION = "/ { print $2; exit }' src/constants.ts
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
read_package_lock_version() {
|
|
46
|
+
node -e 'const fs = require("node:fs"); const data = JSON.parse(fs.readFileSync("package-lock.json", "utf8")); process.stdout.write(String(data.version ?? ""));'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
read_package_lock_package_version() {
|
|
50
|
+
node -e 'const fs = require("node:fs"); const data = JSON.parse(fs.readFileSync("package-lock.json", "utf8")); process.stdout.write(String(data.packages?.[""]?.version ?? ""));'
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
write_package_version() {
|
|
46
54
|
local next_version="$1"
|
|
47
55
|
awk -v target="$next_version" '
|
|
@@ -69,13 +77,50 @@ write_constants_version() {
|
|
|
69
77
|
mv src/constants.ts.tmp src/constants.ts
|
|
70
78
|
}
|
|
71
79
|
|
|
80
|
+
write_package_lock_version() {
|
|
81
|
+
local next_version="$1"
|
|
82
|
+
node - "$next_version" <<'NODE'
|
|
83
|
+
const fs = require("node:fs");
|
|
84
|
+
|
|
85
|
+
const target = process.argv[2];
|
|
86
|
+
const lockPath = "package-lock.json";
|
|
87
|
+
const lock = JSON.parse(fs.readFileSync(lockPath, "utf8"));
|
|
88
|
+
|
|
89
|
+
lock.version = target;
|
|
90
|
+
if (!lock.packages || typeof lock.packages !== "object" || !lock.packages[""]) {
|
|
91
|
+
throw new Error('package-lock.json missing packages[""] root package entry');
|
|
92
|
+
}
|
|
93
|
+
lock.packages[""].version = target;
|
|
94
|
+
|
|
95
|
+
fs.writeFileSync(`${lockPath}.tmp`, `${JSON.stringify(lock, null, 2)}\n`);
|
|
96
|
+
NODE
|
|
97
|
+
mv package-lock.json.tmp package-lock.json
|
|
98
|
+
}
|
|
99
|
+
|
|
72
100
|
validate_semver() {
|
|
73
101
|
local value="$1"
|
|
74
102
|
# Standard semver: MAJOR.MINOR.PATCH with optional prerelease/build metadata.
|
|
75
|
-
local pattern='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z
|
|
103
|
+
local pattern='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$'
|
|
76
104
|
[[ "$value" =~ $pattern ]] || die "not a valid semver: $value"
|
|
77
105
|
}
|
|
78
106
|
|
|
107
|
+
check_version_lockstep() {
|
|
108
|
+
local pkg const_ lock lock_package
|
|
109
|
+
pkg="$(read_package_version)" || die "failed to read package.json version"
|
|
110
|
+
const_="$(read_constants_version)" || die "failed to read src/constants.ts VERSION"
|
|
111
|
+
lock="$(read_package_lock_version)" || die "failed to read package-lock.json root version"
|
|
112
|
+
lock_package="$(read_package_lock_package_version)" || die "failed to read package-lock.json package version"
|
|
113
|
+
[[ -n "$pkg" ]] || die "package.json has no \"version\" field"
|
|
114
|
+
[[ -n "$const_" ]] || die "src/constants.ts has no VERSION constant"
|
|
115
|
+
[[ -n "$lock" ]] || die "package-lock.json has no root \"version\" field"
|
|
116
|
+
[[ -n "$lock_package" ]] || die 'package-lock.json has no packages[""].version field'
|
|
117
|
+
if ! [[ "$pkg" == "$const_" && "$pkg" == "$lock" && "$pkg" == "$lock_package" ]]; then
|
|
118
|
+
printf 'version surfaces disagree: package.json=%s src/constants.ts=%s package-lock.json=%s package-lock.json packages[""]=%s\n' "$pkg" "$const_" "$lock" "$lock_package" >&2
|
|
119
|
+
exit 1
|
|
120
|
+
fi
|
|
121
|
+
printf 'package.json, package-lock.json, and src/constants.ts agree on %s\n' "$pkg"
|
|
122
|
+
}
|
|
123
|
+
|
|
79
124
|
main() {
|
|
80
125
|
if [[ "$#" -eq 0 ]]; then
|
|
81
126
|
usage >&2
|
|
@@ -84,6 +129,7 @@ main() {
|
|
|
84
129
|
|
|
85
130
|
cd "$(repo_root)"
|
|
86
131
|
[[ -f package.json ]] || die "package.json not found"
|
|
132
|
+
[[ -f package-lock.json ]] || die "package-lock.json not found"
|
|
87
133
|
[[ -f src/constants.ts ]] || die "src/constants.ts not found"
|
|
88
134
|
|
|
89
135
|
case "$1" in
|
|
@@ -92,16 +138,7 @@ main() {
|
|
|
92
138
|
exit 0
|
|
93
139
|
;;
|
|
94
140
|
--check)
|
|
95
|
-
|
|
96
|
-
pkg="$(read_package_version)" || die "failed to read package.json version"
|
|
97
|
-
const_="$(read_constants_version)" || die "failed to read src/constants.ts VERSION"
|
|
98
|
-
[[ -n "$pkg" ]] || die "package.json has no \"version\" field"
|
|
99
|
-
[[ -n "$const_" ]] || die "src/constants.ts has no VERSION constant"
|
|
100
|
-
if [[ "$pkg" != "$const_" ]]; then
|
|
101
|
-
printf 'package.json (%s) and src/constants.ts (%s) disagree\n' "$pkg" "$const_" >&2
|
|
102
|
-
exit 1
|
|
103
|
-
fi
|
|
104
|
-
printf 'package.json and src/constants.ts agree on %s\n' "$pkg"
|
|
141
|
+
check_version_lockstep
|
|
105
142
|
exit 0
|
|
106
143
|
;;
|
|
107
144
|
esac
|
|
@@ -117,8 +154,14 @@ main() {
|
|
|
117
154
|
current_const="$(read_constants_version)" || die "failed to read src/constants.ts VERSION"
|
|
118
155
|
[[ -n "$current_const" ]] || die "src/constants.ts has no VERSION constant"
|
|
119
156
|
|
|
120
|
-
|
|
121
|
-
|
|
157
|
+
local current_lock current_lock_package
|
|
158
|
+
current_lock="$(read_package_lock_version)" || die "failed to read package-lock.json root version"
|
|
159
|
+
current_lock_package="$(read_package_lock_package_version)" || die "failed to read package-lock.json package version"
|
|
160
|
+
[[ -n "$current_lock" ]] || die "package-lock.json has no root \"version\" field"
|
|
161
|
+
[[ -n "$current_lock_package" ]] || die 'package-lock.json has no packages[""].version field'
|
|
162
|
+
|
|
163
|
+
if ! [[ "$current" == "$current_const" && "$current" == "$current_lock" && "$current" == "$current_lock_package" ]]; then
|
|
164
|
+
die "current versions diverge: package.json=$current src/constants.ts=$current_const package-lock.json=$current_lock package-lock.json packages[\"\"]=$current_lock_package (resolve manually first)"
|
|
122
165
|
fi
|
|
123
166
|
|
|
124
167
|
if [[ "$current" == "$next" ]]; then
|
|
@@ -128,15 +171,21 @@ main() {
|
|
|
128
171
|
|
|
129
172
|
write_package_version "$next"
|
|
130
173
|
write_constants_version "$next"
|
|
174
|
+
write_package_lock_version "$next"
|
|
131
175
|
|
|
132
|
-
local check_pkg check_const
|
|
176
|
+
local check_pkg check_const check_lock check_lock_package
|
|
133
177
|
check_pkg="$(read_package_version)"
|
|
134
178
|
check_const="$(read_constants_version)"
|
|
179
|
+
check_lock="$(read_package_lock_version)"
|
|
180
|
+
check_lock_package="$(read_package_lock_package_version)"
|
|
135
181
|
[[ "$check_pkg" == "$next" ]] || die "package.json did not update cleanly (read back: ${check_pkg:-empty})"
|
|
136
182
|
[[ "$check_const" == "$next" ]] || die "src/constants.ts did not update cleanly (read back: ${check_const:-empty})"
|
|
183
|
+
[[ "$check_lock" == "$next" ]] || die "package-lock.json did not update cleanly (read back: ${check_lock:-empty})"
|
|
184
|
+
[[ "$check_lock_package" == "$next" ]] || die "package-lock.json packages[\"\"] did not update cleanly (read back: ${check_lock_package:-empty})"
|
|
137
185
|
|
|
138
186
|
printf 'bumped %s -> %s\n' "$current" "$next"
|
|
139
187
|
printf ' package.json\n'
|
|
188
|
+
printf ' package-lock.json\n'
|
|
140
189
|
printf ' src/constants.ts\n'
|
|
141
190
|
# shellcheck disable=SC2016
|
|
142
191
|
printf 'next: update CHANGELOG.md and run `npm run check`\n'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
NPM_AUDIT_LEVEL="${NPM_AUDIT_LEVEL:-moderate}"
|
|
5
|
+
RUN_AUDIT=1
|
|
6
|
+
RUN_CHECK=0
|
|
7
|
+
|
|
8
|
+
usage() {
|
|
9
|
+
cat <<'USAGE'
|
|
10
|
+
Usage:
|
|
11
|
+
scripts/dependency-install.sh [options]
|
|
12
|
+
|
|
13
|
+
Installs dependencies from package-lock.json using npm ci.
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
--audit-level LEVEL npm audit threshold (default: moderate)
|
|
17
|
+
--no-audit Skip npm audit after install
|
|
18
|
+
--check Run npm run check after install and audit
|
|
19
|
+
--help, -h Show this help
|
|
20
|
+
|
|
21
|
+
Environment:
|
|
22
|
+
NPM_AUDIT_LEVEL Default audit threshold when --audit-level is omitted
|
|
23
|
+
USAGE
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
die() {
|
|
27
|
+
printf 'dependency-install: %s\n' "$*" >&2
|
|
28
|
+
exit 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
repo_root() {
|
|
32
|
+
local script_dir
|
|
33
|
+
script_dir="$(CDPATH='' cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
34
|
+
CDPATH='' cd -- "$script_dir/.." && pwd
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
parse_args() {
|
|
38
|
+
while [[ "$#" -gt 0 ]]; do
|
|
39
|
+
case "$1" in
|
|
40
|
+
--audit-level)
|
|
41
|
+
[[ "$#" -ge 2 ]] || die "--audit-level requires a value"
|
|
42
|
+
NPM_AUDIT_LEVEL="$2"
|
|
43
|
+
shift
|
|
44
|
+
;;
|
|
45
|
+
--audit-level=*)
|
|
46
|
+
NPM_AUDIT_LEVEL="${1#*=}"
|
|
47
|
+
;;
|
|
48
|
+
--no-audit)
|
|
49
|
+
RUN_AUDIT=0
|
|
50
|
+
;;
|
|
51
|
+
--check)
|
|
52
|
+
RUN_CHECK=1
|
|
53
|
+
;;
|
|
54
|
+
--help|-h)
|
|
55
|
+
usage
|
|
56
|
+
exit 0
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
usage >&2
|
|
60
|
+
die "unknown option: $1"
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
shift
|
|
64
|
+
done
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
require_tool() {
|
|
68
|
+
command -v "$1" >/dev/null 2>&1 || die "$1 is required"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
main() {
|
|
72
|
+
parse_args "$@"
|
|
73
|
+
cd "$(repo_root)"
|
|
74
|
+
|
|
75
|
+
require_tool node
|
|
76
|
+
require_tool npm
|
|
77
|
+
[[ -f package.json ]] || die "package.json not found"
|
|
78
|
+
[[ -f package-lock.json ]] || die "package-lock.json not found"
|
|
79
|
+
|
|
80
|
+
echo "--- Install dependencies ---"
|
|
81
|
+
npm ci
|
|
82
|
+
|
|
83
|
+
if [[ "$RUN_AUDIT" -eq 1 ]]; then
|
|
84
|
+
echo ""
|
|
85
|
+
echo "--- Dependency audit ---"
|
|
86
|
+
npm audit --audit-level="$NPM_AUDIT_LEVEL"
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
if [[ "$RUN_CHECK" -eq 1 ]]; then
|
|
90
|
+
echo ""
|
|
91
|
+
echo "--- TypeScript + tests ---"
|
|
92
|
+
npm run check
|
|
93
|
+
fi
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main "$@"
|