diff --git a/.githooks/post-commit b/.githooks/post-commit index 467799bd..9054c0e1 100755 --- a/.githooks/post-commit +++ b/.githooks/post-commit @@ -1,11 +1,12 @@ #!/usr/bin/sh -FILE=.links.temp-disabled.yaml -if test -f "$FILE"; then +FILE=.links.cjs +FILE_DIS=.links.temp-disabled.cjs +if test -f "$FILE_DIS"; then # Only do the post-commit hook if the file was temp-disabled by the pre-commit hook. # Otherwise linking was actively (`yarn links:disable`) disabled and this hook should noop. - mv .links.temp-disabled.yaml .links.yaml + mv $FILE_DIS $FILE yarnLog=$(yarn) - echo "[yarn-linker] The post-commit hook has re-enabled .links.yaml." + echo "[yarn-linker] The post-commit hook has re-enabled $FILE" exit 1 fi diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 435d75f1..6d8d26b0 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -1,11 +1,12 @@ #!/usr/bin/sh -FILE=".links.yaml" +FILE=.links.cjs +FILE_DIS=.links.temp-disabled.cjs if test -f "$FILE"; then - mv .links.yaml .links.temp-disabled.yaml + mv $FILE .links.temp-disabled.cjs # echo "running yarn" - x=$(yarn) - y=$(git add yarn.lock) - echo "[yarn-linker] The pre-commit hook has disabled .links.yaml and MODIFIED the yarn.lock file. Review the staged changes (the hook added yarn.lock, was this desired?) and run \`git commit \` again if they look okay. The post-commit hook will re-enable your links." + x=$(pnpm install) + y=$(git add pnpm-lock.yaml) + echo "[yarn-linker] The pre-commit hook has disabled $FILE and MODIFIED the pnpm-lock.yaml file. Review the staged changes (the hook added pnpm-lock.yaml, was this desired?) and run \`git commit \` again if they look okay. The post-commit hook will re-enable your links." exit 1 fi diff --git a/.gitignore b/.gitignore index 2b6fab8e..e9225072 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,14 @@ yarn-error.log !/.yarn/releases !/.yarn/sdks !/.yarn/versions +# old yarn based linking /.links.yaml /.links.disabled.yaml /.links.temp-disabled.yaml +# pnpm based linking +/.links.cjs +/.links.disabled.cjs +/.links.temp-disabled.cjs # Playwright /test-results/ diff --git a/.pnpmfile.cjs b/.pnpmfile.cjs new file mode 100644 index 00000000..f5759c26 --- /dev/null +++ b/.pnpmfile.cjs @@ -0,0 +1,58 @@ +/* +Copyright 2026 Element Creations Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE in the repository root for full details. +*/ + +// Created based on https://github.com/element-hq/element-call/blob/60fae70a60e3697eb41210ccf1e400cab37df7c8/.yarn/plugins/linker.cjs +// and the following prompt history: +// - Can you convert this yarn plugin into a pnpm plugin. +// - The goal is to not have modifications to the package.json and lock files so that we do not track links on gh. +// This seems to modify the package.json file. +// What can we do with pnpm to have the link inforamtion in a seperate file +// - why do you cache the loaded links. When does this file get executed? +// Do we need this optimization. +// How do we guarantee, that we aleays use the most recent content from the links file? +// +// Manual transition to cjs. Claude proposed manual yaml parsing. + +const fs = require("fs"); +const path = require("path"); + +function loadLinks() { + try { + return require(path.join(__dirname, ".links.cjs")); + } catch (e) { + return null; + } +} + +function readPackage(pkg, context) { + const links = loadLinks(); + if (!links) return pkg; + + const manifest = JSON.parse( + fs.readFileSync(path.join(__dirname, "package.json"), "utf8"), + ); + if (pkg.name !== manifest.name) return pkg; + + for (const [name, linkPath] of Object.entries(links)) { + const resolved = `link:${path.resolve(__dirname, linkPath)}`; + if (pkg.dependencies && pkg.dependencies[name]) { + context.log(`Linking ${name} -> ${resolved}`); + pkg.dependencies[name] = resolved; + } else if (pkg.devDependencies && pkg.devDependencies[name]) { + context.log(`Linking ${name} -> ${resolved}`); + pkg.devDependencies[name] = resolved; + } + } + + return pkg; +} + +module.exports = { + hooks: { + readPackage, + }, +}; diff --git a/docs/linking.md b/docs/linking.md index 0abbc73e..689a6f02 100644 --- a/docs/linking.md +++ b/docs/linking.md @@ -1,30 +1,34 @@ # Developing with linked packages -If you want to make changes to a package that Element Call depends on and see those changes applied in real time, you can create a link to a local copy of the package. Yarn has a command for this (`yarn link`), but it's not recommended to use it as it ends up modifying package.json with details specific to your development environment. +If you want to make changes to a package that Element Call depends on and see those changes applied in real time, you can create a link to a local copy of the package. Pnpm has a command for this (`pnpm link`), but it's not recommended to use it as it ends up modifying package.json with details specific to your development environment. -Instead, you can use our little 'linker' plugin. Create a file named `.links.yaml` in the Element Call project directory, listing the names and paths of any dependencies you want to link. For example: +Instead, you can use our little 'linker' plugin. Create a file named `.links.cjs` in the Element Call project directory, listing the names and paths of any dependencies you want to link. For example: -```yaml -matrix-js-sdk: ../path/to/matrix-js-sdk -"@vector-im/compound-web": /home/alice/path/to/compound-web +```cjs +// Packages to link to local checkouts +module.exports = { + "matrix-js-sdk": "../your/path/matrix-js-sdk", + "matrix-widget-api": "../your/path/matrix-widget-api", +}; ``` -Then run `yarn install`. +Then run `pnpm install`. ## Hooks -Changes in `.links.yaml` will also update `yarn.lock` when `yarn` is executed. The lockfile will then contain the local +Changes in `.links.yaml` will also update `pnpm-lock.yaml` when `pnpm` is executed. The lockfile will then contain the local version of the package which would not work on others dev setups or the github CI. + One always needs to run: ```bash -mv .links.yaml .links.disabled.yaml +mv .links.cjs .links.disabled.cjs yarn ``` before committing a change. -To make it more convenient to work with this linking system we added git hooks for your conviniece. +To make it more convenient to work with this linking system we added git hooks. A `pre-commit` hook will run `mv .links.yaml .links.disabled.yaml`, `yarn` and `git add yarn.lock` if it detects a `.links.yaml` file and abort the commit. You will than need to check if the resulting changes are appropriate and commit again. @@ -35,5 +39,5 @@ before if a `.links.disabled.yaml` is present. It runs `mv .links.disabled.yaml To activate the hooks automatically configure git with ```bash -git config --local core.hooksPath .githooks/ +git config --local core.hooksPath .githooks ``` diff --git a/package.json b/package.json index 65c0f469..c0f4d505 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "backend-playwright": "docker-compose -f playwright-backend-docker-compose.yml -f playwright-backend-docker-compose.override.yml up", "test:playwright": "playwright test", "test:playwright:open": "pnpm test:playwright --ui", - "links:enable": "mv .links.disabled.yaml .links.yaml & touch .links.yaml", - "links:disable": "mv .links.yaml .links.disabled.yaml", + "links:enable": "mv .links.disabled.cjs .links.cjs & touch .links.cjs", + "links:disable": "mv .links.cjs .links.disabled.cjs", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01c59c96..c800b0c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,8 @@ overrides: js-yaml: ^4.1.1 esbuild: ^0.27.7 +pnpmfileChecksum: rxqlpiscahzxqq6bf4el6c6jvu + importers: .: @@ -236,7 +238,7 @@ importers: version: 1.9.2 matrix-js-sdk: specifier: matrix-org/matrix-js-sdk#develop - version: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/fd01b172368e0ac5479d4830f92ad261a7eccc6c + version: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/668183d7226ccb4819788018fb48e9a58f85a45b matrix-widget-api: specifier: ^1.16.1 version: 1.17.0 @@ -1576,8 +1578,8 @@ packages: '@types/dom-mediacapture-transform': ^0.1.9 livekit-client: ^1.12.0 || ^2.1.0 - '@matrix-org/matrix-sdk-crypto-wasm@18.0.0': - resolution: {integrity: sha512-88+n+dvxLI1cjS10UIlKXVYK7TGWbpAnnaDC9fow7ch/hCvdu3dFhJ3tS3/13N9s9+1QFXB4FFuommj+tHJPhQ==} + '@matrix-org/matrix-sdk-crypto-wasm@18.1.0': + resolution: {integrity: sha512-GxXK2U39+2qWNvR3fXJY7nxdikvpiT17RaS0/Dktk6R8FMKDk3vm79Hq65yrCWLBmT7pJZoerfILNZqhrcUHrg==} engines: {node: '>= 18'} '@mdx-js/react@3.1.1': @@ -4974,8 +4976,8 @@ packages: matrix-events-sdk@0.0.1: resolution: {integrity: sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==} - matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/fd01b172368e0ac5479d4830f92ad261a7eccc6c: - resolution: {tarball: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/fd01b172368e0ac5479d4830f92ad261a7eccc6c} + matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/668183d7226ccb4819788018fb48e9a58f85a45b: + resolution: {tarball: https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/668183d7226ccb4819788018fb48e9a58f85a45b} version: 41.3.0 engines: {node: '>=22.0.0'} @@ -8110,7 +8112,7 @@ snapshots: '@types/dom-mediacapture-transform': 0.1.11 livekit-client: 2.18.3(@types/dom-mediacapture-record@1.0.22) - '@matrix-org/matrix-sdk-crypto-wasm@18.0.0': {} + '@matrix-org/matrix-sdk-crypto-wasm@18.1.0': {} '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5)': dependencies: @@ -11749,10 +11751,10 @@ snapshots: matrix-events-sdk@0.0.1: {} - matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/fd01b172368e0ac5479d4830f92ad261a7eccc6c: + matrix-js-sdk@https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/668183d7226ccb4819788018fb48e9a58f85a45b: dependencies: '@babel/runtime': 7.29.2 - '@matrix-org/matrix-sdk-crypto-wasm': 18.0.0 + '@matrix-org/matrix-sdk-crypto-wasm': 18.1.0 another-json: 0.2.0 bs58: 6.0.0 content-type: 1.0.5