Last active
March 29, 2023 20:19
-
-
Save kangax/8ddcbca6cf0804ee6a55289eb7ef0866 to your computer and use it in GitHub Desktop.
Find average age of npm dependencies
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const { exec } = require('child_process'); | |
const moment = require('moment'); | |
const _ = require('lodash'); | |
const chalk = require('chalk'); | |
fs.readFile('package.json', (err, data) => { | |
const { dependencies } = JSON.parse(data.toString()); | |
let totalDays = 0; | |
let dependenciesToCheck = Object.keys(dependencies).length; | |
const meta = {}; | |
console.log(`Checking ${dependenciesToCheck} dependencies\n`); | |
for (const name in dependencies) { | |
const currentVersion = dependencies[name].replace(/^\^/, ''); | |
console.log(`checking ${name} version`); | |
exec(`npm view ${name} version`, (err, stdout, stderr) => { | |
if (err) { | |
return console.log(err); | |
} | |
const latestVersion = stdout.trim(); | |
console.log(`checking ${name} time`); | |
exec(`npm view ${name} time`, (err, stdout, stderr) => { | |
if (err) { | |
return console.log(err); | |
} | |
const times = JSON.parse( | |
// sudo make me a proper json lol | |
stdout | |
.trim() | |
.replace('modified', '"modified"') | |
.replace('created', '"created"') | |
.replace(/'/g, '"') | |
); | |
const currentVersionTime = times[currentVersion]; | |
const latestVersionTime = times[latestVersion]; | |
const daysSinceCurrent = moment(latestVersionTime).diff(currentVersionTime, 'days'); | |
meta[name] = { | |
name, | |
currentVersion, | |
currentVersionTime, | |
latestVersion, | |
latestVersionTime, | |
daysSinceCurrent, | |
}; | |
if (--dependenciesToCheck === 0) { | |
console.log('\n'); | |
const sortedByOldest = _.sortBy(meta, 'daysSinceCurrent').reverse(); | |
sortedByOldest.forEach(package => { | |
const coloredDays = | |
package.daysSinceCurrent < 30 // less than a month | |
? chalk.green(package.daysSinceCurrent) | |
: package.daysSinceCurrent < 180 // less than half a year | |
? chalk.yellow(package.daysSinceCurrent) | |
: chalk.red(package.daysSinceCurrent); | |
console.log( | |
`${package.name} is ${coloredDays} days old (${moment( | |
package.currentVersionTime | |
).format('MMMM Do YYYY')} → ${moment(package.latestVersionTime).format( | |
'MMMM Do YYYY' | |
)})` | |
); | |
}); | |
const values = _.map(_.toArray(meta), 'daysSinceCurrent').sort((a, b) => a - b); | |
const half = Math.floor(values.length / 2); | |
const median = values.length % 2 ? values[half] : (values[half - 1] + values[half]) / 2; | |
const average = _.sumBy(values) / values.length; | |
console.log( | |
`\nAverage age in days: ${average.toFixed()}\nMedian age in days: ${median.toFixed()}` | |
); | |
} | |
}); | |
}); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment