diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 1e1d2eb..5b165f7 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,5 +1,10 @@ # CoSpace +## 0.6.0 + +- Add `update-lockfile` command to update all `pnpm-lock.yaml`s found in the CoSpace + - Will update pnpm lockfiles used by [@microsoft/rush](https://rushjs.io/pages/intro/welcome/) by using [RUSH_PNPM_STORE_PATH](https://rushjs.io/pages/configs/environment_vars/#rush_pnpm_store_path) env var + ## 0.5.0 - Converted to TypeScript diff --git a/cli/index.ts b/cli/index.ts index f401d1c..5f904ba 100644 --- a/cli/index.ts +++ b/cli/index.ts @@ -4,6 +4,7 @@ import { execSync } from "node:child_process"; import path from "node:path"; import { fileURLToPath } from "node:url"; import fs from "fs-extra"; +import { globby } from "globby"; import meow from "meow"; // since __filename and __dirname are undefined for esm, define ourselves @@ -12,6 +13,8 @@ const __dirname = path.dirname(__filename); const PACKAGE_JSON = "package.json"; const WORKSPACE_VERSION = "workspace:*"; +const PNPM_LOCKFILE = "pnpm-lock.yaml"; +const RUSH_JSON = "rush.json"; interface PnpmPackageInfo { name: string; @@ -24,6 +27,7 @@ const enum Commands { INIT = "init", OVERRIDE = "override", PURGE = "purge", + UPDATE_LOCKFILE = "update-lockfile", } const help = ` @@ -37,6 +41,7 @@ const help = ` ${Commands.OVERRIDE} Override the CoSpace's pnpm config ${Commands.PURGE} Purge all node_modules from the CoSpace + ${Commands.UPDATE_LOCKFILE} Update all pnpm lockfiles found in the CoSpace Flags: --help, -h Show this help message @@ -45,9 +50,10 @@ const help = ` --includePrivate Add private packages to CoSpace's pnpm overrides `; +let pnpmStorePath = ""; const checkPnpmInstalled = () => { try { - execSync("pnpm -v", { stdio: "ignore" }); + pnpmStorePath = execSync("pnpm store path", { encoding: "utf8" }); } catch { console.error( "Please install pnpm before using CoSpace, see https://pnpm.io/installation" @@ -159,6 +165,51 @@ const purge = async () => { console.log("All node_modules have been purged from the CoSpace."); }; +const updateLockfile = async () => { + const lockfiles = await globby( + [ + `**/${PNPM_LOCKFILE}`, + `!**/rush/${PNPM_LOCKFILE}`, + `**/${RUSH_JSON}`, + ], + { + absolute: true, + cwd: "./repos/", + ignore: ["**/node_modules/**"], + objectMode: true, + } + ); + + let rush_update_cmd = "rush update"; + if (lockfiles.some((l) => l.name === RUSH_JSON)) { + try { + execSync("rush -h", { stdio: "ignore" }); + } catch { + rush_update_cmd = "pnpm dlx @microsoft/rush update"; + } + } + + for (const lockfile of lockfiles) { + try { + console.log(`Updating ${lockfile.path}`); + process.chdir(path.join(lockfile.path, "..")); + switch (lockfile.name) { + case PNPM_LOCKFILE: + execSync("pnpm i --lockfile-only", { stdio: "inherit" }); + break; + case RUSH_JSON: + execSync(rush_update_cmd, { + stdio: "inherit", + env: { ...process.env, RUSH_PNPM_STORE_PATH: pnpmStorePath }, + }); + break; + } + } catch (e) { + console.log((e as Error).message); + } + } +}; + const run = async () => { const { input, flags, showHelp, showVersion } = meow(help, { importMeta: import.meta, @@ -184,6 +235,8 @@ const run = async () => { return await overridePnpm(flags.includePrivate); case Commands.PURGE: return await purge(); + case Commands.UPDATE_LOCKFILE: + return await updateLockfile(); default: console.error( `Unrecognized command, "${command}", please try again with --help for more info.` diff --git a/cli/package.json b/cli/package.json index 901488e..20c9f54 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "cospace", - "version": "0.5.0", + "version": "0.6.0", "description": "Setup a `CoSpace` to link multiple (mono)repos together!", "author": "https://github.com/aruniverse", "homepage": "https://aruniverse.github.io/cospace/", @@ -33,6 +33,7 @@ ], "dependencies": { "fs-extra": "^10.0.0", + "globby": "^13.1.2", "meow": "^10.0.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a664b8e..49df5be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,11 +16,13 @@ importers: '@types/fs-extra': 9.0.13 '@types/node': ^16.0.0 fs-extra: ^10.0.0 + globby: ^13.1.2 meow: ^10.0.0 rimraf: ^3.0.2 typescript: ^4.8.2 dependencies: fs-extra: 10.0.1 + globby: 13.1.2 meow: 10.1.2 devDependencies: '@types/fs-extra': 9.0.13 @@ -51,6 +53,27 @@ packages: js-tokens: 4.0.0 dev: false + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: false + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: false + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: false + /@types/fs-extra/9.0.13: resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} dependencies: @@ -92,6 +115,13 @@ packages: concat-map: 0.0.1 dev: true + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: false + /camelcase-keys/7.0.2: resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} engines: {node: '>=12'} @@ -148,6 +178,13 @@ packages: engines: {node: '>=10'} dev: false + /dir-glob/3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: false + /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -159,6 +196,30 @@ packages: engines: {node: '>=0.8.0'} dev: false + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: false + + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: false + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: false + /find-up/5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -184,6 +245,13 @@ packages: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: false + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: false + /glob/7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: @@ -195,6 +263,17 @@ packages: path-is-absolute: 1.0.1 dev: true + /globby/13.1.2: + resolution: {integrity: sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.2.12 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 4.0.0 + dev: false + /graceful-fs/4.2.9: resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} dev: false @@ -223,6 +302,11 @@ packages: lru-cache: 6.0.0 dev: false + /ignore/5.2.0: + resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} + engines: {node: '>= 4'} + dev: false + /indent-string/5.0.0: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} @@ -249,6 +333,23 @@ packages: has: 1.0.3 dev: false + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: false + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: false + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: false + /is-plain-obj/1.1.0: resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=} engines: {node: '>=0.10.0'} @@ -321,6 +422,19 @@ packages: yargs-parser: 20.2.9 dev: false + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: false + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: false + /min-indent/1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -391,6 +505,20 @@ packages: engines: {node: '>=0.10.0'} dev: true + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: false + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: false + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: false + /quick-lru/5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} @@ -423,6 +551,11 @@ packages: strip-indent: 4.0.0 dev: false + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: false + /rimraf/3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true @@ -430,6 +563,12 @@ packages: glob: 7.2.3 dev: true + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: false + /semver/7.3.5: resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} engines: {node: '>=10'} @@ -438,6 +577,11 @@ packages: lru-cache: 6.0.0 dev: false + /slash/4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: false + /spdx-correct/3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} dependencies: @@ -474,6 +618,13 @@ packages: has-flag: 3.0.0 dev: false + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: false + /trim-newlines/4.0.2: resolution: {integrity: sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==} engines: {node: '>=12'}