ng-checkup 0.1.0 → 0.2.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/dist/init.d.ts ADDED
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The two reads `planInit` needs. `ng-checkup init` backs it with `node:fs`,
3
+ * `ng add` with the schematic's virtual tree, and tests with a plain object,
4
+ * which is why the planner never touches the disk itself.
5
+ */
6
+ export interface InitFileSystem {
7
+ /** File content, or undefined when the path is missing. Paths are root-relative with `/`. */
8
+ read(path: string): string | undefined;
9
+ /** True for an existing file or directory. */
10
+ exists(path: string): boolean;
11
+ }
12
+ /** Where the CI step goes. `auto` picks from what the repository already has. */
13
+ export type CiChoice = 'auto' | 'github' | 'gitlab' | 'none';
14
+ /** What `planInit` should do. */
15
+ export interface InitOptions {
16
+ /** Defaults to `auto`: GitHub when `.github/` exists, GitLab when `.gitlab-ci.yml` does, else none. */
17
+ ci?: CiChoice;
18
+ /**
19
+ * Add `ng-checkup` to `devDependencies`. Defaults to true. `ng add` passes
20
+ * false because the Angular CLI has already installed and saved it.
21
+ */
22
+ addDependency?: boolean;
23
+ /** The version to pin, normally this package's own. */
24
+ version: string;
25
+ /** Replace an existing `checkup` script that runs something else. */
26
+ force?: boolean;
27
+ }
28
+ /** One file to write. Content is the whole new file. */
29
+ export interface InitChange {
30
+ path: string;
31
+ action: 'create' | 'update';
32
+ content: string;
33
+ /** One line for the user: what this change does. */
34
+ summary: string;
35
+ }
36
+ /** Everything `init` would do, and what the user has to do afterwards. */
37
+ export interface InitPlan {
38
+ changes: InitChange[];
39
+ /** Things left alone or left to the user, one line each. */
40
+ notes: string[];
41
+ /** Commands the user runs next, in order. */
42
+ nextSteps: string[];
43
+ ci: Exclude<CiChoice, 'auto'>;
44
+ packageManager: PackageManager;
45
+ }
46
+ /** The package managers whose lockfiles `init` recognises. */
47
+ export type PackageManager = 'npm' | 'pnpm' | 'yarn';
48
+ /**
49
+ * Plans what `ng-checkup init` and `ng add ng-checkup` set up in a repository:
50
+ *
51
+ * 1. a `checkup` script in `package.json` (and `ng-checkup` in `devDependencies`),
52
+ * 2. `ng-checkup.config.json` with the local report and an empty `ignore` list,
53
+ * 3. the generated reports in `.gitignore`, when there is one,
54
+ * 4. a CI step: a GitHub Actions workflow, or a GitLab CI file to `include`.
55
+ *
56
+ * Idempotent: on a repository that already has all of it, the plan is empty.
57
+ * It never overwrites a file the user wrote: an existing workflow, config or
58
+ * different `checkup` script is kept and reported in `notes` instead
59
+ * (`force` replaces the script only). It does not edit `.gitlab-ci.yml`
60
+ * either, since merging into someone's pipeline YAML is where a tool does
61
+ * damage; it writes a separate file and says which `include` to add.
62
+ *
63
+ * @throws When there is no `package.json` or it is not valid JSON. Both mean
64
+ * this is not the root of a Node project, and writing anything would be wrong.
65
+ */
66
+ export declare function planInit(files: InitFileSystem, options: InitOptions): InitPlan;
67
+ /** The package manager, from its lockfile. npm when there is none or only npm's. */
68
+ export declare function detectPackageManager(files: InitFileSystem): PackageManager;
69
+ /** A GitHub Actions workflow for the repository's package manager. */
70
+ export declare function githubWorkflow(manager: PackageManager): string;
71
+ /** A GitLab CI job file for the repository's package manager, meant to be `include`d. */
72
+ export declare function gitlabJob(manager: PackageManager): string;
73
+ /**
74
+ * Serialises `value` with the indentation and final newline of `original`,
75
+ * so `init` changes only the lines it means to and a `git diff` of
76
+ * `package.json` shows exactly the added keys.
77
+ */
78
+ export declare function formatJsonLike(original: string, value: unknown): string;
package/dist/init.js ADDED
@@ -0,0 +1,220 @@
1
+ import { CONFIG_FILE } from './config.js';
2
+ /** The script `init` adds. Reports come from the config file, so the script stays this short. */
3
+ const CHECKUP_SCRIPT = 'ng-checkup';
4
+ /** Report files the generated config writes locally and the CI step writes as artifacts. */
5
+ const LOCAL_REPORT = 'checkup.html';
6
+ const CI_REPORTS = ['checkup.md', 'checkup.html'];
7
+ /**
8
+ * Plans what `ng-checkup init` and `ng add ng-checkup` set up in a repository:
9
+ *
10
+ * 1. a `checkup` script in `package.json` (and `ng-checkup` in `devDependencies`),
11
+ * 2. `ng-checkup.config.json` with the local report and an empty `ignore` list,
12
+ * 3. the generated reports in `.gitignore`, when there is one,
13
+ * 4. a CI step: a GitHub Actions workflow, or a GitLab CI file to `include`.
14
+ *
15
+ * Idempotent: on a repository that already has all of it, the plan is empty.
16
+ * It never overwrites a file the user wrote: an existing workflow, config or
17
+ * different `checkup` script is kept and reported in `notes` instead
18
+ * (`force` replaces the script only). It does not edit `.gitlab-ci.yml`
19
+ * either, since merging into someone's pipeline YAML is where a tool does
20
+ * damage; it writes a separate file and says which `include` to add.
21
+ *
22
+ * @throws When there is no `package.json` or it is not valid JSON. Both mean
23
+ * this is not the root of a Node project, and writing anything would be wrong.
24
+ */
25
+ export function planInit(files, options) {
26
+ const changes = [];
27
+ const notes = [];
28
+ const packageManager = detectPackageManager(files);
29
+ const packageText = files.read('package.json');
30
+ if (packageText === undefined)
31
+ throw new Error('No package.json here. Run ng-checkup init in the root of your Angular project.');
32
+ let packageJson;
33
+ try {
34
+ packageJson = JSON.parse(packageText);
35
+ }
36
+ catch (error) {
37
+ throw new Error(`package.json is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
38
+ }
39
+ const dependencies = asRecord(packageJson['dependencies']);
40
+ const devDependencies = asRecord(packageJson['devDependencies']);
41
+ if (!files.exists('angular.json') && !files.exists('nx.json') && !('@angular/core' in dependencies) && !('@angular/core' in devDependencies)) {
42
+ notes.push('This does not look like an Angular workspace (no angular.json, nx.json or @angular/core). The checkup will still run, but most areas will be "info".');
43
+ }
44
+ // 1. package.json: the script and the dev dependency.
45
+ let packageChanged = false;
46
+ const summaryParts = [];
47
+ const scripts = { ...asRecord(packageJson['scripts']) };
48
+ const existingScript = scripts['checkup'];
49
+ if (existingScript === undefined || (existingScript !== CHECKUP_SCRIPT && options.force)) {
50
+ scripts['checkup'] = CHECKUP_SCRIPT;
51
+ packageJson['scripts'] = scripts;
52
+ packageChanged = true;
53
+ summaryParts.push(`"checkup" script`);
54
+ }
55
+ else if (existingScript !== CHECKUP_SCRIPT) {
56
+ notes.push(`Kept your existing "checkup" script (${String(existingScript)}). Run with --force to replace it with "${CHECKUP_SCRIPT}".`);
57
+ }
58
+ const addDependency = options.addDependency ?? true;
59
+ if (addDependency && !('ng-checkup' in dependencies) && !('ng-checkup' in devDependencies)) {
60
+ packageJson['devDependencies'] = { ...devDependencies, 'ng-checkup': `^${options.version}` };
61
+ packageChanged = true;
62
+ summaryParts.push(`ng-checkup ^${options.version} in devDependencies`);
63
+ }
64
+ if (packageChanged) {
65
+ changes.push({ path: 'package.json', action: 'update', content: formatJsonLike(packageText, packageJson), summary: `Adds ${summaryParts.join(' and ')}` });
66
+ }
67
+ // 2. The config file.
68
+ if (!files.exists(CONFIG_FILE)) {
69
+ changes.push({
70
+ path: CONFIG_FILE,
71
+ action: 'create',
72
+ content: `${JSON.stringify({ reports: [LOCAL_REPORT], ignore: [] }, null, 2)}\n`,
73
+ summary: `Writes ${LOCAL_REPORT} on every run; add paths to "ignore" to leave them out`,
74
+ });
75
+ }
76
+ // 3. .gitignore, only when the repository has one.
77
+ const gitignore = files.read('.gitignore');
78
+ if (gitignore !== undefined) {
79
+ const lines = new Set(gitignore.split(/\r?\n/).map((line) => line.trim()));
80
+ const missing = [...new Set([LOCAL_REPORT, ...CI_REPORTS])].map((report) => `/${report}`).filter((entry) => !lines.has(entry) && !lines.has(entry.slice(1)));
81
+ if (missing.length > 0) {
82
+ const separator = gitignore.length === 0 || gitignore.endsWith('\n') ? '' : '\n';
83
+ changes.push({ path: '.gitignore', action: 'update', content: `${gitignore}${separator}\n# ng-checkup reports\n${missing.join('\n')}\n`, summary: 'Keeps the generated reports out of git' });
84
+ }
85
+ }
86
+ // 4. CI.
87
+ const ci = resolveCi(files, options.ci ?? 'auto');
88
+ if (ci === 'github') {
89
+ const path = '.github/workflows/ng-checkup.yml';
90
+ if (files.exists(path))
91
+ notes.push(`Kept the existing ${path}.`);
92
+ else
93
+ changes.push({ path, action: 'create', content: githubWorkflow(packageManager), summary: 'Runs the checkup on every pull request and uploads the reports' });
94
+ }
95
+ else if (ci === 'gitlab') {
96
+ const path = 'ng-checkup.gitlab-ci.yml';
97
+ if (files.exists(path))
98
+ notes.push(`Kept the existing ${path}.`);
99
+ else
100
+ changes.push({ path, action: 'create', content: gitlabJob(packageManager), summary: 'A GitLab CI job that runs the checkup and keeps the reports as artifacts' });
101
+ if (!(files.read('.gitlab-ci.yml') ?? '').includes(path)) {
102
+ notes.push(`Add this to your .gitlab-ci.yml to run it:\n include:\n - local: ${path}`);
103
+ }
104
+ }
105
+ else if ((options.ci ?? 'auto') === 'auto') {
106
+ notes.push('No .github/ or .gitlab-ci.yml found, so no CI step was added. Run with --ci github or --ci gitlab to add one.');
107
+ }
108
+ const nextSteps = [];
109
+ if (packageChanged && addDependency)
110
+ nextSteps.push(installCommand(packageManager, false));
111
+ nextSteps.push(runScriptCommand(packageManager));
112
+ return { changes, notes, nextSteps, ci, packageManager };
113
+ }
114
+ /** The CI to set up for `auto`: whatever the repository already uses. */
115
+ function resolveCi(files, choice) {
116
+ if (choice !== 'auto')
117
+ return choice;
118
+ if (files.exists('.github'))
119
+ return 'github';
120
+ if (files.exists('.gitlab-ci.yml'))
121
+ return 'gitlab';
122
+ return 'none';
123
+ }
124
+ /** The package manager, from its lockfile. npm when there is none or only npm's. */
125
+ export function detectPackageManager(files) {
126
+ if (files.exists('pnpm-lock.yaml'))
127
+ return 'pnpm';
128
+ if (files.exists('yarn.lock'))
129
+ return 'yarn';
130
+ return 'npm';
131
+ }
132
+ /** Install command; `frozen` is the CI form that refuses to change the lockfile. */
133
+ function installCommand(manager, frozen) {
134
+ if (manager === 'pnpm')
135
+ return frozen ? 'pnpm install --frozen-lockfile' : 'pnpm install';
136
+ if (manager === 'yarn')
137
+ return frozen ? 'yarn install --frozen-lockfile' : 'yarn install';
138
+ return frozen ? 'npm ci' : 'npm install';
139
+ }
140
+ /** How to run the `checkup` script. */
141
+ function runScriptCommand(manager) {
142
+ return manager === 'npm' ? 'npm run checkup' : `${manager} checkup`;
143
+ }
144
+ /** How CI runs the installed binary. */
145
+ function binCommand(manager) {
146
+ if (manager === 'pnpm')
147
+ return 'pnpm exec ng-checkup';
148
+ if (manager === 'yarn')
149
+ return 'yarn ng-checkup';
150
+ return 'npx ng-checkup';
151
+ }
152
+ /** The CI invocation: fail on a poor area, keep both report formats. */
153
+ function ciRun(manager) {
154
+ return `${binCommand(manager)} --fail-on poor ${CI_REPORTS.map((report) => `--report ${report}`).join(' ')}`;
155
+ }
156
+ /** A GitHub Actions workflow for the repository's package manager. */
157
+ export function githubWorkflow(manager) {
158
+ const pnpmSetup = manager === 'pnpm' ? ' - uses: pnpm/action-setup@v4\n' : '';
159
+ return `# Added by ng-checkup init. Grades the Angular codebase on every pull request
160
+ # and fails the job when an area turns poor. Reports: see the run's artifacts.
161
+ name: ng-checkup
162
+
163
+ on:
164
+ pull_request:
165
+ push:
166
+ branches: [main]
167
+
168
+ jobs:
169
+ checkup:
170
+ runs-on: ubuntu-latest
171
+ steps:
172
+ - uses: actions/checkout@v4
173
+ ${pnpmSetup} - uses: actions/setup-node@v4
174
+ with:
175
+ node-version: 22
176
+ cache: ${manager}
177
+ - run: ${installCommand(manager, true)}
178
+ - run: ${ciRun(manager)}
179
+ - uses: actions/upload-artifact@v4
180
+ if: always()
181
+ with:
182
+ name: ng-checkup
183
+ path: |
184
+ ${CI_REPORTS.map((report) => ` ${report}`).join('\n')}
185
+ `;
186
+ }
187
+ /** A GitLab CI job file for the repository's package manager, meant to be `include`d. */
188
+ export function gitlabJob(manager) {
189
+ const corepack = manager === 'pnpm' ? ' - corepack enable\n' : '';
190
+ return `# Added by ng-checkup init. Include it from .gitlab-ci.yml:
191
+ # include:
192
+ # - local: ng-checkup.gitlab-ci.yml
193
+ ng-checkup:
194
+ image: node:22
195
+ script:
196
+ ${corepack} - ${installCommand(manager, true)}
197
+ - ${ciRun(manager)}
198
+ artifacts:
199
+ when: always
200
+ expose_as: ng-checkup report
201
+ paths:
202
+ ${CI_REPORTS.map((report) => ` - ${report}`).join('\n')}
203
+ `;
204
+ }
205
+ /**
206
+ * Serialises `value` with the indentation and final newline of `original`,
207
+ * so `init` changes only the lines it means to and a `git diff` of
208
+ * `package.json` shows exactly the added keys.
209
+ */
210
+ export function formatJsonLike(original, value) {
211
+ const indent = /^[{[]\r?\n([ \t]+)/.exec(original)?.[1] ?? ' ';
212
+ const newline = original.includes('\r\n') ? '\r\n' : '\n';
213
+ const body = JSON.stringify(value, null, indent).replace(/\n/g, newline);
214
+ return original.endsWith('\n') ? `${body}${newline}` : body;
215
+ }
216
+ /** Narrows an unknown JSON value to an object, treating anything else as empty. */
217
+ function asRecord(value) {
218
+ return typeof value === 'object' && value !== null && !Array.isArray(value) ? value : {};
219
+ }
220
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAuD1C,iGAAiG;AACjG,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,4FAA4F;AAC5F,MAAM,YAAY,GAAG,cAAc,CAAC;AACpC,MAAM,UAAU,GAAG,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAqB,EAAE,OAAoB;IAClE,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,cAAc,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAEnD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/C,IAAI,WAAW,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACjI,IAAI,WAAoC,CAAC;IACzC,IAAI,CAAC;QACH,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAA4B,CAAC;IACnE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/G,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,QAAQ,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,eAAe,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,eAAe,IAAI,eAAe,CAAC,EAAE,CAAC;QAC7I,KAAK,CAAC,IAAI,CAAC,sJAAsJ,CAAC,CAAC;IACrK,CAAC;IAED,sDAAsD;IACtD,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,cAAc,KAAK,SAAS,IAAI,CAAC,cAAc,KAAK,cAAc,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzF,OAAO,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC;QACpC,WAAW,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC;QACjC,cAAc,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,cAAc,KAAK,cAAc,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,wCAAwC,MAAM,CAAC,cAAc,CAAC,2CAA2C,cAAc,IAAI,CAAC,CAAC;IAC1I,CAAC;IACD,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC;IACpD,IAAI,aAAa,IAAI,CAAC,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,YAAY,IAAI,eAAe,CAAC,EAAE,CAAC;QAC3F,WAAW,CAAC,iBAAiB,CAAC,GAAG,EAAE,GAAG,eAAe,EAAE,YAAY,EAAE,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7F,cAAc,GAAG,IAAI,CAAC;QACtB,YAAY,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,OAAO,qBAAqB,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7J,CAAC;IAED,sBAAsB;IACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;YAChF,OAAO,EAAE,UAAU,YAAY,wDAAwD;SACxF,CAAC,CAAC;IACL,CAAC;IAED,mDAAmD;IACnD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7J,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,SAAS,GAAG,SAAS,2BAA2B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,wCAAwC,EAAE,CAAC,CAAC;QAChM,CAAC;IACH,CAAC;IAED,SAAS;IACT,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC;IAClD,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,kCAAkC,CAAC;QAChD,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;;YAC5D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,gEAAgE,EAAE,CAAC,CAAC;IACpK,CAAC;SAAM,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,0BAA0B,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;;YAC5D,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,0EAA0E,EAAE,CAAC,CAAC;QACvK,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,4EAA4E,IAAI,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;SAAM,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,MAAM,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,+GAA+G,CAAC,CAAC;IAC9H,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,cAAc,IAAI,aAAa;QAAE,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;IAC3F,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAAC;IACjD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC;AAC3D,CAAC;AAED,yEAAyE;AACzE,SAAS,SAAS,CAAC,KAAqB,EAAE,MAAgB;IACxD,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACrC,IAAI,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,KAAqB;IACxD,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC;QAAE,OAAO,MAAM,CAAC;IAClD,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;QAAE,OAAO,MAAM,CAAC;IAC7C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,oFAAoF;AACpF,SAAS,cAAc,CAAC,OAAuB,EAAE,MAAe;IAC9D,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1F,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1F,OAAO,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;AAC3C,CAAC;AAED,uCAAuC;AACvC,SAAS,gBAAgB,CAAC,OAAuB;IAC/C,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,UAAU,CAAC;AACtE,CAAC;AAED,wCAAwC;AACxC,SAAS,UAAU,CAAC,OAAuB;IACzC,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,sBAAsB,CAAC;IACtD,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,iBAAiB,CAAC;IACjD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,wEAAwE;AACxE,SAAS,KAAK,CAAC,OAAuB;IACpC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,mBAAmB,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC/G,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,MAAM,SAAS,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,OAAO;;;;;;;;;;;;;;EAcP,SAAS;;;mBAGQ,OAAO;eACX,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;eAC7B,KAAK,CAAC,OAAO,CAAC;;;;;;EAM3B,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;CAC/D,CAAC;AACF,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,SAAS,CAAC,OAAuB;IAC/C,MAAM,QAAQ,GAAG,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,OAAO;;;;;;EAMP,QAAQ,SAAS,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;QACxC,KAAK,CAAC,OAAO,CAAC;;;;;EAKpB,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;CAC3D,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,KAAc;IAC7D,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAChE,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzE,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED,mFAAmF;AACnF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAiC,CAAC,CAAC,CAAC,EAAE,CAAC;AACxH,CAAC"}
package/dist/types.d.ts CHANGED
@@ -92,4 +92,6 @@ export interface CheckupOptions {
92
92
  offline?: boolean;
93
93
  /** How many example locations a finding lists. Defaults to 5. */
94
94
  maxExamples?: number;
95
+ /** Paths to leave out, as in the config file's `ignore` (see `ignoreMatcher`). */
96
+ ignore?: string[];
95
97
  }
@@ -27,6 +27,12 @@ export interface WorkspaceInfo {
27
27
  /** From `installed` when present, else from `declared`. Absent when Angular is not a dependency. */
28
28
  major?: number;
29
29
  };
30
+ /**
31
+ * The project's TypeScript major, installed version first, then the
32
+ * `package.json` range. It decides what an absent `strict` means: on from
33
+ * TypeScript 6, off before.
34
+ */
35
+ typescriptMajor?: number;
30
36
  targets: TargetInfo[];
31
37
  /** Every polyfill entry of every target, which is where `zone.js` is wired in for CLI 15+ projects. */
32
38
  polyfills: string[];
package/dist/workspace.js CHANGED
@@ -31,6 +31,7 @@ export function readWorkspace(root, projectJsons) {
31
31
  dependencies,
32
32
  hasNodeModules: installed !== undefined,
33
33
  angular: { declared, installed, major: majorOf(installed ?? declared) },
34
+ typescriptMajor: majorOf(readInstalledVersion(root, 'typescript') ?? dependencies['typescript']),
34
35
  targets,
35
36
  polyfills: targets.flatMap((target) => polyfillsOf(target.options)),
36
37
  appTsconfig: findAppTsconfig(root, targets),
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-checkup",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A one-minute modernization report for any Angular codebase: version gap, deprecated APIs, zoneless readiness, signals adoption, test runner, type safety and circular dependencies.",
5
5
  "keywords": [
6
6
  "angular",
@@ -28,14 +28,21 @@
28
28
  },
29
29
  "main": "dist/index.js",
30
30
  "types": "dist/index.d.ts",
31
+ "schematics": "./schematics/collection.json",
32
+ "ng-add": {
33
+ "save": "devDependencies"
34
+ },
31
35
  "exports": {
32
36
  ".": {
33
37
  "types": "./dist/index.d.ts",
34
38
  "default": "./dist/index.js"
35
- }
39
+ },
40
+ "./package.json": "./package.json",
41
+ "./schematics/*": "./schematics/*"
36
42
  },
37
43
  "files": [
38
- "dist"
44
+ "dist",
45
+ "schematics"
39
46
  ],
40
47
  "engines": {
41
48
  "node": ">=22"
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
3
+ "schematics": {
4
+ "ng-add": {
5
+ "description": "Sets up ng-checkup: a checkup script, a config file and a CI step.",
6
+ "factory": "./ng-add/index.cjs#ngAdd",
7
+ "schema": "./ng-add/schema.json"
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+ /**
3
+ * `ng add ng-checkup`.
4
+ *
5
+ * The Angular CLI has already installed the package and saved it to
6
+ * devDependencies (see "ng-add" in package.json) by the time this runs, so the
7
+ * rule only applies the same plan `ng-checkup init` does, through the CLI's
8
+ * virtual tree: nothing is written unless the whole schematic succeeds, and
9
+ * `ng add --dry-run` shows the changes for free.
10
+ *
11
+ * Written as CommonJS on purpose. The Angular CLI loads schematic factories
12
+ * with `require`, while the rest of this package is ESM; the planner is
13
+ * therefore loaded with a dynamic `import()`, which a CommonJS module may do
14
+ * and which Angular's rule runner awaits.
15
+ *
16
+ * It deliberately depends on nothing from @angular-devkit: the Tree and
17
+ * context are passed in by the CLI, so the package needs no schematics
18
+ * dependency of its own.
19
+ */
20
+ const { join } = require('node:path');
21
+ const { pathToFileURL } = require('node:url');
22
+
23
+ /**
24
+ * @param {{ ci?: 'auto' | 'github' | 'gitlab' | 'none', force?: boolean }} options
25
+ */
26
+ function ngAdd(options) {
27
+ return async (tree, context) => {
28
+ const { planInit } = await import(pathToFileURL(join(__dirname, '..', '..', 'dist', 'init.js')).href);
29
+ const { version } = require(join(__dirname, '..', '..', 'package.json'));
30
+
31
+ const plan = planInit(
32
+ {
33
+ read: (path) => {
34
+ const buffer = tree.read(`/${path}`);
35
+ return buffer ? buffer.toString('utf8') : undefined;
36
+ },
37
+ exists: (path) => {
38
+ if (tree.exists(`/${path}`)) return true;
39
+ // Tree.exists only knows files; a directory exists when it holds something.
40
+ const directory = tree.getDir(`/${path}`);
41
+ return directory.subfiles.length > 0 || directory.subdirs.length > 0;
42
+ },
43
+ },
44
+ { ci: options.ci ?? 'auto', force: options.force ?? false, addDependency: false, version },
45
+ );
46
+
47
+ for (const change of plan.changes) {
48
+ const path = `/${change.path}`;
49
+ if (tree.exists(path)) tree.overwrite(path, change.content);
50
+ else tree.create(path, change.content);
51
+ context.logger.info(`ng-checkup: ${change.path}: ${change.summary}`);
52
+ }
53
+ if (plan.changes.length === 0) context.logger.info('ng-checkup is already configured here.');
54
+ for (const note of plan.notes) context.logger.warn(note);
55
+ context.logger.info(`Run the checkup with: ${plan.nextSteps[plan.nextSteps.length - 1]}`);
56
+ return tree;
57
+ };
58
+ }
59
+
60
+ module.exports = { ngAdd };
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "NgCheckupNgAdd",
4
+ "title": "ng-checkup ng-add",
5
+ "type": "object",
6
+ "properties": {
7
+ "ci": {
8
+ "type": "string",
9
+ "enum": ["auto", "github", "gitlab", "none"],
10
+ "default": "auto",
11
+ "description": "Where to add the CI step. auto uses GitHub when .github/ exists, GitLab when .gitlab-ci.yml does.",
12
+ "x-prompt": {
13
+ "message": "Add a CI step that runs the checkup on every pull request?",
14
+ "type": "list",
15
+ "items": [
16
+ { "value": "auto", "label": "Yes, for the CI this repository already uses" },
17
+ { "value": "github", "label": "Yes, GitHub Actions" },
18
+ { "value": "gitlab", "label": "Yes, GitLab CI" },
19
+ { "value": "none", "label": "No" }
20
+ ]
21
+ }
22
+ },
23
+ "force": {
24
+ "type": "boolean",
25
+ "default": false,
26
+ "description": "Replace an existing \"checkup\" script."
27
+ }
28
+ }
29
+ }