Skip to content

Commit c4d17d3

Browse files
authored
Merge pull request #1312 from nakrovati/update-check-obsolote.js
Refactor checkObsolote.js
2 parents 5668378 + c0a74b6 commit c4d17d3

File tree

1 file changed

+144
-50
lines changed

1 file changed

+144
-50
lines changed

checkObsolete.js

Lines changed: 144 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,160 @@
1-
var _ = require("lodash");
2-
var exec = require("child_process").execSync;
3-
var fs = require("fs");
4-
var path = require("path");
1+
const { execSync } = require("child_process");
2+
const fs = require("fs");
53
const JSON5 = require("json5");
4+
const path = require("path");
65

7-
let args = process.argv.length <= 2 ? [] : process.argv.slice(2, process.argv.length);
6+
const DEBUG = false;
7+
8+
/**
9+
* Returns an array with arrays of types and names of frameworks
10+
* @example getFramewokrs()
11+
* @returns [{type:"keyed", name:"vue"},{type:"keyed", name:"qwik"},{type:"non-keyed", name:"svelte"}]
12+
*/
13+
function getFrameworks() {
14+
const keyedFrameworks = fs
15+
.readdirSync("./frameworks/keyed")
16+
.map((framework) => ({ type: "keyed", name: framework }));
17+
const nonKeyedFrameworks = fs
18+
.readdirSync("./frameworks/non-keyed")
19+
.map((framework) => ({ type: "non-keyed", name: framework }));
20+
return [...keyedFrameworks, ...nonKeyedFrameworks];
21+
}
822

9-
var frameworks = [].concat(
10-
fs.readdirSync("./frameworks/keyed").map((f) => ["keyed", f]),
11-
fs.readdirSync("./frameworks/non-keyed").map((f) => ["non-keyed", f])
12-
);
23+
const frameworks = getFrameworks();
1324

14-
let now = new Date();
15-
let obsoleteDate = new Date(now.getFullYear() - 1, now.getMonth(), now.getDay());
25+
/**
26+
* Looks for duplicate frameworks
27+
* @param {{type: string, name: string}[]} frameworks
28+
* @returns {string[]}
29+
*/
30+
function findDuplicateFrameworks(frameworks) {
31+
const names = frameworks.map((framework) => framework.name); // Creates an array with framework names only
32+
const duplicateNames = names.filter(
33+
(name, index) => names.indexOf(name) !== index
34+
); // Filters out repetitive framework names
35+
36+
return duplicateNames;
37+
}
1638

17-
let warnings = [];
18-
let manually = [];
39+
const duplicateFrameworks = findDuplicateFrameworks(frameworks);
40+
const frameworksCache = new Map();
1941

20-
function maybeObsolete(package) {
21-
let output;
42+
/**
43+
* @param {string} packageName
44+
*/
45+
function maybeObsolete(packageName) {
2246
try {
23-
let output = exec(`npm view ${package} time`, {
24-
stdio: ["ignore", "pipe", "ignore"],
25-
}).toString();
26-
let r = JSON5.parse(output);
27-
return [new Date(r.modified) < obsoleteDate, package, new Date(r.modified).toISOString().substring(0, 10)];
47+
const npmCmd = `npm view ${packageName} time`;
48+
let timeData;
49+
50+
if (duplicateFrameworks.includes(packageName)) {
51+
if (frameworksCache.has(packageName)) {
52+
const output = frameworksCache.get(packageName);
53+
timeData = JSON5.parse(output);
54+
return;
55+
}
56+
57+
const output = execSync(npmCmd, {
58+
stdio: ["ignore", "pipe", "ignore"],
59+
}).toString();
60+
timeData = JSON5.parse(output);
61+
62+
frameworksCache.set(packageName, JSON5.stringify(timeData));
63+
} else {
64+
const output = execSync(npmCmd, {
65+
stdio: ["ignore", "pipe", "ignore"],
66+
}).toString();
67+
timeData = JSON5.parse(output);
68+
}
69+
70+
const now = new Date();
71+
const obsoleteDate = new Date(
72+
now.getFullYear() - 1,
73+
now.getMonth(),
74+
now.getDay()
75+
);
76+
77+
const modifiedDate = new Date(timeData.modified);
78+
const isObsolete = modifiedDate < obsoleteDate;
79+
const formattedDate = modifiedDate.toISOString().substring(0, 10);
80+
81+
return { isObsolete, packageName, lastUpdate: formattedDate };
2882
} catch (error) {
29-
console.error(`Failed to execute npm view for ${package}. Error Code ${error.status} and message: ${error.message}`);
30-
return [false, package, null];
83+
console.error(
84+
`Failed to execute npm view for ${packageName}. Error Code ${error.status} and message: ${error.message}`
85+
);
86+
return { isObsolete: false, packageName, lastUpdate: null };
3187
}
3288
}
3389

34-
const DEBUG = false;
90+
const missingPackageWarnings = [];
91+
const manualChecks = [];
3592

36-
for (f of frameworks) {
37-
let [dir, name] = f;
38-
let path = `frameworks/${dir}/${name}`;
39-
if (!fs.existsSync(path + "/package.json")) {
40-
warnings.push(`WARN: skipping ${dir}/${name} since there's no package.json`);
41-
} else {
42-
let packageJSON = JSON.parse(fs.readFileSync(path + "/package.json"));
43-
let mainPackages = packageJSON?.["js-framework-benchmark"]?.frameworkVersionFromPackage;
44-
if (mainPackages) {
45-
if (DEBUG) console.log(`Checking ${dir}/${name} ${mainPackages}`);
46-
let packages = mainPackages.split(":");
47-
let maybeObsoleteResults = packages.map((p) => maybeObsolete(p));
48-
if (DEBUG) console.log(`Results for ${dir}/${name} ${maybeObsoleteResults}`);
49-
maybeObsoleteResult = maybeObsoleteResults.some((r) => r[0]);
50-
if (maybeObsoleteResult) {
51-
console.log(
52-
`Last npm update for ${dir}/${name} ${mainPackages} is older than a year: ${maybeObsoleteResults
53-
.map((a) => a.slice(1).join(":"))
54-
.join(", ")}`
55-
);
56-
} else {
57-
if (DEBUG) console.log(` Last npm update for ${dir}/${name} ${mainPackages} is newer than a year`);
58-
}
59-
} else {
60-
manually.push(`${dir}/${name} has no frameworkVersionFromPackage`);
93+
/**
94+
* Checks frameworks in frameworks/keyed and frameworks/non-keyed for obsolescence,
95+
* the presence of package.json and the presence of the frameworkVersionFromPackage property
96+
*/
97+
function checkFrameworks() {
98+
for (const { type, name } of frameworks) {
99+
const frameworkPath = path.join("frameworks", type, name);
100+
const packageJSONPath = path.join(frameworkPath, "package.json");
101+
102+
if (!fs.existsSync(packageJSONPath)) {
103+
missingPackageWarnings.push(
104+
`WARN: skipping ${type}/${name} since there's no package.json`
105+
);
106+
continue;
107+
}
108+
109+
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, "utf-8"));
110+
const mainPackages =
111+
packageJSON?.["js-framework-benchmark"]?.frameworkVersionFromPackage;
112+
113+
if (!mainPackages) {
114+
manualChecks.push(`${type}/${name} has no frameworkVersionFromPackage`);
115+
continue;
116+
}
117+
118+
if (DEBUG) {
119+
console.log(`Checking ${type}/${name} ${mainPackages}`);
120+
}
121+
122+
const packages = mainPackages.split(":");
123+
const isPackageObsolete = packages.map(maybeObsolete);
124+
125+
if (DEBUG) {
126+
console.log(`Results for ${type}/${name} ${isPackageObsolete}`);
127+
}
128+
129+
const anyPackageObsolete = isPackageObsolete.some(
130+
(packageFramework) => packageFramework.isObsolete
131+
);
132+
133+
if (anyPackageObsolete) {
134+
const formattedPackages = isPackageObsolete
135+
.map((result) => `${result.packageName}:${result.lastUpdate}`)
136+
.join(", ");
137+
138+
console.log(
139+
`Last npm update for ${type}/${name} - ${mainPackages} is older than a year: ${formattedPackages}`
140+
);
141+
continue;
142+
}
143+
144+
if (DEBUG) {
145+
console.log(
146+
`Last npm update for ${type}/${name} ${mainPackages} is newer than a year`
147+
);
61148
}
62149
}
150+
151+
if (missingPackageWarnings.length > 0)
152+
console.warn("\nWarnings:\n" + missingPackageWarnings.join("\n"));
153+
if (manualChecks.length > 0)
154+
console.warn(
155+
"\nThe following frameworks must be checked manually\n" +
156+
manualChecks.join("\n")
157+
);
63158
}
64159

65-
if (warnings.length > 0) console.log("\nWarnings:\n" + warnings.join("\n"));
66-
if (manually.length > 0) console.log("\nThe following frameworks must be checked manually\n" + manually.join("\n"));
160+
checkFrameworks();

0 commit comments

Comments
 (0)