From 2105735a0cde41fca8cb7b3582043e72df3a6c43 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Thu, 30 Jun 2022 16:11:01 +0300 Subject: [PATCH] fix(env): throw an error on a system that uses MUSL libc (#4958) --- .changeset/strong-ways-tap.md | 6 ++++++ packages/node.fetcher/package.json | 4 +++- packages/node.fetcher/src/index.ts | 5 +++++ packages/node.fetcher/test/node.test.ts | 19 +++++++++++++++++++ packages/node.fetcher/tsconfig.json | 3 +++ pnpm-lock.yaml | 4 ++++ 6 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 .changeset/strong-ways-tap.md diff --git a/.changeset/strong-ways-tap.md b/.changeset/strong-ways-tap.md new file mode 100644 index 0000000000..15b3b2789e --- /dev/null +++ b/.changeset/strong-ways-tap.md @@ -0,0 +1,6 @@ +--- +"@pnpm/node.fetcher": patch +"pnpm": patch +--- + +`pnpm env use` should throw an error on a system that use the MUSL libc. diff --git a/packages/node.fetcher/package.json b/packages/node.fetcher/package.json index e9d3cfb5ae..d1a71be95d 100644 --- a/packages/node.fetcher/package.json +++ b/packages/node.fetcher/package.json @@ -36,10 +36,12 @@ "homepage": "https://github.com/pnpm/pnpm/blob/main/packages/node.fetcher#readme", "dependencies": { "@pnpm/create-cafs-store": "workspace:2.0.2", - "@pnpm/fetching-types": "workspace:3.0.0", + "@pnpm/error": "workspace:3.0.1", "@pnpm/fetcher-base": "workspace:13.0.1", + "@pnpm/fetching-types": "workspace:3.0.0", "@pnpm/tarball-fetcher": "workspace:10.0.8", "adm-zip": "^0.5.5", + "detect-libc": "^2.0.1", "rename-overwrite": "^4.0.2", "tempy": "^1.0.0" }, diff --git a/packages/node.fetcher/src/index.ts b/packages/node.fetcher/src/index.ts index ffee072cbd..9a53701d7d 100644 --- a/packages/node.fetcher/src/index.ts +++ b/packages/node.fetcher/src/index.ts @@ -1,5 +1,6 @@ import fs from 'fs' import path from 'path' +import PnpmError from '@pnpm/error' import { FetchFromRegistry, RetryTimeoutOptions, @@ -10,6 +11,7 @@ import createFetcher, { waitForFilesIndex } from '@pnpm/tarball-fetcher' import AdmZip from 'adm-zip' import renameOverwrite from 'rename-overwrite' import tempy from 'tempy' +import { isNonGlibcLinux } from 'detect-libc' import { getNodeTarball } from './getNodeTarball' export interface FetchNodeOptions { @@ -20,6 +22,9 @@ export interface FetchNodeOptions { } export async function fetchNode (fetch: FetchFromRegistry, version: string, targetDir: string, opts: FetchNodeOptions) { + if (await isNonGlibcLinux()) { + throw new PnpmError('MUSL', 'The current system uses the "MUSL" C standard library. Node.js currently has prebuilt artifacts only for the "glibc" libc, so we can install Node.js only for glibc') + } const nodeMirrorBaseUrl = opts.nodeMirrorBaseUrl ?? 'https://nodejs.org/download/release/' const { tarball, pkgName } = getNodeTarball(version, nodeMirrorBaseUrl, process.platform, process.arch) if (tarball.endsWith('.zip')) { diff --git a/packages/node.fetcher/test/node.test.ts b/packages/node.fetcher/test/node.test.ts index dc32401628..955dbf9017 100644 --- a/packages/node.fetcher/test/node.test.ts +++ b/packages/node.fetcher/test/node.test.ts @@ -4,6 +4,11 @@ import path from 'path' import { Readable } from 'stream' import { fetchNode, FetchNodeOptions } from '@pnpm/node.fetcher' import { tempDir } from '@pnpm/prepare' +import { isNonGlibcLinux } from 'detect-libc' + +jest.mock('detect-libc', () => ({ + isNonGlibcLinux: jest.fn(), +})) const fetchMock = jest.fn(async (url: string) => { if (url.endsWith('.zip')) { @@ -20,6 +25,7 @@ const fetchMock = jest.fn(async (url: string) => { }) beforeEach(() => { + isNonGlibcLinux['mockReturnValue'](Promise.resolve(false)) fetchMock.mockClear() }) @@ -52,3 +58,16 @@ test('install Node using the default node mirror', async () => { expect(call[0]).toMatch('https://nodejs.org/download/release/') } }) + +test('install Node using a custom node mirror', async () => { + isNonGlibcLinux['mockReturnValue'](Promise.resolve(true)) + tempDir() + + const opts: FetchNodeOptions = { + cafsDir: path.resolve('files'), + } + + await expect( + fetchNode(fetchMock, '16.4.0', path.resolve('node'), opts) + ).rejects.toThrow('The current system uses the "MUSL" C standard library. Node.js currently has prebuilt artifacts only for the "glibc" libc, so we can install Node.js only for glibc') +}) diff --git a/packages/node.fetcher/tsconfig.json b/packages/node.fetcher/tsconfig.json index a706e0b485..322ea6f9da 100644 --- a/packages/node.fetcher/tsconfig.json +++ b/packages/node.fetcher/tsconfig.json @@ -15,6 +15,9 @@ { "path": "../create-cafs-store" }, + { + "path": "../error" + }, { "path": "../fetcher-base" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad1aaa0853..284f0b03d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1736,6 +1736,7 @@ importers: packages/node.fetcher: specifiers: '@pnpm/create-cafs-store': workspace:2.0.2 + '@pnpm/error': workspace:3.0.1 '@pnpm/fetcher-base': workspace:13.0.1 '@pnpm/fetching-types': workspace:3.0.0 '@pnpm/node.fetcher': workspace:1.0.3 @@ -1743,15 +1744,18 @@ importers: '@pnpm/tarball-fetcher': workspace:10.0.8 '@types/adm-zip': ^0.4.34 adm-zip: ^0.5.5 + detect-libc: ^2.0.1 node-fetch: 3.0.0-beta.9 rename-overwrite: ^4.0.2 tempy: ^1.0.0 dependencies: '@pnpm/create-cafs-store': link:../create-cafs-store + '@pnpm/error': link:../error '@pnpm/fetcher-base': link:../fetcher-base '@pnpm/fetching-types': link:../fetching-types '@pnpm/tarball-fetcher': link:../tarball-fetcher adm-zip: 0.5.9 + detect-libc: 2.0.1 rename-overwrite: 4.0.2 tempy: 1.0.1 devDependencies: