md app
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env node
|
||||
// For each npm package, prints its four newest major lines: first release,
|
||||
// latest version and when that latest version was published. A line with no
|
||||
// release for a long time has probably stopped receiving patches.
|
||||
//
|
||||
// Backs the version table in docs/GO-LIVE-PLAN.md §4. Re-run it before acting
|
||||
// on that table — the numbers there are only true for the day they were taken.
|
||||
//
|
||||
// node scripts/check-majors.mjs # the packages the plan tracks
|
||||
// node scripts/check-majors.mjs vite pinia # any packages
|
||||
//
|
||||
// Goes through the npm CLI rather than fetch() so the machine's registry or
|
||||
// mirror settings (.npmrc) apply.
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
const TRACKED = [
|
||||
'vue', 'vite', '@vitejs/plugin-vue', 'vite-plugin-pwa', 'vue-router', 'pinia',
|
||||
'typescript', 'vue-tsc', 'tailwindcss', 'ant-design-vue', 'vant', '@vueuse/core',
|
||||
'@nestjs/core', 'prisma',
|
||||
];
|
||||
// Package names only — they are interpolated into a shell command.
|
||||
const PACKAGE_NAME = /^(@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*$/i;
|
||||
const STALE_AFTER_DAYS = 180;
|
||||
|
||||
const pkgs = process.argv.length > 2 ? process.argv.slice(2) : TRACKED;
|
||||
const now = Date.now();
|
||||
|
||||
for (const pkg of pkgs) {
|
||||
if (!PACKAGE_NAME.test(pkg)) {
|
||||
console.log(`\n${pkg}: not a package name, skipped`);
|
||||
continue;
|
||||
}
|
||||
|
||||
let published;
|
||||
try {
|
||||
published = JSON.parse(
|
||||
execSync(`npm view ${pkg} time --json`, {
|
||||
encoding: 'utf8',
|
||||
timeout: 60_000,
|
||||
stdio: ['ignore', 'pipe', 'ignore'],
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
console.log(`\n${pkg}: npm view failed`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const lines = new Map();
|
||||
for (const [version, date] of Object.entries(published)) {
|
||||
// Stable releases only; this also drops the `created` / `modified` keys.
|
||||
if (!/^\d+\.\d+\.\d+$/.test(version)) continue;
|
||||
const major = Number(version.split('.')[0]);
|
||||
const line = lines.get(major) ?? { firstVersion: version, first: date, lastVersion: version, last: date };
|
||||
if (date < line.first) Object.assign(line, { firstVersion: version, first: date });
|
||||
if (date > line.last) Object.assign(line, { lastVersion: version, last: date });
|
||||
lines.set(major, line);
|
||||
}
|
||||
|
||||
console.log(`\n${pkg}`);
|
||||
const newestFirst = [...lines].sort(([a], [b]) => b - a).slice(0, 4);
|
||||
for (const [major, line] of newestFirst) {
|
||||
const idleDays = Math.floor((now - Date.parse(line.last)) / 86_400_000);
|
||||
const stale = idleDays > STALE_AFTER_DAYS ? ` <- no release for ${idleDays} days` : '';
|
||||
console.log(
|
||||
` v${String(major).padEnd(3)} first ${line.firstVersion.padEnd(9)} ${line.first.slice(0, 10)}` +
|
||||
` latest ${line.lastVersion.padEnd(9)} ${line.last.slice(0, 10)}${stale}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user