Skip to content

Commit

Permalink
Merge pull request #11 from NullVoxPopuli/recursive-aka-monorepo-support
Browse files Browse the repository at this point in the history
Resolve #9, support scanning a whole monorepo. Add --force (to clear …cache), --recursive (for monorepo), --help, --verbose (for the old output), new output has a progress bar now
  • Loading branch information
NullVoxPopuli authored Jul 6, 2024
2 parents abf31b9 + de2ffea commit e23f0c8
Show file tree
Hide file tree
Showing 5 changed files with 801 additions and 1,565 deletions.
107 changes: 102 additions & 5 deletions bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ import path from "node:path";
import fs from "node:fs/promises";
import fsSync from "node:fs";
import process from "node:process";
import { parseArgs } from "node:util";
import { execa } from "execa";
import cliProgress from "cli-progress";

import { cacheResponse, readCachedResponse } from "./cache.js";
import { IN_MONOREPO, getMonorepoPackage } from "./monorepo.js";
import { cacheResponse, readCachedResponse, clearCache } from "./cache.js";
import {
IN_MONOREPO,
getMonorepoPackage,
getAllPackageJSONs,
} from "./monorepo.js";
import { getPackageInfo } from "./npm.js";
import { readPackageJson, getDeclaredDeps } from "./package-json.js";
import { printSummary } from "./output.js";
Expand All @@ -21,7 +27,62 @@ import {

const CWD = process.cwd();

const args = parseArgs({
options: {
recursive: {
type: "boolean",
short: "r",
default: false,
},
force: {
type: "boolean",
default: false,
},
verbose: {
type: "boolean",
short: "v",
default: false,
},
help: {
type: "boolean",
short: "h",
default: false,
},
},
});

if (args.values.help) {
console.log(`
Usage:
npx dependency-maintainers
--recursive, -r In a monorepo, find the montainers of every (package in the monorepo)'s (dev)dependencies
npx dependency-maintainers --recursive
--verbose, -v Print extra logging to stdout
npx dependency-maintainers --verbose
--force Force a cache refresh
npx dependency-maintainers --force
--help, -h show this message
npx dependency-maintainers --help
`);
process.exit(0);
}

if (args.values.force) {
await clearCache();
}

const BATCH_SIZE = 40;
const IS_VERBOSE = args.values.verbose;

function updateMaintainers(npmInfo) {
/**
Expand All @@ -47,14 +108,36 @@ function incrementUser(user) {

const QUEUE = [];
const HAS_INFO = new Set();
let seen = 0;
let total = 0;
const progress = new cliProgress.SingleBar(
{},
cliProgress.Presets.shades_classic,
);

function showProgress() {
progress.start(total, seen);
}

function updateProgress() {
if (IS_VERBOSE) return;

progress.update(seen);
}

async function traverseGraph() {
async function processDep(depName) {
console.debug(`Processed ${SEEN_DEPS.size}. Processing ${depName}`);
if (IS_VERBOSE) {
console.debug(`Processed ${SEEN_DEPS.size}. Processing ${depName}`);
} else {
showProgress();
}

let shouldSkipMaintainers = IN_MONOREPO.has(depName);
let info = getMonorepoPackage(depName) || (await getPackageInfo(depName));

seen++;
updateProgress();
if (!info) {
return;
}
Expand All @@ -75,6 +158,7 @@ async function traverseGraph() {
batch.map((depName) => {
if (SEEN_DEPS.has(depName)) return;

total++;
SEEN_DEPS.add(depName);
return processDep(depName);
}),
Expand All @@ -99,10 +183,23 @@ async function traverseGraph() {
}
}

let rootJson = await readPackageJson();
let rootDeps = await getDeclaredDeps(rootJson, true);
let rootDeps = [];

if (args.values.recursive) {
let all = getAllPackageJSONs();

console.log(`Getting maintainers for all ${all.length} packages...`);

for (let rootJson of all) {
rootDeps = await getDeclaredDeps(rootJson, true);
}
} else {
let rootJson = await readPackageJson();
rootDeps = await getDeclaredDeps(rootJson, true);
}

QUEUE.push(...rootDeps);
await traverseGraph();

progress.stop();
printSummary();
5 changes: 5 additions & 0 deletions cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ async function ensureCacheDir() {
}
await ensureCacheDir();

export async function clearCache() {
await fs.rm(path.join(__dirname, ".cache"), { recursive: true });
await ensureCacheDir();
}

export async function cacheResponse(depName, response) {
let cachePath = path.join(__dirname, ".cache", depName + ".json");

Expand Down
4 changes: 4 additions & 0 deletions monorepo.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const CWD = process.cwd();
*/
const monorepoInfo = await getPackages(CWD);

export function getAllPackageJSONs() {
return monorepoInfo.packages.map((pkg) => pkg.packageJson);
}

export const IN_MONOREPO = new Set(
monorepoInfo.packages.map((pkg) => pkg.packageJson.name),
);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
},
"dependencies": {
"@manypkg/get-packages": "^2.2.1",
"cli-progress": "^3.12.0",
"execa": "^9.2.0"
},
"publishConfig": {
Expand Down
Loading

0 comments on commit e23f0c8

Please sign in to comment.