ras-stack 0.22.0 → 0.23.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/README.md +11 -1
- package/dist/policy/cli.js +9 -4
- package/dist/policy/cli.js.map +1 -1
- package/dist/policy/index.d.ts +1 -0
- package/dist/policy/index.js +61 -0
- package/dist/policy/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -346,7 +346,13 @@ Policy files which cannot inherit can stay committed while being checked against
|
|
|
346
346
|
}
|
|
347
347
|
},
|
|
348
348
|
"dependabot": true,
|
|
349
|
-
"pnpm": {}
|
|
349
|
+
"pnpm": {},
|
|
350
|
+
"adoption": {
|
|
351
|
+
"minimumRasStackVersion": "0.22.0",
|
|
352
|
+
"node": ">=24 <25",
|
|
353
|
+
"pnpm": "11.15.0",
|
|
354
|
+
"just": "1.58.0"
|
|
355
|
+
}
|
|
350
356
|
}
|
|
351
357
|
```
|
|
352
358
|
|
|
@@ -355,10 +361,14 @@ Then generate or verify the effective files:
|
|
|
355
361
|
```sh
|
|
356
362
|
pnpm exec ras-stack-policy sync
|
|
357
363
|
pnpm exec ras-stack-policy check
|
|
364
|
+
pnpm exec ras-stack-policy sync adoption
|
|
365
|
+
pnpm exec ras-stack-policy check adoption
|
|
358
366
|
```
|
|
359
367
|
|
|
360
368
|
`changesets` and `dependabot` produce deterministic complete files, with optional deep overrides. The pnpm policy changes only `minimumReleaseAge` in the existing `pnpm-workspace.yaml`, preserving local package layout, build approvals, dependency overrides, exclusions, and comments. Its default is seven days; set `"minimumReleaseAge": 0` only as an explicit repository exception. Commit both the selection and generated files so policy changes remain visible in review.
|
|
361
369
|
|
|
370
|
+
Adoption synchronization updates older ras-stack package and workflow references plus the declared Node, pnpm, and Just versions. It preserves package range style, explicit workflow-version exceptions, newer ras-stack versions, application dependencies, and workflow structure. Check mode reports the exact files that would change without writing them. Shared config references remain check-only because adding them requires application-specific include paths and overrides.
|
|
371
|
+
|
|
362
372
|
The same adoption policy can produce a read-only fleet report from public repository metadata. Declare each repository's supported versions and required shared config references in `ras-stack.fleet.json`, then run:
|
|
363
373
|
|
|
364
374
|
```sh
|
package/dist/policy/cli.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import { fleetConfig, fleetMarkdown, inspectFleet } from './fleet.js';
|
|
5
|
-
import { checkRepositoryPolicy, syncRepositoryPolicy } from './index.js';
|
|
5
|
+
import { checkRepositoryPolicy, syncAdoptionPolicy, syncRepositoryPolicy } from './index.js';
|
|
6
6
|
const command = process.argv[2];
|
|
7
7
|
if (command !== 'check' && command !== 'sync' && command !== 'fleet') {
|
|
8
|
-
console.error('usage: ras-stack-policy <check|sync|fleet>');
|
|
8
|
+
console.error('usage: ras-stack-policy <check|sync|fleet> [adoption]');
|
|
9
9
|
process.exitCode = 2;
|
|
10
10
|
}
|
|
11
11
|
else if (command === 'fleet') {
|
|
@@ -17,11 +17,16 @@ else if (command === 'fleet') {
|
|
|
17
17
|
process.exitCode = 1;
|
|
18
18
|
}
|
|
19
19
|
else {
|
|
20
|
-
const
|
|
20
|
+
const adoption = process.argv[3] === 'adoption';
|
|
21
|
+
const changed = adoption
|
|
22
|
+
? await syncAdoptionPolicy(process.cwd(), command === 'check' ? 'check' : 'write')
|
|
23
|
+
: command === 'check'
|
|
24
|
+
? await checkRepositoryPolicy(process.cwd())
|
|
25
|
+
: await syncRepositoryPolicy(process.cwd(), 'write');
|
|
21
26
|
if (command === 'check' && changed.length > 0) {
|
|
22
27
|
for (const message of changed)
|
|
23
28
|
console.error(message);
|
|
24
|
-
console.error(
|
|
29
|
+
console.error(`run ras-stack-policy sync${adoption ? ' adoption' : ''} and commit the result`);
|
|
25
30
|
process.exitCode = 1;
|
|
26
31
|
}
|
|
27
32
|
else if (command === 'sync') {
|
package/dist/policy/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/policy/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/policy/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAE5F,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAC/B,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IACrE,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAA;IACtE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC;KAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC,CAAA;IAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAA;IAC5C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AAC7E,CAAC;KAAM,CAAC;IACN,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,CAAA;IAC/C,MAAM,OAAO,GAAG,QAAQ;QACtB,CAAC,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAClF,CAAC,CAAC,OAAO,KAAK,OAAO;YACnB,CAAC,CAAC,MAAM,qBAAqB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC5C,CAAC,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;IACxD,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,KAAK,MAAM,OAAO,IAAI,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrD,OAAO,CAAC,KAAK,CAAC,4BAA4B,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAA;QAC9F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;IACtB,CAAC;SAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { fleetConfig, fleetMarkdown, inspectFleet } from './fleet.js'\nimport { checkRepositoryPolicy, syncAdoptionPolicy, syncRepositoryPolicy } from './index.js'\n\nconst command = process.argv[2]\nif (command !== 'check' && command !== 'sync' && command !== 'fleet') {\n console.error('usage: ras-stack-policy <check|sync|fleet> [adoption]')\n process.exitCode = 2\n} else if (command === 'fleet') {\n const path = resolve(process.argv[3] ?? 'ras-stack.fleet.json')\n const config = fleetConfig(JSON.parse(await readFile(path, 'utf8')))\n const results = await inspectFleet(config)\n process.stdout.write(fleetMarkdown(results))\n if (results.some((result) => result.drift.length > 0)) process.exitCode = 1\n} else {\n const adoption = process.argv[3] === 'adoption'\n const changed = adoption\n ? await syncAdoptionPolicy(process.cwd(), command === 'check' ? 'check' : 'write')\n : command === 'check'\n ? await checkRepositoryPolicy(process.cwd())\n : await syncRepositoryPolicy(process.cwd(), 'write')\n if (command === 'check' && changed.length > 0) {\n for (const message of changed) console.error(message)\n console.error(`run ras-stack-policy sync${adoption ? ' adoption' : ''} and commit the result`)\n process.exitCode = 1\n } else if (command === 'sync') {\n for (const path of changed) console.log(`updated ${path}`)\n }\n}\n"]}
|
package/dist/policy/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type AdoptionSnapshot = {
|
|
|
25
25
|
};
|
|
26
26
|
export declare function syncRepositoryPolicy(root: string, mode: 'check' | 'write'): Promise<string[]>;
|
|
27
27
|
export declare function checkRepositoryPolicy(root: string): Promise<string[]>;
|
|
28
|
+
export declare function syncAdoptionPolicy(root: string, mode: 'check' | 'write'): Promise<string[]>;
|
|
28
29
|
export declare function adoptionDrift(root: string, policy: AdoptionPolicy): Promise<string[]>;
|
|
29
30
|
export declare function adoptionSnapshotDrift(snapshot: AdoptionSnapshot, policy: AdoptionPolicy): string[];
|
|
30
31
|
export declare function renderedPolicyFiles(root: string, config: RepositoryPolicy): Promise<Map<string, string>>;
|
package/dist/policy/index.js
CHANGED
|
@@ -52,6 +52,22 @@ export async function checkRepositoryPolicy(root) {
|
|
|
52
52
|
const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'));
|
|
53
53
|
return [...files.map((path) => `policy drift: ${path}`), ...(config.adoption ? await adoptionDrift(root, config.adoption) : [])];
|
|
54
54
|
}
|
|
55
|
+
export async function syncAdoptionPolicy(root, mode) {
|
|
56
|
+
const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'));
|
|
57
|
+
if (!config.adoption)
|
|
58
|
+
return [];
|
|
59
|
+
const files = await renderedAdoptionFiles(root, config.adoption);
|
|
60
|
+
const changed = await Promise.all([...files].map(async ([path, expected]) => {
|
|
61
|
+
const absolute = join(root, path);
|
|
62
|
+
const actual = await readFile(absolute, 'utf8');
|
|
63
|
+
if (actual === expected)
|
|
64
|
+
return undefined;
|
|
65
|
+
if (mode === 'write')
|
|
66
|
+
await writeFile(absolute, expected);
|
|
67
|
+
return path;
|
|
68
|
+
}));
|
|
69
|
+
return changed.filter((path) => path !== undefined);
|
|
70
|
+
}
|
|
55
71
|
export async function adoptionDrift(root, policy) {
|
|
56
72
|
const manifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8'));
|
|
57
73
|
const files = await adoptionFiles(root);
|
|
@@ -185,6 +201,51 @@ async function adoptionFiles(root) {
|
|
|
185
201
|
}));
|
|
186
202
|
return files;
|
|
187
203
|
}
|
|
204
|
+
async function renderedAdoptionFiles(root, policy) {
|
|
205
|
+
const files = new Map();
|
|
206
|
+
const manifestPath = join(root, 'package.json');
|
|
207
|
+
const manifestSource = await readFile(manifestPath, 'utf8');
|
|
208
|
+
const manifest = JSON.parse(manifestSource);
|
|
209
|
+
if (policy.node) {
|
|
210
|
+
const engines = plainObject(manifest.engines) ? manifest.engines : {};
|
|
211
|
+
manifest.engines = { ...engines, node: policy.node };
|
|
212
|
+
}
|
|
213
|
+
if (policy.pnpm)
|
|
214
|
+
manifest.packageManager = `pnpm@${policy.pnpm}`;
|
|
215
|
+
if (policy.minimumRasStackVersion) {
|
|
216
|
+
for (const field of ['dependencies', 'devDependencies']) {
|
|
217
|
+
const dependencies = manifest[field];
|
|
218
|
+
if (!plainObject(dependencies) || typeof dependencies['ras-stack'] !== 'string')
|
|
219
|
+
continue;
|
|
220
|
+
dependencies['ras-stack'] = versionAtLeast(dependencies['ras-stack'], policy.minimumRasStackVersion);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const renderedManifest = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
224
|
+
if (renderedManifest !== manifestSource)
|
|
225
|
+
files.set('package.json', renderedManifest);
|
|
226
|
+
const workflowVersion = policy.minimumWorkflowRasStackVersion ?? policy.minimumRasStackVersion;
|
|
227
|
+
const workflows = await textFiles(join(root, '.github'), root);
|
|
228
|
+
for (const [path, source] of workflows) {
|
|
229
|
+
let rendered = source;
|
|
230
|
+
if (workflowVersion) {
|
|
231
|
+
rendered = rendered.replace(/(richardsolomou\/ras-stack\/[^\s'"}]+@v)(\d+\.\d+\.\d+)/g, (reference, prefix, current) => compareVersions(current, workflowVersion) < 0 ? `${prefix}${workflowVersion}` : reference);
|
|
232
|
+
}
|
|
233
|
+
if (policy.just) {
|
|
234
|
+
rendered = rendered.replace(/(just-version:\s*)(['"]?)\d+\.\d+\.\d+\2/g, `$1$2${policy.just}$2`);
|
|
235
|
+
rendered = rendered.replace(/(richardsolomou\/ras-stack\/actions\/setup-just@[^\n]+\n(?:(?!\n\s*-\s+uses:)[\s\S]){0,300}?\n\s+version:\s*)(['"]?)\d+\.\d+\.\d+\2/g, `$1$2${policy.just}$2`);
|
|
236
|
+
}
|
|
237
|
+
if (rendered !== source)
|
|
238
|
+
files.set(path, rendered);
|
|
239
|
+
}
|
|
240
|
+
return files;
|
|
241
|
+
}
|
|
242
|
+
function versionAtLeast(current, version) {
|
|
243
|
+
const match = /^(\s*(?:\^|~|>=|>|<=|<|=)?\s*)\d+\.\d+\.\d+(.*)$/.exec(current);
|
|
244
|
+
const currentVersion = /\d+\.\d+\.\d+/.exec(current)?.[0];
|
|
245
|
+
if (currentVersion && compareVersions(currentVersion, version) >= 0)
|
|
246
|
+
return current;
|
|
247
|
+
return match ? `${match[1]}${version}${match[2]}` : version;
|
|
248
|
+
}
|
|
188
249
|
function validateSelection(name, value) {
|
|
189
250
|
if (value === undefined || typeof value === 'boolean')
|
|
190
251
|
return;
|
package/dist/policy/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { parseDocument, stringify } from 'yaml'\n\nexport { fleetConfig, fleetMarkdown, inspectFleet, loadGitHubAdoptionSnapshot } from './fleet.js'\nexport type { FleetConfig, FleetRepository, FleetResult } from './fleet.js'\n\nconst changesetsPolicy = {\n $schema: 'https://unpkg.com/@changesets/config@3.1.2/schema.json',\n changelog: '@changesets/cli/changelog',\n commit: false,\n fixed: [],\n linked: [],\n access: 'public',\n baseBranch: 'main',\n updateInternalDependencies: 'patch',\n ignore: [],\n}\n\nconst dependabotPolicy = {\n version: 2,\n updates: [\n {\n 'package-ecosystem': 'npm',\n directory: '/',\n schedule: { interval: 'weekly' },\n cooldown: { 'default-days': 7 },\n groups: { 'javascript-dependencies': { patterns: ['*'] } },\n },\n {\n 'package-ecosystem': 'github-actions',\n directory: '/',\n schedule: { interval: 'weekly' },\n cooldown: { 'default-days': 7 },\n },\n ],\n}\n\ntype PolicySelection = boolean | { overrides?: Record<string, unknown> }\n\nexport type RepositoryPolicy = {\n changesets?: PolicySelection\n dependabot?: PolicySelection\n pnpm?: false | { minimumReleaseAge?: number }\n adoption?: false | AdoptionPolicy\n}\n\nexport type AdoptionPolicy = {\n minimumRasStackVersion?: string\n minimumWorkflowRasStackVersion?: string\n node?: string\n pnpm?: string\n just?: string\n requiredReferences?: string[]\n}\n\nexport type AdoptionSnapshot = {\n manifest: Record<string, unknown>\n files: Map<string, string>\n}\n\nexport async function syncRepositoryPolicy(root: string, mode: 'check' | 'write') {\n const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'))\n const files = await renderedPolicyFiles(root, config)\n const compared = await Promise.all(\n [...files].map(async ([path, expected]) => {\n const absolute = join(root, path)\n const actual = await readFile(absolute, 'utf8').catch(() => undefined)\n if (actual === expected) return undefined\n if (mode === 'write') {\n await mkdir(dirname(absolute), { recursive: true })\n await writeFile(absolute, expected)\n }\n return path\n }),\n )\n return compared.filter((path) => path !== undefined)\n}\n\nexport async function checkRepositoryPolicy(root: string) {\n const files = await syncRepositoryPolicy(root, 'check')\n const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'))\n return [...files.map((path) => `policy drift: ${path}`), ...(config.adoption ? await adoptionDrift(root, config.adoption) : [])]\n}\n\nexport async function adoptionDrift(root: string, policy: AdoptionPolicy) {\n const manifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) as Record<string, unknown>\n const files = await adoptionFiles(root)\n return adoptionSnapshotDrift({ manifest, files }, policy)\n}\n\nexport function adoptionSnapshotDrift(snapshot: AdoptionSnapshot, policy: AdoptionPolicy) {\n const drift: string[] = []\n const { manifest, files } = snapshot\n if (policy.node && manifest.engines && plainObject(manifest.engines) && manifest.engines.node !== policy.node) {\n drift.push(`toolchain drift: package.json engines.node must be ${policy.node}`)\n }\n if (policy.pnpm && manifest.packageManager !== `pnpm@${policy.pnpm}`) {\n drift.push(`toolchain drift: package.json packageManager must be pnpm@${policy.pnpm}`)\n }\n if (policy.minimumRasStackVersion) {\n const dependency = dependencyVersion(manifest, 'ras-stack')\n if (dependency && compareVersions(dependency, policy.minimumRasStackVersion) < 0) {\n drift.push(`ras-stack drift: package.json uses ${dependency}, minimum is ${policy.minimumRasStackVersion}`)\n }\n }\n\n const workflows = new Map([...files].filter(([path]) => path.startsWith('.github/') && /\\.ya?ml$/.test(path)))\n const workflowMinimum = policy.minimumWorkflowRasStackVersion ?? policy.minimumRasStackVersion\n for (const [path, source] of workflows) {\n if (workflowMinimum) {\n for (const match of source.matchAll(/richardsolomou\\/ras-stack\\/[^\\s'\"}]+@v(\\d+\\.\\d+\\.\\d+)/g)) {\n const version = match[1]\n if (version && compareVersions(version, workflowMinimum) < 0) {\n drift.push(`ras-stack drift: ${path} uses v${version}, minimum is v${workflowMinimum}`)\n }\n }\n }\n }\n if (\n policy.just &&\n ![...workflows.values()].some(\n (source) => source.includes(`just-version: '${policy.just}'`) || source.includes(`just-version: ${policy.just}`),\n )\n ) {\n drift.push(`toolchain drift: no workflow declares just-version ${policy.just}`)\n }\n for (const reference of policy.requiredReferences ?? []) {\n if (![...files.values()].some((source) => source.includes(reference))) {\n drift.push(`shared config drift: no configuration references ${reference}`)\n }\n }\n return [...new Set(drift)]\n}\n\nexport async function renderedPolicyFiles(root: string, config: RepositoryPolicy) {\n const files = new Map<string, string>()\n if (config.changesets) {\n files.set('.changeset/config.json', `${JSON.stringify(selectedPolicy(changesetsPolicy, config.changesets), null, 2)}\\n`)\n }\n if (config.dependabot) {\n files.set('.github/dependabot.yml', stringify(selectedPolicy(dependabotPolicy, config.dependabot), { lineWidth: 0, singleQuote: true }))\n }\n if (config.pnpm) {\n const path = join(root, 'pnpm-workspace.yaml')\n const document = parseDocument(await readFile(path, 'utf8').catch(() => ''))\n document.set('minimumReleaseAge', config.pnpm.minimumReleaseAge ?? 10_080)\n files.set('pnpm-workspace.yaml', document.toString({ lineWidth: 0 }))\n }\n return files\n}\n\nfunction repositoryPolicy(source: string): RepositoryPolicy {\n const value = JSON.parse(source) as unknown\n if (!plainObject(value)) throw new Error('ras-stack.policy.json must contain an object')\n for (const name of ['changesets', 'dependabot'] as const) validateSelection(name, value[name])\n const pnpm = value.pnpm\n if (pnpm !== undefined && pnpm !== false) {\n if (!plainObject(pnpm)) throw new Error('pnpm policy must be false or an object')\n const age = pnpm.minimumReleaseAge\n if (age !== undefined && (typeof age !== 'number' || !Number.isInteger(age) || age < 0)) {\n throw new Error('pnpm.minimumReleaseAge must be a non-negative integer')\n }\n }\n const adoption = value.adoption\n if (adoption !== undefined && adoption !== false) {\n if (!plainObject(adoption)) throw new Error('adoption policy must be false or an object')\n for (const key of ['minimumRasStackVersion', 'minimumWorkflowRasStackVersion', 'node', 'pnpm', 'just']) {\n if (adoption[key] !== undefined && typeof adoption[key] !== 'string') throw new Error(`adoption.${key} must be a string`)\n }\n if (adoption.requiredReferences !== undefined && !stringArray(adoption.requiredReferences)) {\n throw new Error('adoption.requiredReferences must be an array of strings')\n }\n }\n return value\n}\n\nfunction dependencyVersion(manifest: Record<string, unknown>, name: string) {\n for (const field of ['dependencies', 'devDependencies']) {\n const dependencies = manifest[field]\n const value = plainObject(dependencies) ? dependencies[name] : undefined\n if (typeof value === 'string') return /\\d+\\.\\d+\\.\\d+/.exec(value)?.[0]\n }\n return undefined\n}\n\nfunction compareVersions(left: string, right: string) {\n const a = left.split('.').map(Number)\n const b = right.split('.').map(Number)\n for (let index = 0; index < 3; index += 1) {\n if (a[index] !== b[index]) return (a[index] ?? 0) - (b[index] ?? 0)\n }\n return 0\n}\n\nasync function textFiles(directory: string, root = directory): Promise<Map<string, string>> {\n const files = new Map<string, string>()\n const entries = await readdir(directory, { withFileTypes: true }).catch(() => [])\n const results = await Promise.all(\n entries.map(async (entry) => {\n const path = join(directory, entry.name)\n if (entry.isDirectory()) return textFiles(path, root)\n if (/\\.ya?ml$/.test(entry.name)) return new Map([[path.slice(root.length + 1), await readFile(path, 'utf8')]])\n return new Map<string, string>()\n }),\n )\n for (const result of results) {\n for (const [path, source] of result) files.set(path, source)\n }\n return files\n}\n\nasync function adoptionFiles(root: string) {\n const files = await textFiles(join(root, '.github'), root)\n const entries = await readdir(root, { withFileTypes: true })\n await Promise.all(\n entries.map(async (entry) => {\n if (!entry.isFile() || !/^(?:ras-stack\\.policy|oxlint|tsconfig(?:\\.[^.]+)*)\\.json$/.test(entry.name)) return\n files.set(entry.name, await readFile(join(root, entry.name), 'utf8'))\n }),\n )\n return files\n}\n\nfunction validateSelection(name: string, value: unknown) {\n if (value === undefined || typeof value === 'boolean') return\n if (!plainObject(value) || (value.overrides !== undefined && !plainObject(value.overrides))) {\n throw new Error(`${name} policy must be a boolean or an object with overrides`)\n }\n}\n\nfunction selectedPolicy(base: Record<string, unknown>, selection: Exclude<PolicySelection, false>) {\n return selection === true ? base : deepMerge(base, selection.overrides ?? {})\n}\n\nfunction deepMerge(base: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n [...new Set([...Object.keys(base), ...Object.keys(overrides)])].map((key) => {\n const left = base[key]\n const right = overrides[key]\n return [key, plainObject(left) && plainObject(right) ? deepMerge(left, right) : right === undefined ? left : right]\n }),\n )\n}\n\nfunction plainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction stringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string')\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { parseDocument, stringify } from 'yaml'\n\nexport { fleetConfig, fleetMarkdown, inspectFleet, loadGitHubAdoptionSnapshot } from './fleet.js'\nexport type { FleetConfig, FleetRepository, FleetResult } from './fleet.js'\n\nconst changesetsPolicy = {\n $schema: 'https://unpkg.com/@changesets/config@3.1.2/schema.json',\n changelog: '@changesets/cli/changelog',\n commit: false,\n fixed: [],\n linked: [],\n access: 'public',\n baseBranch: 'main',\n updateInternalDependencies: 'patch',\n ignore: [],\n}\n\nconst dependabotPolicy = {\n version: 2,\n updates: [\n {\n 'package-ecosystem': 'npm',\n directory: '/',\n schedule: { interval: 'weekly' },\n cooldown: { 'default-days': 7 },\n groups: { 'javascript-dependencies': { patterns: ['*'] } },\n },\n {\n 'package-ecosystem': 'github-actions',\n directory: '/',\n schedule: { interval: 'weekly' },\n cooldown: { 'default-days': 7 },\n },\n ],\n}\n\ntype PolicySelection = boolean | { overrides?: Record<string, unknown> }\n\nexport type RepositoryPolicy = {\n changesets?: PolicySelection\n dependabot?: PolicySelection\n pnpm?: false | { minimumReleaseAge?: number }\n adoption?: false | AdoptionPolicy\n}\n\nexport type AdoptionPolicy = {\n minimumRasStackVersion?: string\n minimumWorkflowRasStackVersion?: string\n node?: string\n pnpm?: string\n just?: string\n requiredReferences?: string[]\n}\n\nexport type AdoptionSnapshot = {\n manifest: Record<string, unknown>\n files: Map<string, string>\n}\n\nexport async function syncRepositoryPolicy(root: string, mode: 'check' | 'write') {\n const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'))\n const files = await renderedPolicyFiles(root, config)\n const compared = await Promise.all(\n [...files].map(async ([path, expected]) => {\n const absolute = join(root, path)\n const actual = await readFile(absolute, 'utf8').catch(() => undefined)\n if (actual === expected) return undefined\n if (mode === 'write') {\n await mkdir(dirname(absolute), { recursive: true })\n await writeFile(absolute, expected)\n }\n return path\n }),\n )\n return compared.filter((path) => path !== undefined)\n}\n\nexport async function checkRepositoryPolicy(root: string) {\n const files = await syncRepositoryPolicy(root, 'check')\n const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'))\n return [...files.map((path) => `policy drift: ${path}`), ...(config.adoption ? await adoptionDrift(root, config.adoption) : [])]\n}\n\nexport async function syncAdoptionPolicy(root: string, mode: 'check' | 'write') {\n const config = repositoryPolicy(await readFile(join(root, 'ras-stack.policy.json'), 'utf8'))\n if (!config.adoption) return []\n const files = await renderedAdoptionFiles(root, config.adoption)\n const changed = await Promise.all(\n [...files].map(async ([path, expected]) => {\n const absolute = join(root, path)\n const actual = await readFile(absolute, 'utf8')\n if (actual === expected) return undefined\n if (mode === 'write') await writeFile(absolute, expected)\n return path\n }),\n )\n return changed.filter((path) => path !== undefined)\n}\n\nexport async function adoptionDrift(root: string, policy: AdoptionPolicy) {\n const manifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) as Record<string, unknown>\n const files = await adoptionFiles(root)\n return adoptionSnapshotDrift({ manifest, files }, policy)\n}\n\nexport function adoptionSnapshotDrift(snapshot: AdoptionSnapshot, policy: AdoptionPolicy) {\n const drift: string[] = []\n const { manifest, files } = snapshot\n if (policy.node && manifest.engines && plainObject(manifest.engines) && manifest.engines.node !== policy.node) {\n drift.push(`toolchain drift: package.json engines.node must be ${policy.node}`)\n }\n if (policy.pnpm && manifest.packageManager !== `pnpm@${policy.pnpm}`) {\n drift.push(`toolchain drift: package.json packageManager must be pnpm@${policy.pnpm}`)\n }\n if (policy.minimumRasStackVersion) {\n const dependency = dependencyVersion(manifest, 'ras-stack')\n if (dependency && compareVersions(dependency, policy.minimumRasStackVersion) < 0) {\n drift.push(`ras-stack drift: package.json uses ${dependency}, minimum is ${policy.minimumRasStackVersion}`)\n }\n }\n\n const workflows = new Map([...files].filter(([path]) => path.startsWith('.github/') && /\\.ya?ml$/.test(path)))\n const workflowMinimum = policy.minimumWorkflowRasStackVersion ?? policy.minimumRasStackVersion\n for (const [path, source] of workflows) {\n if (workflowMinimum) {\n for (const match of source.matchAll(/richardsolomou\\/ras-stack\\/[^\\s'\"}]+@v(\\d+\\.\\d+\\.\\d+)/g)) {\n const version = match[1]\n if (version && compareVersions(version, workflowMinimum) < 0) {\n drift.push(`ras-stack drift: ${path} uses v${version}, minimum is v${workflowMinimum}`)\n }\n }\n }\n }\n if (\n policy.just &&\n ![...workflows.values()].some(\n (source) => source.includes(`just-version: '${policy.just}'`) || source.includes(`just-version: ${policy.just}`),\n )\n ) {\n drift.push(`toolchain drift: no workflow declares just-version ${policy.just}`)\n }\n for (const reference of policy.requiredReferences ?? []) {\n if (![...files.values()].some((source) => source.includes(reference))) {\n drift.push(`shared config drift: no configuration references ${reference}`)\n }\n }\n return [...new Set(drift)]\n}\n\nexport async function renderedPolicyFiles(root: string, config: RepositoryPolicy) {\n const files = new Map<string, string>()\n if (config.changesets) {\n files.set('.changeset/config.json', `${JSON.stringify(selectedPolicy(changesetsPolicy, config.changesets), null, 2)}\\n`)\n }\n if (config.dependabot) {\n files.set('.github/dependabot.yml', stringify(selectedPolicy(dependabotPolicy, config.dependabot), { lineWidth: 0, singleQuote: true }))\n }\n if (config.pnpm) {\n const path = join(root, 'pnpm-workspace.yaml')\n const document = parseDocument(await readFile(path, 'utf8').catch(() => ''))\n document.set('minimumReleaseAge', config.pnpm.minimumReleaseAge ?? 10_080)\n files.set('pnpm-workspace.yaml', document.toString({ lineWidth: 0 }))\n }\n return files\n}\n\nfunction repositoryPolicy(source: string): RepositoryPolicy {\n const value = JSON.parse(source) as unknown\n if (!plainObject(value)) throw new Error('ras-stack.policy.json must contain an object')\n for (const name of ['changesets', 'dependabot'] as const) validateSelection(name, value[name])\n const pnpm = value.pnpm\n if (pnpm !== undefined && pnpm !== false) {\n if (!plainObject(pnpm)) throw new Error('pnpm policy must be false or an object')\n const age = pnpm.minimumReleaseAge\n if (age !== undefined && (typeof age !== 'number' || !Number.isInteger(age) || age < 0)) {\n throw new Error('pnpm.minimumReleaseAge must be a non-negative integer')\n }\n }\n const adoption = value.adoption\n if (adoption !== undefined && adoption !== false) {\n if (!plainObject(adoption)) throw new Error('adoption policy must be false or an object')\n for (const key of ['minimumRasStackVersion', 'minimumWorkflowRasStackVersion', 'node', 'pnpm', 'just']) {\n if (adoption[key] !== undefined && typeof adoption[key] !== 'string') throw new Error(`adoption.${key} must be a string`)\n }\n if (adoption.requiredReferences !== undefined && !stringArray(adoption.requiredReferences)) {\n throw new Error('adoption.requiredReferences must be an array of strings')\n }\n }\n return value\n}\n\nfunction dependencyVersion(manifest: Record<string, unknown>, name: string) {\n for (const field of ['dependencies', 'devDependencies']) {\n const dependencies = manifest[field]\n const value = plainObject(dependencies) ? dependencies[name] : undefined\n if (typeof value === 'string') return /\\d+\\.\\d+\\.\\d+/.exec(value)?.[0]\n }\n return undefined\n}\n\nfunction compareVersions(left: string, right: string) {\n const a = left.split('.').map(Number)\n const b = right.split('.').map(Number)\n for (let index = 0; index < 3; index += 1) {\n if (a[index] !== b[index]) return (a[index] ?? 0) - (b[index] ?? 0)\n }\n return 0\n}\n\nasync function textFiles(directory: string, root = directory): Promise<Map<string, string>> {\n const files = new Map<string, string>()\n const entries = await readdir(directory, { withFileTypes: true }).catch(() => [])\n const results = await Promise.all(\n entries.map(async (entry) => {\n const path = join(directory, entry.name)\n if (entry.isDirectory()) return textFiles(path, root)\n if (/\\.ya?ml$/.test(entry.name)) return new Map([[path.slice(root.length + 1), await readFile(path, 'utf8')]])\n return new Map<string, string>()\n }),\n )\n for (const result of results) {\n for (const [path, source] of result) files.set(path, source)\n }\n return files\n}\n\nasync function adoptionFiles(root: string) {\n const files = await textFiles(join(root, '.github'), root)\n const entries = await readdir(root, { withFileTypes: true })\n await Promise.all(\n entries.map(async (entry) => {\n if (!entry.isFile() || !/^(?:ras-stack\\.policy|oxlint|tsconfig(?:\\.[^.]+)*)\\.json$/.test(entry.name)) return\n files.set(entry.name, await readFile(join(root, entry.name), 'utf8'))\n }),\n )\n return files\n}\n\nasync function renderedAdoptionFiles(root: string, policy: AdoptionPolicy) {\n const files = new Map<string, string>()\n const manifestPath = join(root, 'package.json')\n const manifestSource = await readFile(manifestPath, 'utf8')\n const manifest = JSON.parse(manifestSource) as Record<string, unknown>\n if (policy.node) {\n const engines = plainObject(manifest.engines) ? manifest.engines : {}\n manifest.engines = { ...engines, node: policy.node }\n }\n if (policy.pnpm) manifest.packageManager = `pnpm@${policy.pnpm}`\n if (policy.minimumRasStackVersion) {\n for (const field of ['dependencies', 'devDependencies']) {\n const dependencies = manifest[field]\n if (!plainObject(dependencies) || typeof dependencies['ras-stack'] !== 'string') continue\n dependencies['ras-stack'] = versionAtLeast(dependencies['ras-stack'], policy.minimumRasStackVersion)\n }\n }\n const renderedManifest = `${JSON.stringify(manifest, null, 2)}\\n`\n if (renderedManifest !== manifestSource) files.set('package.json', renderedManifest)\n\n const workflowVersion = policy.minimumWorkflowRasStackVersion ?? policy.minimumRasStackVersion\n const workflows = await textFiles(join(root, '.github'), root)\n for (const [path, source] of workflows) {\n let rendered = source\n if (workflowVersion) {\n rendered = rendered.replace(/(richardsolomou\\/ras-stack\\/[^\\s'\"}]+@v)(\\d+\\.\\d+\\.\\d+)/g, (reference, prefix, current) =>\n compareVersions(current, workflowVersion) < 0 ? `${prefix}${workflowVersion}` : reference,\n )\n }\n if (policy.just) {\n rendered = rendered.replace(/(just-version:\\s*)(['\"]?)\\d+\\.\\d+\\.\\d+\\2/g, `$1$2${policy.just}$2`)\n rendered = rendered.replace(\n /(richardsolomou\\/ras-stack\\/actions\\/setup-just@[^\\n]+\\n(?:(?!\\n\\s*-\\s+uses:)[\\s\\S]){0,300}?\\n\\s+version:\\s*)(['\"]?)\\d+\\.\\d+\\.\\d+\\2/g,\n `$1$2${policy.just}$2`,\n )\n }\n if (rendered !== source) files.set(path, rendered)\n }\n return files\n}\n\nfunction versionAtLeast(current: string, version: string) {\n const match = /^(\\s*(?:\\^|~|>=|>|<=|<|=)?\\s*)\\d+\\.\\d+\\.\\d+(.*)$/.exec(current)\n const currentVersion = /\\d+\\.\\d+\\.\\d+/.exec(current)?.[0]\n if (currentVersion && compareVersions(currentVersion, version) >= 0) return current\n return match ? `${match[1]}${version}${match[2]}` : version\n}\n\nfunction validateSelection(name: string, value: unknown) {\n if (value === undefined || typeof value === 'boolean') return\n if (!plainObject(value) || (value.overrides !== undefined && !plainObject(value.overrides))) {\n throw new Error(`${name} policy must be a boolean or an object with overrides`)\n }\n}\n\nfunction selectedPolicy(base: Record<string, unknown>, selection: Exclude<PolicySelection, false>) {\n return selection === true ? base : deepMerge(base, selection.overrides ?? {})\n}\n\nfunction deepMerge(base: Record<string, unknown>, overrides: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(\n [...new Set([...Object.keys(base), ...Object.keys(overrides)])].map((key) => {\n const left = base[key]\n const right = overrides[key]\n return [key, plainObject(left) && plainObject(right) ? deepMerge(left, right) : right === undefined ? left : right]\n }),\n )\n}\n\nfunction plainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction stringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string')\n}\n"]}
|