diff --git a/.changeset/red-feet-relax.md b/.changeset/red-feet-relax.md new file mode 100644 index 0000000000..9a71246886 --- /dev/null +++ b/.changeset/red-feet-relax.md @@ -0,0 +1,9 @@ +--- +"@pnpm/cli-utils": patch +"@pnpm/filter-lockfile": patch +"@pnpm/lockfile-file": patch +"@pnpm/package-is-installable": patch +"@pnpm/resolve-dependencies": patch +--- + +feat: support libc filed diff --git a/package.json b/package.json index 5b6932a54d..f313684ed4 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "hosted-git-info@4": "npm:@zkochan/hosted-git-info@^4.0.2", "http-errors": "^1.7.3", "istanbul-reports": "npm:@zkochan/istanbul-reports", - "js-yaml@^4.0.0": "npm:@zkochan/js-yaml@0.0.5", + "js-yaml@^4.0.0": "npm:@zkochan/js-yaml@0.0.6", "lodash@<4.17.19": "^4.17.9", "nopt@5": "npm:@pnpm/nopt@^0.2.1", "pkg-fetch": "3.1.1", diff --git a/packages/cli-utils/src/packageIsInstallable.ts b/packages/cli-utils/src/packageIsInstallable.ts index fd45b46191..86154899c1 100644 --- a/packages/cli-utils/src/packageIsInstallable.ts +++ b/packages/cli-utils/src/packageIsInstallable.ts @@ -8,6 +8,7 @@ export function packageIsInstallable ( engines?: WantedEngine cpu?: string[] os?: string[] + libc?: string[] }, opts: { engineStrict?: boolean diff --git a/packages/exportable-manifest/src/overridePublishConfig.ts b/packages/exportable-manifest/src/overridePublishConfig.ts index 8335258e72..f5a38dc086 100644 --- a/packages/exportable-manifest/src/overridePublishConfig.ts +++ b/packages/exportable-manifest/src/overridePublishConfig.ts @@ -21,6 +21,7 @@ const PUBLISH_CONFIG_WHITELIST = new Set([ // These are useful to hide in order to avoid warnings during local development 'os', 'cpu', + 'libc', // https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html#version-selection-with-typesversions 'typesVersions', ]) diff --git a/packages/filter-lockfile/package.json b/packages/filter-lockfile/package.json index f365c106f5..764c6fa3bf 100644 --- a/packages/filter-lockfile/package.json +++ b/packages/filter-lockfile/package.json @@ -39,7 +39,8 @@ "@types/ramda": "0.27.39", "tempy": "^1.0.0", "write-yaml-file": "^4.2.0", - "yaml-tag": "1.1.0" + "yaml-tag": "1.1.0", + "detect-libc": "^2.0.1" }, "dependencies": { "@pnpm/constants": "workspace:6.1.0", diff --git a/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts b/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts index 72e14298af..6a7313710d 100644 --- a/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts +++ b/packages/filter-lockfile/src/filterLockfileByImportersAndEngine.ts @@ -137,6 +137,7 @@ function pkgAllDeps ( cpu: pkgSnapshot.cpu, engines: pkgSnapshot.engines, os: pkgSnapshot.os, + libc: pkgSnapshot.libc, } // TODO: depPath is not the package ID. Should be fixed installable = opts.includeIncompatiblePackages || packageIsInstallable(pkgSnapshot.id ?? depPath, pkg, { diff --git a/packages/filter-lockfile/test/filterByImportersAndEngine.ts b/packages/filter-lockfile/test/filterByImportersAndEngine.ts index a9d1ecc63f..5a10af816d 100644 --- a/packages/filter-lockfile/test/filterByImportersAndEngine.ts +++ b/packages/filter-lockfile/test/filterByImportersAndEngine.ts @@ -1,6 +1,28 @@ import { LOCKFILE_VERSION } from '@pnpm/constants' import { filterLockfileByImportersAndEngine } from '@pnpm/filter-lockfile' +const REGIONAL_ARCH = Object.assign({}, process.arch) +const REGIONAL_CPU = Object.assign({}, process.platform) + +jest.mock('detect-libc', () => { + const orginal = jest.requireActual('detect-libc') + return { + ...orginal, + familySync: () => 'musl', + } +}) + +afterEach(() => { + Object.defineProperties(process, { + platform: { + value: REGIONAL_CPU, + }, + arch: { + value: REGIONAL_ARCH, + }, + }) +}) + test('filterByImportersAndEngine(): skip packages that are not installable', () => { const skippedPackages = new Set(['/preserve-existing-skipped/1.0.0']) const filteredLockfile = filterLockfileByImportersAndEngine( @@ -171,3 +193,348 @@ test('filterByImportersAndEngine(): skip packages that are not installable', () }) expect(Array.from(skippedPackages)).toStrictEqual(['/preserve-existing-skipped/1.0.0', '/optional-dep/1.0.0', '/foo/1.0.0']) }) + +test('filterByImportersAndEngine(): filter the packages that set os and cpu', () => { + Object.defineProperties(process, { + platform: { + value: 'darwin', + }, + arch: { + value: 'x64', + }, + }) + + const skippedPackages = new Set(['/preserve-existing-skipped/1.0.0']) + const filteredLockfile = filterLockfileByImportersAndEngine( + { + importers: { + 'project-1': { + dependencies: { + 'prod-dep': '1.0.0', + }, + devDependencies: { + 'dev-dep': '1.0.0', + }, + optionalDependencies: { + 'not-skipped-optional': '1.0.0', + 'optional-dep': '1.0.0', + }, + specifiers: { + 'dev-dep': '^1.0.0', + 'not-skipped-optional': '^1.0.0', + 'optional-dep': '^1.0.0', + 'prod-dep': '^1.0.0', + }, + }, + 'project-2': { + dependencies: { + 'project-2-prod-dep': '1.0.0', + }, + specifiers: { + 'project-2-prod-dep': '^1.0.0', + }, + }, + }, + lockfileVersion: LOCKFILE_VERSION, + packages: { + '/bar/1.0.0': { + resolution: { integrity: '' }, + }, + '/dev-dep/1.0.0': { + dev: true, + resolution: { integrity: '' }, + }, + '/foo/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/not-skipped-optional/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/optional-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + foo: '1.0.0', + }, + os: ['linux'], + cpu: ['x64'], + optional: true, + resolution: { integrity: '' }, + }, + '/prod-dep-dep/1.0.0': { + resolution: { integrity: '' }, + }, + '/prod-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + 'prod-dep-dep': '1.0.0', + }, + optionalDependencies: { + 'optional-dep': '1.0.0', + }, + resolution: { integrity: '' }, + }, + '/project-2-prod-dep/1.0.0': { + resolution: { integrity: '' }, + }, + }, + }, + ['project-1'], + { + currentEngine: { + nodeVersion: '10.0.0', + pnpmVersion: '2.0.0', + }, + engineStrict: true, + failOnMissingDependencies: true, + include: { + dependencies: true, + devDependencies: true, + optionalDependencies: true, + }, + lockfileDir: process.cwd(), + skipped: skippedPackages, + } + ) + + expect(filteredLockfile).toStrictEqual({ + importers: { + 'project-1': { + dependencies: { + 'prod-dep': '1.0.0', + }, + devDependencies: { + 'dev-dep': '1.0.0', + }, + optionalDependencies: { + 'not-skipped-optional': '1.0.0', + 'optional-dep': '1.0.0', + }, + specifiers: { + 'dev-dep': '^1.0.0', + 'not-skipped-optional': '^1.0.0', + 'optional-dep': '^1.0.0', + 'prod-dep': '^1.0.0', + }, + }, + 'project-2': { + dependencies: { + 'project-2-prod-dep': '1.0.0', + }, + specifiers: { + 'project-2-prod-dep': '^1.0.0', + }, + }, + }, + lockfileVersion: LOCKFILE_VERSION, + packages: { + '/bar/1.0.0': { + resolution: { integrity: '' }, + }, + '/dev-dep/1.0.0': { + dev: true, + resolution: { integrity: '' }, + }, + '/foo/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/not-skipped-optional/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/optional-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + foo: '1.0.0', + }, + os: ['linux'], + cpu: ['x64'], + optional: true, + resolution: { integrity: '' }, + }, + '/prod-dep-dep/1.0.0': { + resolution: { integrity: '' }, + }, + '/prod-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + 'prod-dep-dep': '1.0.0', + }, + optionalDependencies: { + 'optional-dep': '1.0.0', + }, + resolution: { integrity: '' }, + }, + }, + }) + expect(Array.from(skippedPackages)).toStrictEqual(['/preserve-existing-skipped/1.0.0', '/optional-dep/1.0.0', '/foo/1.0.0']) +}) + +test('filterByImportersAndEngine(): filter the packages that set libc', () => { + const skippedPackages = new Set(['/preserve-existing-skipped/1.0.0']) + const filteredLockfile = filterLockfileByImportersAndEngine( + { + importers: { + 'project-1': { + dependencies: { + 'prod-dep': '1.0.0', + }, + devDependencies: { + 'dev-dep': '1.0.0', + }, + optionalDependencies: { + 'not-skipped-optional': '1.0.0', + 'optional-dep': '1.0.0', + }, + specifiers: { + 'dev-dep': '^1.0.0', + 'not-skipped-optional': '^1.0.0', + 'optional-dep': '^1.0.0', + 'prod-dep': '^1.0.0', + }, + }, + 'project-2': { + dependencies: { + 'project-2-prod-dep': '1.0.0', + }, + specifiers: { + 'project-2-prod-dep': '^1.0.0', + }, + }, + }, + lockfileVersion: LOCKFILE_VERSION, + packages: { + '/bar/1.0.0': { + resolution: { integrity: '' }, + }, + '/dev-dep/1.0.0': { + dev: true, + resolution: { integrity: '' }, + }, + '/foo/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/not-skipped-optional/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/optional-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + foo: '1.0.0', + }, + libc: ['glibc'], + optional: true, + resolution: { integrity: '' }, + }, + '/prod-dep-dep/1.0.0': { + resolution: { integrity: '' }, + }, + '/prod-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + 'prod-dep-dep': '1.0.0', + }, + optionalDependencies: { + 'optional-dep': '1.0.0', + }, + resolution: { integrity: '' }, + }, + '/project-2-prod-dep/1.0.0': { + resolution: { integrity: '' }, + }, + }, + }, + ['project-1'], + { + currentEngine: { + nodeVersion: '10.0.0', + pnpmVersion: '2.0.0', + }, + engineStrict: true, + failOnMissingDependencies: true, + include: { + dependencies: true, + devDependencies: true, + optionalDependencies: true, + }, + lockfileDir: process.cwd(), + skipped: skippedPackages, + } + ) + + expect(filteredLockfile).toStrictEqual({ + importers: { + 'project-1': { + dependencies: { + 'prod-dep': '1.0.0', + }, + devDependencies: { + 'dev-dep': '1.0.0', + }, + optionalDependencies: { + 'not-skipped-optional': '1.0.0', + 'optional-dep': '1.0.0', + }, + specifiers: { + 'dev-dep': '^1.0.0', + 'not-skipped-optional': '^1.0.0', + 'optional-dep': '^1.0.0', + 'prod-dep': '^1.0.0', + }, + }, + 'project-2': { + dependencies: { + 'project-2-prod-dep': '1.0.0', + }, + specifiers: { + 'project-2-prod-dep': '^1.0.0', + }, + }, + }, + lockfileVersion: LOCKFILE_VERSION, + packages: { + '/bar/1.0.0': { + resolution: { integrity: '' }, + }, + '/dev-dep/1.0.0': { + dev: true, + resolution: { integrity: '' }, + }, + '/foo/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/not-skipped-optional/1.0.0': { + optional: true, + resolution: { integrity: '' }, + }, + '/optional-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + foo: '1.0.0', + }, + libc: ['glibc'], + optional: true, + resolution: { integrity: '' }, + }, + '/prod-dep-dep/1.0.0': { + resolution: { integrity: '' }, + }, + '/prod-dep/1.0.0': { + dependencies: { + bar: '1.0.0', + 'prod-dep-dep': '1.0.0', + }, + optionalDependencies: { + 'optional-dep': '1.0.0', + }, + resolution: { integrity: '' }, + }, + }, + }) + expect(Array.from(skippedPackages)).toStrictEqual(['/preserve-existing-skipped/1.0.0', '/optional-dep/1.0.0', '/foo/1.0.0']) +}) \ No newline at end of file diff --git a/packages/filter-lockfile/test/index.ts b/packages/filter-lockfile/test/index.ts deleted file mode 100644 index c4756985a4..0000000000 --- a/packages/filter-lockfile/test/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -/// -import './filterByImporters' -import './filterByImportersAndEngine' diff --git a/packages/headless/src/lockfileToDepGraph.ts b/packages/headless/src/lockfileToDepGraph.ts index e9c18d8b4d..c5d0e94099 100644 --- a/packages/headless/src/lockfileToDepGraph.ts +++ b/packages/headless/src/lockfileToDepGraph.ts @@ -108,6 +108,7 @@ export default async function lockfileToDepGraph ( engines: pkgSnapshot.engines, cpu: pkgSnapshot.cpu, os: pkgSnapshot.os, + libc: pkgSnapshot.libc, } if (!opts.force && packageIsInstallable(packageId, pkg, { diff --git a/packages/headless/src/lockfileToHoistedDepGraph.ts b/packages/headless/src/lockfileToHoistedDepGraph.ts index 4cd7b480a8..fdea99699d 100644 --- a/packages/headless/src/lockfileToHoistedDepGraph.ts +++ b/packages/headless/src/lockfileToHoistedDepGraph.ts @@ -157,6 +157,7 @@ async function fetchDeps ( engines: pkgSnapshot.engines, cpu: pkgSnapshot.cpu, os: pkgSnapshot.os, + libc: pkgSnapshot.libc, } if (!opts.force && packageIsInstallable(packageId, pkg, { diff --git a/packages/lockfile-file/package.json b/packages/lockfile-file/package.json index 4cba602c1e..f44cdb61fa 100644 --- a/packages/lockfile-file/package.json +++ b/packages/lockfile-file/package.json @@ -16,7 +16,8 @@ "_test": "jest", "test": "pnpm run compile && pnpm run _test", "prepublishOnly": "pnpm run compile", - "compile": "tsc --build && pnpm run lint --fix" + "compile": "tsc --build && pnpm run lint --fix", + "start": "tsc --watch" }, "repository": "https://github.com/pnpm/pnpm/blob/main/packages/lockfile-file", "keywords": [ @@ -53,7 +54,7 @@ "@pnpm/types": "workspace:8.0.1", "@zkochan/rimraf": "^2.1.2", "comver-to-semver": "^1.0.0", - "js-yaml": "npm:@zkochan/js-yaml@0.0.5", + "js-yaml": "npm:@zkochan/js-yaml@0.0.6", "normalize-path": "^3.0.0", "ramda": "^0.27.1", "semver": "^7.3.4", diff --git a/packages/lockfile-file/src/sortLockfileKeys.ts b/packages/lockfile-file/src/sortLockfileKeys.ts index ea5533e7b1..15e65b7c07 100644 --- a/packages/lockfile-file/src/sortLockfileKeys.ts +++ b/packages/lockfile-file/src/sortLockfileKeys.ts @@ -11,22 +11,23 @@ const ORDERED_KEYS = { engines: 5, cpu: 6, os: 7, + libc: 8, - deprecated: 8, - hasBin: 9, - prepare: 10, - requiresBuild: 11, + deprecated: 9, + hasBin: 10, + prepare: 11, + requiresBuild: 12, - bundleDependencies: 12, - peerDependencies: 13, - peerDependenciesMeta: 14, + bundleDependencies: 13, + peerDependencies: 14, + peerDependenciesMeta: 15, - dependencies: 15, - optionalDependencies: 16, + dependencies: 16, + optionalDependencies: 17, - transitivePeerDependencies: 17, - dev: 18, - optional: 19, + transitivePeerDependencies: 18, + dev: 19, + optional: 20, } const ROOT_KEYS_ORDER = { diff --git a/packages/lockfile-file/test/__snapshots__/write.test.ts.snap b/packages/lockfile-file/test/__snapshots__/write.test.ts.snap index 8219b4f045..a2bb8ce94e 100644 --- a/packages/lockfile-file/test/__snapshots__/write.test.ts.snap +++ b/packages/lockfile-file/test/__snapshots__/write.test.ts.snap @@ -18,6 +18,7 @@ packages: engines: {node: '>=10', npm: \\"\\\\nfoo\\\\n\\"} cpu: [x86] os: [darwin] + libc: [glibc] dependencies: is-positive: 2.0.0 diff --git a/packages/lockfile-file/test/write.test.ts b/packages/lockfile-file/test/write.test.ts index 4b256fec55..b25fcda23a 100644 --- a/packages/lockfile-file/test/write.test.ts +++ b/packages/lockfile-file/test/write.test.ts @@ -32,6 +32,7 @@ test('writeLockfiles()', async () => { 'is-positive': '2.0.0', }, cpu: ['x86'], + libc: ['glibc'], engines: { node: '>=10', npm: '\nfoo\n', diff --git a/packages/lockfile-types/src/index.ts b/packages/lockfile-types/src/index.ts index 92c6d14a90..832d7c03e9 100644 --- a/packages/lockfile-types/src/index.ts +++ b/packages/lockfile-types/src/index.ts @@ -90,6 +90,7 @@ export interface PackageSnapshot { } os?: string[] cpu?: string[] + libc?: string[] deprecated?: string } diff --git a/packages/package-is-installable/package.json b/packages/package-is-installable/package.json index 188e7ed07b..c2e2798080 100644 --- a/packages/package-is-installable/package.json +++ b/packages/package-is-installable/package.json @@ -32,6 +32,7 @@ "@pnpm/core-loggers": "workspace:7.0.1", "@pnpm/error": "workspace:3.0.1", "@pnpm/types": "workspace:8.0.1", + "detect-libc": "^2.0.1", "execa": "npm:safe-execa@^0.1.1", "mem": "^8.0.0", "semver": "^7.3.4" diff --git a/packages/package-is-installable/src/checkPlatform.ts b/packages/package-is-installable/src/checkPlatform.ts index 7a56d9342a..62e59ff224 100644 --- a/packages/package-is-installable/src/checkPlatform.ts +++ b/packages/package-is-installable/src/checkPlatform.ts @@ -1,4 +1,7 @@ import PnpmError from '@pnpm/error' +import { familySync as getLibcFamilySync } from 'detect-libc' + +const currentLibc = getLibcFamilySync() ?? 'unknown' export class UnsupportedPlatformError extends PnpmError { public wanted: WantedPlatform @@ -15,10 +18,8 @@ export default function checkPlatform ( packageId: string, wantedPlatform: WantedPlatform ) { - const platform = process.platform - const arch = process.arch - let osOk = true - let cpuOk = true + const { platform, arch } = process + let osOk = true; let cpuOk = true; let libcOk = true if (wantedPlatform.os) { osOk = checkList(platform, wantedPlatform.os) @@ -26,8 +27,12 @@ export default function checkPlatform ( if (wantedPlatform.cpu) { cpuOk = checkList(arch, wantedPlatform.cpu) } - if (!osOk || !cpuOk) { - return new UnsupportedPlatformError(packageId, wantedPlatform, { os: platform, cpu: arch }) + if (wantedPlatform.libc && currentLibc !== 'unknown') { + libcOk = checkList(currentLibc, wantedPlatform.libc) + } + + if (!osOk || !cpuOk || !libcOk) { + return new UnsupportedPlatformError(packageId, wantedPlatform, { os: platform, cpu: arch, libc: currentLibc }) } return null } @@ -35,14 +40,13 @@ export default function checkPlatform ( export interface Platform { cpu: string | string[] os: string | string[] + libc: string | string[] } export type WantedPlatform = Partial function checkList (value: string, list: string | string[]) { - let tmp - let match = false - let blc = 0 + let tmp; let match = false; let blc = 0 if (typeof list === 'string') { list = [list] } diff --git a/packages/package-is-installable/src/index.ts b/packages/package-is-installable/src/index.ts index cd537e911b..d3a9be0216 100644 --- a/packages/package-is-installable/src/index.ts +++ b/packages/package-is-installable/src/index.ts @@ -23,6 +23,7 @@ export default function packageIsInstallable ( engines?: WantedEngine cpu?: string[] os?: string[] + libc?: string[] }, options: { engineStrict?: boolean @@ -67,6 +68,7 @@ export function checkPackage ( engines?: WantedEngine cpu?: string[] os?: string[] + libc?: string[] }, options: { nodeVersion?: string @@ -76,6 +78,7 @@ export function checkPackage ( return checkPlatform(pkgId, { cpu: manifest.cpu ?? ['any'], os: manifest.os ?? ['any'], + libc: manifest.libc ?? ['any'], }) ?? ( (manifest.engines == null) ? null diff --git a/packages/package-is-installable/test/checkPlatform.ts b/packages/package-is-installable/test/checkPlatform.ts index 2cde1292db..0d8594bad1 100644 --- a/packages/package-is-installable/test/checkPlatform.ts +++ b/packages/package-is-installable/test/checkPlatform.ts @@ -2,10 +2,19 @@ import checkPlatform from '../lib/checkPlatform' const packageId = 'registry.npmjs.org/foo/1.0.0' +jest.mock('detect-libc', () => { + const orginal = jest.requireActual('detect-libc') + return { + ...orginal, + familySync: () => 'musl', + } +}) + test('target cpu wrong', () => { const target = { cpu: 'enten-cpu', os: 'any', + libc: 'any', } const err = checkPlatform(packageId, target) expect(err).toBeTruthy() @@ -16,6 +25,18 @@ test('os wrong', () => { const target = { cpu: 'any', os: 'enten-os', + libc: 'any', + } + const err = checkPlatform(packageId, target) + expect(err).toBeTruthy() + expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM') +}) + +test('libc wrong', () => { + const target = { + cpu: 'any', + os: 'any', + libc: 'enten-libc', } const err = checkPlatform(packageId, target) expect(err).toBeTruthy() @@ -26,34 +47,35 @@ test('nothing wrong', () => { const target = { cpu: 'any', os: 'any', + libc: 'any', } expect(checkPlatform(packageId, target)).toBeFalsy() }) test('only target cpu wrong', () => { - const err = checkPlatform(packageId, { cpu: 'enten-cpu', os: 'any' }) + const err = checkPlatform(packageId, { cpu: 'enten-cpu', os: 'any', libc: 'any' }) expect(err).toBeTruthy() expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM') }) test('only os wrong', () => { - const err = checkPlatform(packageId, { cpu: 'any', os: 'enten-os' }) + const err = checkPlatform(packageId, { cpu: 'any', os: 'enten-os', libc: 'any' }) expect(err).toBeTruthy() expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM') }) test('everything wrong w/arrays', () => { - const err = checkPlatform(packageId, { cpu: ['enten-cpu'], os: ['enten-os'] }) + const err = checkPlatform(packageId, { cpu: ['enten-cpu'], os: ['enten-os'], libc: ['enten-libc'] }) expect(err).toBeTruthy() expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM') }) test('os wrong (negation)', () => { - const err = checkPlatform(packageId, { cpu: 'any', os: `!${process.platform}` }) + const err = checkPlatform(packageId, { cpu: 'any', os: `!${process.platform}`, libc: 'any' }) expect(err).toBeTruthy() expect(err?.code).toBe('ERR_PNPM_UNSUPPORTED_PLATFORM') }) test('nothing wrong (negation)', () => { - expect(checkPlatform(packageId, { cpu: '!enten-cpu', os: '!enten-os' })).toBe(null) + expect(checkPlatform(packageId, { cpu: '!enten-cpu', os: '!enten-os', libc: '!enten-libc' })).toBe(null) }) diff --git a/packages/resolve-dependencies/src/resolveDependencies.ts b/packages/resolve-dependencies/src/resolveDependencies.ts index 98df169c1e..97e35789cb 100644 --- a/packages/resolve-dependencies/src/resolveDependencies.ts +++ b/packages/resolve-dependencies/src/resolveDependencies.ts @@ -197,6 +197,7 @@ export interface ResolvedPackage { } cpu?: string[] os?: string[] + libc?: string[] } } @@ -878,6 +879,7 @@ function getResolvedPackage ( deprecated: options.pkg.deprecated, engines: options.pkg.engines, os: options.pkg.os, + libc: options.pkg.libc, }, depPath: options.depPath, dev: options.wantedDependency.dev, diff --git a/packages/resolve-dependencies/src/updateLockfile.ts b/packages/resolve-dependencies/src/updateLockfile.ts index d2b3f4855a..2290f9f4b7 100644 --- a/packages/resolve-dependencies/src/updateLockfile.ts +++ b/packages/resolve-dependencies/src/updateLockfile.ts @@ -144,6 +144,9 @@ function toLockfileDependency ( if (pkg.additionalInfo.os != null) { result['os'] = pkg.additionalInfo.os } + if (pkg.additionalInfo.libc != null) { + result['libc'] = pkg.additionalInfo.libc + } if (Array.isArray(pkg.additionalInfo.bundledDependencies) || Array.isArray(pkg.additionalInfo.bundleDependencies)) { result['bundledDependencies'] = pkg.additionalInfo.bundledDependencies ?? pkg.additionalInfo.bundleDependencies } diff --git a/packages/types/src/package.ts b/packages/types/src/package.ts index 66ea249d7a..4d1bb00b41 100644 --- a/packages/types/src/package.ts +++ b/packages/types/src/package.ts @@ -93,6 +93,7 @@ export interface BaseManifest { } cpu?: string[] os?: string[] + libc?: string[] main?: string module?: string typings?: string diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 531bcd5fb0..f1620a1eeb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,7 +12,7 @@ overrides: hosted-git-info@4: npm:@zkochan/hosted-git-info@^4.0.2 http-errors: ^1.7.3 istanbul-reports: npm:@zkochan/istanbul-reports - js-yaml@^4.0.0: npm:@zkochan/js-yaml@0.0.5 + js-yaml@^4.0.0: npm:@zkochan/js-yaml@0.0.6 lodash@<4.17.19: ^4.17.9 nopt@5: npm:@pnpm/nopt@^0.2.1 pkg-fetch: 3.1.1 @@ -879,6 +879,7 @@ importers: '@pnpm/types': workspace:8.0.1 '@types/ramda': 0.27.39 dependency-path: workspace:9.1.1 + detect-libc: ^2.0.1 ramda: ^0.27.1 tempy: ^1.0.0 write-yaml-file: ^4.2.0 @@ -897,6 +898,7 @@ importers: '@pnpm/filter-lockfile': 'link:' '@pnpm/logger': 4.0.0 '@types/ramda': 0.27.39 + detect-libc: 2.0.1 tempy: 1.0.1 write-yaml-file: 4.2.0 yaml-tag: 1.1.0 @@ -1383,7 +1385,7 @@ importers: '@types/write-file-atomic': ^3.0.1 '@zkochan/rimraf': ^2.1.2 comver-to-semver: ^1.0.0 - js-yaml: npm:@zkochan/js-yaml@0.0.5 + js-yaml: npm:@zkochan/js-yaml@0.0.6 normalize-path: ^3.0.0 ramda: ^0.27.1 semver: ^7.3.4 @@ -1401,7 +1403,7 @@ importers: '@pnpm/types': link:../types '@zkochan/rimraf': 2.1.2 comver-to-semver: 1.0.0 - js-yaml: /@zkochan/js-yaml/0.0.5 + js-yaml: /@zkochan/js-yaml/0.0.6 normalize-path: 3.0.0 ramda: 0.27.2 semver: 7.3.7 @@ -1835,6 +1837,7 @@ importers: '@pnpm/package-is-installable': workspace:6.0.2 '@pnpm/types': workspace:8.0.1 '@types/semver': ^7.3.4 + detect-libc: ^2.0.1 execa: npm:safe-execa@^0.1.1 mem: ^8.0.0 semver: ^7.3.4 @@ -1842,6 +1845,7 @@ importers: '@pnpm/core-loggers': link:../core-loggers '@pnpm/error': link:../error '@pnpm/types': link:../types + detect-libc: 2.0.1 execa: /safe-execa/0.1.1 mem: 8.1.1 semver: 7.3.7 @@ -4535,7 +4539,7 @@ packages: globals: 13.13.0 ignore: 5.2.0 import-fresh: 3.3.0 - js-yaml: /@zkochan/js-yaml/0.0.5 + js-yaml: /@zkochan/js-yaml/0.0.6 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -6018,8 +6022,8 @@ packages: istanbul-lib-report: 3.0.0 dev: true - /@zkochan/js-yaml/0.0.5: - resolution: {integrity: sha512-/uaB1kf+t+UATNUSyzHSzy4JqKOh2Y77gdCnhQEKTX/vrpQp8qjvohvC6eG9X4spQf0a8TKL0qF5LiFNj+GrJw==} + /@zkochan/js-yaml/0.0.6: + resolution: {integrity: sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==} hasBin: true dependencies: argparse: 2.0.1 @@ -7753,6 +7757,10 @@ packages: hasBin: true dev: true + /detect-libc/2.0.1: + resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} + engines: {node: '>=8'} + /detect-newline/3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -8470,7 +8478,7 @@ packages: import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 - js-yaml: /@zkochan/js-yaml/0.0.5 + js-yaml: /@zkochan/js-yaml/0.0.6 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 lodash.merge: 4.6.2 @@ -12909,7 +12917,7 @@ packages: resolution: {integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==} engines: {node: '>=10.13'} dependencies: - js-yaml: /@zkochan/js-yaml/0.0.5 + js-yaml: /@zkochan/js-yaml/0.0.6 strip-bom: 4.0.0 /readable-stream/2.3.7: @@ -14851,7 +14859,7 @@ packages: fast-safe-stringify: 2.1.1 handlebars: 4.7.7 http-errors: 1.8.1 - js-yaml: /@zkochan/js-yaml/0.0.5 + js-yaml: /@zkochan/js-yaml/0.0.6 JSONStream: 1.3.5 jsonwebtoken: 8.5.1 kleur: 4.1.4 @@ -15185,7 +15193,7 @@ packages: resolution: {integrity: sha512-LwyucHy0uhWqbrOkh9cBluZBeNVxzHjDaE9mwepZG3n3ZlbM4v3ndrFw51zW/NXYFFqP+QWZ72ihtLWTh05e4Q==} engines: {node: '>=10.13'} dependencies: - js-yaml: /@zkochan/js-yaml/0.0.5 + js-yaml: /@zkochan/js-yaml/0.0.6 write-file-atomic: 3.0.3 /ws/7.5.7: