Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20.11.0
- uses: pnpm/action-setup@v2
with:
version: 8.15.1
node-version: 22.14.0
- uses: pnpm/action-setup@v6
- name: Install Depdendencies
run: pnpm install
- name: Build all projects
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ jobs:
- uses: actions/setup-node@v3
with:
node-version: 20.11.0
- uses: pnpm/action-setup@v2
with:
version: 8.15.1
- uses: pnpm/action-setup@v6
- name: Install Depdendencies
run: pnpm install
- name: Build and run tests for pnpm-sync-lib
Expand Down
2 changes: 1 addition & 1 deletion packages/pnpm-sync-lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pnpm-sync-lib",
"version": "0.3.4",
"version": "0.3.5",
"description": "API library for integrating \"pnpm-sync\" with your toolchain",
"repository": {
"type": "git",
Expand Down
16 changes: 10 additions & 6 deletions packages/pnpm-sync-lib/src/pnpmSyncPrepare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
IVersionSpecifier,
ITargetFolder
} from './interfaces';
import { isPnpmV10, isPnpmV8, isPnpmV9, pnpmSyncGetJsonVersion } from './utilities';
import { isPnpmV10, isPnpmV11, isPnpmV8, isPnpmV9, pnpmSyncGetJsonVersion } from './utilities';

/**
* @beta
Expand Down Expand Up @@ -224,9 +224,12 @@ export async function pnpmSyncPrepareAsync(options: IPnpmSyncPrepareOptions): Pr
const pnpmModulesYaml = YAML.parse(fs.readFileSync(`${pnpmModulesYamlPath}/.modules.yaml`, 'utf8'));
const pnpmVersion: string | undefined = pnpmModulesYaml?.packageManager?.split('@')[1];

if (!pnpmVersion || !(isPnpmV8(pnpmVersion) || isPnpmV9(pnpmVersion) || isPnpmV10(pnpmVersion))) {
if (
!pnpmVersion ||
!(isPnpmV8(pnpmVersion) || isPnpmV9(pnpmVersion) || isPnpmV10(pnpmVersion) || isPnpmV11(pnpmVersion))
) {
logMessageCallback({
message: `The pnpm version is not supported; pnpm-sync requires pnpm version 8.x, 9.x, 10.x`,
message: `The pnpm version is not supported; pnpm-sync requires pnpm version 8.x, 9.x, 10.x, 11.x`,
messageKind: LogMessageKind.ERROR,
details: {
messageIdentifier: LogMessageIdentifier.PREPARE_ERROR_UNSUPPORTED_PNPM_VERSION,
Expand All @@ -242,7 +245,7 @@ export async function pnpmSyncPrepareAsync(options: IPnpmSyncPrepareOptions): Pr
ignoreIncompatible: true
});

// currently, only support lockfileVersion 6.x, which is pnpm v8 and lockfileVersion 9.x, which is pnpm v9
// pnpm v8 uses lockfile version 6.x; pnpm v9 through v11 use lockfile version 9.x.
const lockfileVersion: string | undefined = pnpmLockfile?.lockfileVersion.toString();
if (
!pnpmLockfile ||
Expand Down Expand Up @@ -297,10 +300,11 @@ export async function pnpmSyncPrepareAsync(options: IPnpmSyncPrepareOptions): Pr
if (isPnpmV9(pnpmVersion)) {
return depPathToFilenameV9(injectedDependency + '@' + injectedDependencyVersion, 120);
}
if (isPnpmV10(pnpmVersion)) {
if (isPnpmV10(pnpmVersion) || isPnpmV11(pnpmVersion)) {
return depPathToFilenameV10(
injectedDependency + '@' + injectedDependencyVersion,
// for v10 default is 120 on Linux/MacOS and 60 on Windows https://pnpm.io/next/settings#virtualstoredirmaxlength
// For pnpm v10 and v11 the default is 120 on Linux/macOS and 60 on Windows.
// https://pnpm.io/settings#virtualstoredirmaxlength
process.platform === 'win32' ? 60 : 120
);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/pnpm-sync-lib/src/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ export const isPnpmV8 = (pnpmVersion: string): boolean => pnpmVersion.startsWith
export const isPnpmV9 = (pnpmVersion: string): boolean => pnpmVersion.startsWith('9.');

export const isPnpmV10 = (pnpmVersion: string): boolean => pnpmVersion.startsWith('10.');

export const isPnpmV11 = (pnpmVersion: string): boolean => pnpmVersion.startsWith('11.');
2 changes: 1 addition & 1 deletion packages/pnpm-sync/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pnpm-sync",
"version": "0.3.4",
"version": "0.3.5",
"description": "Recopy injected dependencies whenever a project is rebuilt in your PNPM workspace",
"keywords": [
"rush",
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Object {
},
],
},
"version": "0.3.4",
"version": "0.3.5",
}
`;

Expand Down Expand Up @@ -93,7 +93,7 @@ Object {
},
],
},
"version": "0.3.4",
"version": "0.3.5",
}
`;

Expand Down Expand Up @@ -140,6 +140,53 @@ Object {
},
],
},
"version": "0.3.4",
"version": "0.3.5",
}
`;

exports[`pnpm multi version test pnpm v11 1`] = `
Array [
Object {
"details": Object {
"dotPnpmFolder": "<root>/pnpm-sync/tests/test-fixtures/pnpm-v11/node_modules/.pnpm",
"lockfilePath": "<root>/pnpm-sync/tests/test-fixtures/pnpm-v11/pnpm-lock.yaml",
"messageIdentifier": "prepare-starting",
},
"message": "Starting...",
"messageKind": "verbose",
},
Object {
"details": Object {
"messageIdentifier": "prepare-writing-file",
"pnpmSyncJsonPath": "<root>/pnpm-sync/tests/test-fixtures/pnpm-v11/packages/sample-lib1/node_modules/.pnpm-sync.json",
"sourceProjectFolder": "<root>/pnpm-sync/tests/test-fixtures/pnpm-v11/packages/sample-lib1",
},
"message": "Writing...",
"messageKind": "verbose",
},
Object {
"details": Object {
"dotPnpmFolder": "<root>/pnpm-sync/tests/test-fixtures/pnpm-v11/node_modules/.pnpm",
"executionTimeInMs": "[TIMING]",
"lockfilePath": "<root>/pnpm-sync/tests/test-fixtures/pnpm-v11/pnpm-lock.yaml",
"messageIdentifier": "prepare-finishing",
},
"message": "Regenerated...",
"messageKind": "info",
},
]
`;

exports[`pnpm multi version test pnpm v11 2`] = `
Object {
"postbuildInjectedCopy": Object {
"sourceFolder": "..",
"targetFolders": Array [
Object {
"folderPath": "../../../node_modules/.pnpm/sample-lib1@file+packages+sample-lib1_@rushstack+eslint-patch@1.16.1_@rushstack+node-co_c39b755ece3ba75158e9aae0754dd9f8/node_modules/sample-lib1",
},
],
},
"version": "0.3.5",
}
`;
74 changes: 42 additions & 32 deletions tests/pnpm-sync-api-test/src/test/pnpmMultiVersion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,54 @@ import { ILogMessageCallbackOptions, pnpmSyncPrepareAsync } from 'pnpm-sync-lib'
import { __dirname, readPnpmLockfile, scrubLog } from './testUtilities.js';

describe('pnpm multi version test', () => {
it.each(['8', '9', '10'])('pnpm v%s', async (version) => {
const logs: ILogMessageCallbackOptions[] = [];
const projectDir = path.join(__dirname, '..', '..', '..', 'test-fixtures', `pnpm-v${version}`);
it.each(['8', '9', '10', '11'])(
'pnpm v%s',
async (version) => {
const logs: ILogMessageCallbackOptions[] = [];
const projectDir = path.join(__dirname, '..', '..', '..', 'test-fixtures', `pnpm-v${version}`);

// Clean the project directory by removing all untracked files and directories
await execa({ cwd: projectDir })`git clean -xdf`;
// Install dependencies using the specified pnpm version via corepack
await execa({ cwd: projectDir })`corepack pnpm i`;
// Remove install outputs without requiring the fixture itself to already be tracked by Git.
await Promise.all(
[
path.join(projectDir, 'node_modules'),
path.join(projectDir, 'apps', 'sample-app1', 'node_modules'),
path.join(projectDir, 'apps', 'sample-app2', 'node_modules'),
path.join(projectDir, 'packages', 'sample-lib1', 'node_modules')
].map((folderPath) => FileSystem.deleteFolderAsync(folderPath))
);
// Install dependencies using the specified pnpm version via corepack
await execa({ cwd: projectDir })`corepack pnpm i`;

await pnpmSyncPrepareAsync({
lockfilePath: path.join(projectDir, 'pnpm-lock.yaml'),
dotPnpmFolder: path.join(projectDir, 'node_modules', '.pnpm'),
ensureFolderAsync: FileSystem.ensureFolderAsync,
readPnpmLockfile,
logMessageCallback: (options: ILogMessageCallbackOptions): void => {
logs.push(options);
}
});
await pnpmSyncPrepareAsync({
lockfilePath: path.join(projectDir, 'pnpm-lock.yaml'),
dotPnpmFolder: path.join(projectDir, 'node_modules', '.pnpm'),
ensureFolderAsync: FileSystem.ensureFolderAsync,
readPnpmLockfile,
logMessageCallback: (options: ILogMessageCallbackOptions): void => {
logs.push(options);
}
});

expect(logs.map((x) => scrubLog(x))).toMatchSnapshot();
expect(logs.map((x) => scrubLog(x))).toMatchSnapshot();

const pnpmSyncJSONFile = path.join(
projectDir,
'packages',
'sample-lib1',
'node_modules',
'.pnpm-sync.json'
);
const pnpmSyncJSON = JSON.parse(FileSystem.readFile(pnpmSyncJSONFile));
const pnpmSyncJSONFile = path.join(
projectDir,
'packages',
'sample-lib1',
'node_modules',
'.pnpm-sync.json'
);
const pnpmSyncJSON = JSON.parse(FileSystem.readFile(pnpmSyncJSONFile));

// Verify that the configuration matches the expected snapshot
expect(pnpmSyncJSON).toMatchSnapshot();
// Verify that the configuration matches the expected snapshot
expect(pnpmSyncJSON).toMatchSnapshot();

// Verify that all target folders specified in the configuration exist
expect(() => {
// Verify that all target folders specified in the configuration exist
for (const targetFolder of pnpmSyncJSON.postbuildInjectedCopy.targetFolders) {
FileSystem.exists(targetFolder.folderPath);
const targetFolderPath = path.resolve(path.dirname(pnpmSyncJSONFile), targetFolder.folderPath);
expect(FileSystem.exists(targetFolderPath)).toBe(true);
}
}).not.toThrow();
});
},
120_000
);
});
2 changes: 1 addition & 1 deletion tests/pnpm-sync-api-test/src/test/pnpmSyncPrepare.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Array [
Object {
"details": Object {
"actualVersion": "incompatible-version",
"expectedVersion": "0.3.4",
"expectedVersion": "0.3.5",
"messageIdentifier": "prepare-replacing-file",
"pnpmSyncJsonPath": "<root>/pnpm-sync/tests/test-fixtures/sample-lib1/node_modules/.pnpm-sync.json",
"sourceProjectFolder": "<root>/pnpm-sync/tests/test-fixtures/sample-lib1",
Expand Down
3 changes: 1 addition & 2 deletions tests/test-fixtures/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Each pnpm version directory contains:
Update the test file to include the new version:
```typescript
// tests/pnpm-sync-api-test/src/test/pnpmMultiVersion.test.ts
it.each(['8', '9', '10', 'X'])('pnpm v%s', async (version) => {
it.each(['8', '9', '10', '11', 'X'])('pnpm v%s', async (version) => {
```

7. **Run tests to verify**:
Expand Down Expand Up @@ -107,4 +107,3 @@ These fixtures are used by the pnpm-sync test suite to:
- Ensure proper handling of different project structures

Each fixture represents a specific test scenario and should be maintained to reflect real-world usage patterns.

22 changes: 22 additions & 0 deletions tests/test-fixtures/pnpm-v11/apps/sample-app1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "sample-app1",
"version": "0.0.0",
"scripts": {
"build": "tsc"
},
"dependencies": {
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sample-lib1": "workspace:*"
},
"devDependencies": {
"typescript": "^5.8.3"
},
"dependenciesMeta": {
"sample-lib1": {
"injected": true
}
}
}
8 changes: 8 additions & 0 deletions tests/test-fixtures/pnpm-v11/apps/sample-app1/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Lib1Component } from 'sample-lib1';

export const App1Component = () => (
<div>
{'I am from sample-app1.'}
<Lib1Component />
</div>
);
5 changes: 5 additions & 0 deletions tests/test-fixtures/pnpm-v11/apps/sample-app1/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.app.base.json",
"compilerOptions": {},
"include": ["src"]
}
22 changes: 22 additions & 0 deletions tests/test-fixtures/pnpm-v11/apps/sample-app2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "sample-app2",
"version": "0.0.0",
"scripts": {
"build": "tsc"
},
"dependencies": {
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"sample-lib1": "workspace:*"
},
"devDependencies": {
"typescript": "^5.8.3"
},
"dependenciesMeta": {
"sample-lib1": {
"injected": true
}
}
}
8 changes: 8 additions & 0 deletions tests/test-fixtures/pnpm-v11/apps/sample-app2/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Lib1Component } from 'sample-lib1';

export const App2Component = () => (
<div>
{'I am from sample-app2.'}
<Lib1Component />
</div>
);
5 changes: 5 additions & 0 deletions tests/test-fixtures/pnpm-v11/apps/sample-app2/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../../tsconfig.app.base.json",
"compilerOptions": {},
"include": ["src"]
}
5 changes: 5 additions & 0 deletions tests/test-fixtures/pnpm-v11/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "pnpm-v11-workspace",
"version": "0.0.0",
"packageManager": "pnpm@11.17.0+sha512.cca3cea332ad254bb84145f966d19f4879615210346fc92c79a047f23a0d7b3cca3c3792f0076ba1f1831d277efbcf0a9119b31a9a60eca7fb3d6231f331ef72"
}
Loading
Loading