diff --git a/bin/clean.js b/bin/clean.js new file mode 100755 index 0000000..b75e4c0 --- /dev/null +++ b/bin/clean.js @@ -0,0 +1,13 @@ +#!/usr/bin/env node +/** + * @file clean.js + * @summary prune remote and local branches, then run git garbage collection + */ +const { execEachRepo } = require('../lib/exec'); + +execEachRepo([ + 'git fetch', + 'git remote prune origin', + 'git gc', +]); + diff --git a/lib/exec.js b/lib/exec.js new file mode 100644 index 0000000..cc3e340 --- /dev/null +++ b/lib/exec.js @@ -0,0 +1,39 @@ +const matrix = require("../matrix.json"); +const assert = require("assert"); +const { exec } = require("child_process"); +const fs = require("fs"); + +const isStringArray = arr => + Array.isArray(arr) && arr.every(i => typeof i === "string"); + +/** + * Execute a command in each repository + * @param {string | string[]} command the command to run. If an array, it will be joined with `&&`. + */ +const execEachRepo = async command => { + assert( + typeof command === "string" || isStringArray(command), + "cmd must be a string or array of strings" + ); + const cmd = Array.isArray(command) ? command.join(" && ") : command; + + assert( + fs.existsSync("repos"), + "No repositories found, did you forget to run `pnpm clone`?" + ); + + for (const item of matrix) { + const command = `cd repos/${item.path} && ${cmd}`; + console.log(command); + + exec(command, function (err) { + if (err) { + console.error(err); + return; + } + console.log(`Finished: ${item.repository}`); + }); + } +}; + +module.exports = { execEachRepo }; diff --git a/package.json b/package.json index fca7a07..22165c5 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "test:default": "RUST_BACKTRACE=1 node bin/test.js $(which oxlint)", "update": "node bin/update.js", "reset": "node bin/reset.js", + "clean": "node bin/clean.js", "lint": "npx oxlint@latest ." } }