From 801ad3c7136153484243cc7789aafe7dc9280c8a Mon Sep 17 00:00:00 2001 From: the letter L <134443988+turbocrime@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:04:58 -0700 Subject: [PATCH] use pnpm overrides instead of root syncpack (#91) --- .pnpmfile.cjs | 25 +++++++++++++ .syncpackrc | 10 ------ package.json | 18 +++------- packages/context/package.json | 1 + packages/ui/package.json | 1 + pnpm-lock.yaml | 65 ++++++++++++---------------------- scripts/add-tgz.ts | 66 +++++++++++++++++++++++++++++++++++ 7 files changed, 120 insertions(+), 66 deletions(-) create mode 100644 .pnpmfile.cjs create mode 100644 scripts/add-tgz.ts diff --git a/.pnpmfile.cjs b/.pnpmfile.cjs new file mode 100644 index 00000000..cb8e8947 --- /dev/null +++ b/.pnpmfile.cjs @@ -0,0 +1,25 @@ +/** + * Developers may wish to use pnpm.overrides to specify local tarballs or other + * customization, but pnpm currently does not respect overrides during peer + * dependency resolution. + * + * @see https://github.com/pnpm/pnpm/issues/4214 + * + * @param pkg manifest of package currently being read + */ +const overridePeerDependencies = (pkg, context) => { + const overrides = require('./package.json').pnpm?.overrides ?? {}; + for (const dep of Object.keys(pkg.peerDependencies ?? {})) { + if (dep in overrides) pkg.peerDependencies[dep] = overrides[dep]; + } + return pkg; +}; + +module.exports = { + hooks: { + readPackage(pkg, context) { + pkg = overridePeerDependencies(pkg, context); + return pkg; + }, + }, +}; diff --git a/.syncpackrc b/.syncpackrc index 6f99f0ae..8936e4b1 100644 --- a/.syncpackrc +++ b/.syncpackrc @@ -18,7 +18,6 @@ "dependencyTypes": [ "dev", "peer", - "pnpmOverrides", "prod" ], "versionGroups": [ @@ -47,15 +46,6 @@ "snapTo": [ "prax-wallet" ] - }, - { - "label": "Control @penumbra-zone packages from root", - "dependencies": [ - "@penumbra-zone/*" - ], - "snapTo": [ - "prax-wallet" - ] } ] } diff --git a/package.json b/package.json index 05b24a57..cf4c0550 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "private": true, "license": "(MIT OR Apache-2.0)", "packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a", + "type": "module", "scripts": { + "add:tgz": "tsx scripts/add-tgz.ts", "all-check": "pnpm clean && pnpm install && pnpm lint && pnpm build && pnpm test", "buf-update": "pnpm update --latest \"@buf/*\" \"@bufbuild/*\" \"@connectrpc/*\" && pnpm syncpack fix-mismatches && pnpm install", "build": "turbo build", @@ -20,6 +22,7 @@ "lint:prettier": "prettier --check .", "lint:rust": "turbo lint:rust", "lint:syncpack": "syncpack lint", + "postadd:tgz": "$npm_execpath install", "postinstall": "syncpack list-mismatches", "pretest": "playwright install", "test": "turbo test", @@ -35,20 +38,7 @@ "@bufbuild/protobuf": "^1.10.0", "@connectrpc/connect": "^1.4.0", "@connectrpc/connect-web": "^1.4.0", - "@penumbra-zone/bech32m": "^6.1.1", - "@penumbra-zone/client": "^11.0.0", - "@penumbra-zone/crypto-web": "^12.0.0", - "@penumbra-zone/getters": "^11.0.0", - "@penumbra-zone/keys": "^4.2.1", - "@penumbra-zone/perspective": "^13.0.0", - "@penumbra-zone/protobuf": "^5.4.0", - "@penumbra-zone/query": "^14.0.0", - "@penumbra-zone/services": "^16.0.0", - "@penumbra-zone/storage": "^13.0.0", - "@penumbra-zone/transport-chrome": "^5.0.1", - "@penumbra-zone/transport-dom": "^7.2.1", - "@penumbra-zone/types": "^15.0.0", - "@penumbra-zone/wasm": "^16.0.0" + "tsx": "^4.16.2" }, "devDependencies": { "@buf/connectrpc_eliza.bufbuild_es": "1.10.0-20230913231627-233fca715f49.1", diff --git a/packages/context/package.json b/packages/context/package.json index c71ba215..b5b26a9b 100644 --- a/packages/context/package.json +++ b/packages/context/package.json @@ -21,6 +21,7 @@ "@penumbra-labs/registry": "9.4.0", "@penumbra-zone/bech32m": "^6.1.1", "@penumbra-zone/crypto-web": "^12.0.0", + "@penumbra-zone/getters": "^11.0.0", "@penumbra-zone/protobuf": "^5.4.0", "@penumbra-zone/query": "^14.0.0", "@penumbra-zone/storage": "^13.0.0", diff --git a/packages/ui/package.json b/packages/ui/package.json index 36de0918..57ad73e5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -33,6 +33,7 @@ "@penumbra-zone/bech32m": "^6.1.1", "@penumbra-zone/getters": "^11.0.0", "@penumbra-zone/perspective": "^13.0.0", + "@penumbra-zone/protobuf": "^5.4.0", "@penumbra-zone/types": "^15.0.0", "@penumbra-zone/wasm": "^16.0.0", "@radix-ui/react-avatar": "^1.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8e2bdce..ff7166f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,8 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +pnpmfileChecksum: bwtiqgusdylthorgowhneampme + importers: .: @@ -32,48 +34,9 @@ importers: '@connectrpc/connect-web': specifier: ^1.4.0 version: 1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/bech32m': - specifier: ^6.1.1 - version: 6.1.1 - '@penumbra-zone/client': - specifier: ^11.0.0 - version: 11.0.0(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/protobuf@5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.2.1) - '@penumbra-zone/crypto-web': - specifier: ^12.0.0 - version: 12.0.0(@penumbra-zone/types@15.0.0(aku33ui5pr7hqvw5mjd4hoxe4u)) - '@penumbra-zone/getters': - specifier: ^11.0.0 - version: 11.0.0(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@6.1.1)(@penumbra-zone/protobuf@5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0)) - '@penumbra-zone/keys': - specifier: ^4.2.1 - version: 4.2.1 - '@penumbra-zone/perspective': - specifier: ^13.0.0 - version: 13.0.0(xnkpkh7kszinuasci55uiljmli) - '@penumbra-zone/protobuf': - specifier: ^5.4.0 - version: 5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0) - '@penumbra-zone/query': - specifier: ^14.0.0 - version: 14.0.0(jrykoqcoppyykbm3yc3xaob7ua) - '@penumbra-zone/services': - specifier: ^16.0.0 - version: 16.0.0(kco4ff7lid2y3pndyjdln5zgxm) - '@penumbra-zone/storage': - specifier: ^13.0.0 - version: 13.0.0(ttlxcu5kwwoiiugedfemcarhbu) - '@penumbra-zone/transport-chrome': - specifier: ^5.0.1 - version: 5.0.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/transport-dom@7.2.1) - '@penumbra-zone/transport-dom': - specifier: ^7.2.1 - version: 7.2.1 - '@penumbra-zone/types': - specifier: ^15.0.0 - version: 15.0.0(aku33ui5pr7hqvw5mjd4hoxe4u) - '@penumbra-zone/wasm': - specifier: ^16.0.0 - version: 16.0.0(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@6.1.1)(@penumbra-zone/protobuf@5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@15.0.0(aku33ui5pr7hqvw5mjd4hoxe4u)) + tsx: + specifier: ^4.16.2 + version: 4.16.2 devDependencies: '@buf/connectrpc_eliza.bufbuild_es': specifier: 1.10.0-20230913231627-233fca715f49.1 @@ -362,6 +325,9 @@ importers: '@penumbra-zone/crypto-web': specifier: ^12.0.0 version: 12.0.0(@penumbra-zone/types@15.0.0(aku33ui5pr7hqvw5mjd4hoxe4u)) + '@penumbra-zone/getters': + specifier: ^11.0.0 + version: 11.0.0(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@6.1.1)(@penumbra-zone/protobuf@5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0)) '@penumbra-zone/protobuf': specifier: ^5.4.0 version: 5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0) @@ -457,6 +423,9 @@ importers: '@penumbra-zone/perspective': specifier: ^13.0.0 version: 13.0.0(xnkpkh7kszinuasci55uiljmli) + '@penumbra-zone/protobuf': + specifier: ^5.4.0 + version: 5.4.0(@buf/cosmos_ibc.bufbuild_es@1.10.0-20240703151202-d7191877c701.1(@bufbuild/protobuf@1.10.0))(@buf/cosmos_ibc.connectrpc_es@1.4.0-20240703151202-d7191877c701.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@buf/penumbra-zone_penumbra.bufbuild_es@1.10.0-20240703080008-312294d02bf9.1(@bufbuild/protobuf@1.10.0))(@buf/penumbra-zone_penumbra.connectrpc_es@1.4.0-20240703080008-312294d02bf9.3(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)))(@bufbuild/protobuf@1.10.0) '@penumbra-zone/types': specifier: ^15.0.0 version: 15.0.0(aku33ui5pr7hqvw5mjd4hoxe4u) @@ -8557,6 +8526,11 @@ packages: peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + tsx@4.16.2: + resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + engines: {node: '>=18.0.0'} + hasBin: true + turbo-darwin-64@1.13.4: resolution: {integrity: sha512-A0eKd73R7CGnRinTiS7txkMElg+R5rKFp9HV7baDiEL4xTG1FIg/56Vm7A5RVgg8UNgG2qNnrfatJtb+dRmNdw==} cpu: [x64] @@ -18795,6 +18769,13 @@ snapshots: tslib: 1.14.1 typescript: 5.5.3 + tsx@4.16.2: + dependencies: + esbuild: 0.21.5 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + turbo-darwin-64@1.13.4: optional: true diff --git a/scripts/add-tgz.ts b/scripts/add-tgz.ts new file mode 100644 index 00000000..56519f20 --- /dev/null +++ b/scripts/add-tgz.ts @@ -0,0 +1,66 @@ +import { type SpawnOptionsWithoutStdio, spawn } from 'node:child_process'; +import fs from 'node:fs/promises'; +import { basename, resolve } from 'node:path'; +import { argv, exit } from 'node:process'; +import url, { URL } from 'node:url'; + +// ----- utils +const usage = (reason?: string) => { + console.warn(reason); + console.warn(`Usage: ${basename(argv[1])} [tarball1.tgz] [tarball2.tgz] ...`); + console.warn("Each tarball should have an accompanying 'package.json' in the same directory."); + return 1; +}; + +const cmd = (exec: string, args?: string[], options?: SpawnOptionsWithoutStdio) => + new Promise((resolve, reject) => { + console.log(exec, ...(args ?? [])); + const run = spawn(exec, args ?? [], { ...options, stdio: 'inherit' }); + run.on('error', reject); + run.on('exit', code => (code ? exit(code) : resolve())); + }); + +const readJson = async (fileUrl: URL): Promise => + JSON.parse((await fs.readFile(fileUrl)).toString()); + +const isPackageJsonWithName = (packageJson: unknown): packageJson is { name: string } => + typeof packageJson === 'object' && + packageJson !== null && + 'name' in packageJson && + typeof packageJson.name === 'string'; + +// ----- main + +const tarballs = argv.slice(2); + +if (!tarballs.length) exit(usage('Missing tarball filenames')); +if (!tarballs.every(fn => fn.endsWith('.tgz'))) + exit(usage("Tarball filenames must end with '.tgz'")); + +// absolute file URLs +const tarballUrls = tarballs.map(tarball => url.pathToFileURL(resolve(tarball))); + +// create record of package name to tarball path +const overrides: Record = Object.fromEntries( + await Promise.all( + tarballUrls.map(async tarballUrl => { + // TODO: the correct package.json is inside the tarball + + const tarballPackageJson = await readJson( + // assume package.json exists in same directory as the tarball + // (default behavior of npm pack) + new URL('package.json', tarballUrl), + ); + + if (!isPackageJsonWithName(tarballPackageJson)) + throw new TypeError(`Invalid package.json adjacent to ${tarballUrl}`); + + return [tarballPackageJson.name, tarballUrl]; + }), + ), +); + +for (const [name, tarballUrl] of Object.entries(overrides)) { + await cmd('pnpm', ['pkg', 'set', `pnpm.overrides.${name}=${tarballUrl}`]); + await cmd('pnpm', ['pkg', 'set', `pnpm.peerDependencyRules.allowAny[].=${name}`]); +}