Created
July 1, 2021 08:13
-
-
Save christianscott/ef1ea69262594bf9c6b31857c4a54845 to your computer and use it in GitHub Desktop.
Count package versions across a JS monorepo
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
fd '**/package.json' | node count_versions_in_monorepo.js |
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 { strict: assert } = require('assert'); | |
const fs = require('fs'); | |
const readline = require('readline'); | |
const depFields = ['dependencies', 'devDependencies', 'peerDependencies']; | |
function getAllDepVersions(pkgJsonObj) { | |
const allDepVersions = []; | |
} | |
async function main() { | |
const lines = await readLinesFromStdin(); | |
const pkgVersions = new Map(); | |
for (const line of lines) { | |
assert( | |
line.endsWith('package.json'), | |
`expected a path to a package.json file, got ${line}`, | |
); | |
const pkgJsonObj = maybeReadJson(line); | |
if (pkgJsonObj == null) { | |
console.error(`skipping ${line}`); | |
continue; | |
} | |
for (const depField of depFields) { | |
if (!(depField in pkgJsonObj)) continue; | |
for (const [name, version] of Object.entries(pkgJsonObj[depField])) { | |
if (isLocalDependency(version)) continue; | |
pushToKey(pkgVersions, name, version); | |
} | |
} | |
} | |
for (const [name, versions] of pkgVersions) { | |
const uniqVersions = unique(versions); | |
if (uniqVersions.length === 1) continue; | |
console.log(`${name}: ${uniqVersions.sort().join(', ')}`); | |
} | |
} | |
function isLocalDependency(version) { | |
return ( | |
version.startsWith('file:') | |
|| version.startsWith('./') | |
|| version.startsWith('../') | |
); | |
} | |
function unique(values) { | |
return [...new Set(values)]; | |
} | |
function pushToKey(map, key, value) { | |
let arr = map.get(key); | |
if (arr == null) { | |
arr = []; | |
map.set(key, arr); | |
} | |
arr.push(value); | |
} | |
function maybeReadJson(filepath) { | |
try { | |
return JSON.parse(fs.readFileSync(filepath, 'utf-8')); | |
} catch (err) { | |
return undefined; | |
} | |
} | |
function readLinesFromStdin() { | |
return new Promise((resolve, reject) => { | |
const lines = []; | |
const linereader = readline.createInterface({ | |
input: process.stdin, | |
terminal: false, | |
}); | |
linereader.on("line", (line) => lines.push(line)); | |
linereader.on("close", () => resolve(lines)); | |
}); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment