mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-02 05:57:27 -05:00
* feat(env): add uninstall command to pnpm env * chore(changeset): define minor bump * fix(env): fixes for pnpm env uninstall - Fix broken node path for the windows platform - Notify user when removing default Node.JS - Remove `await` on `fs.unlink` in `Promise.all` - Add support for Node.JS v14.13 and earlier * fix(env): fix failing tests on Windows platform * fix(env): update aliases and error catching - Add `rm, un, uninstall` aliases to the `remove` command - Update CLI help message - Ignore only `ENOENT` errors * refactor(env): cr updates - Use `remove` with `rm` alias only - Update CLI help message - Update tests to use `remove` command - Replace custom support for older Node.JS versions with `@zkochan/rimraf` * refactor(env): simplify catch block * fix: env rm * refactor: test Co-authored-by: Mark Omarov <inkfaust@gmail.com> Co-authored-by: Zoltan Kochan <z@kochan.io>
100 lines
3.2 KiB
TypeScript
100 lines
3.2 KiB
TypeScript
import fs from 'fs'
|
|
import path from 'path'
|
|
import { Config } from '@pnpm/config'
|
|
import { createFetchFromRegistry, FetchFromRegistry } from '@pnpm/fetch'
|
|
import { globalInfo } from '@pnpm/logger'
|
|
import { fetchNode } from '@pnpm/node.fetcher'
|
|
import storePath from '@pnpm/store-path'
|
|
import loadJsonFile from 'load-json-file'
|
|
import writeJsonFile from 'write-json-file'
|
|
import getNodeMirror from './getNodeMirror'
|
|
import { parseNodeEditionSpecifier } from './parseNodeEditionSpecifier'
|
|
|
|
export type NvmNodeCommandOptions = Pick<Config,
|
|
| 'bin'
|
|
| 'global'
|
|
| 'fetchRetries'
|
|
| 'fetchRetryFactor'
|
|
| 'fetchRetryMaxtimeout'
|
|
| 'fetchRetryMintimeout'
|
|
| 'fetchTimeout'
|
|
| 'userAgent'
|
|
| 'ca'
|
|
| 'cert'
|
|
| 'httpProxy'
|
|
| 'httpsProxy'
|
|
| 'key'
|
|
| 'localAddress'
|
|
| 'noProxy'
|
|
| 'rawConfig'
|
|
| 'strictSsl'
|
|
| 'storeDir'
|
|
| 'useNodeVersion'
|
|
| 'pnpmHomeDir'
|
|
> & Partial<Pick<Config, 'configDir'>>
|
|
|
|
export async function getNodeBinDir (opts: NvmNodeCommandOptions) {
|
|
const fetch = createFetchFromRegistry(opts)
|
|
const nodesDir = getNodeVersionsBaseDir(opts.pnpmHomeDir)
|
|
let wantedNodeVersion = opts.useNodeVersion ?? (await readNodeVersionsManifest(nodesDir))?.default
|
|
if (wantedNodeVersion == null) {
|
|
const response = await fetch('https://registry.npmjs.org/node')
|
|
wantedNodeVersion = (await response.json() as any)['dist-tags'].lts // eslint-disable-line
|
|
if (wantedNodeVersion == null) {
|
|
throw new Error('Could not resolve LTS version of Node.js')
|
|
}
|
|
await writeJsonFile(path.join(nodesDir, 'versions.json'), {
|
|
default: wantedNodeVersion,
|
|
})
|
|
}
|
|
const { versionSpecifier, releaseChannel } = parseNodeEditionSpecifier(wantedNodeVersion)
|
|
const nodeMirrorBaseUrl = getNodeMirror(opts.rawConfig, releaseChannel)
|
|
const nodeDir = await getNodeDir(fetch, {
|
|
...opts,
|
|
useNodeVersion: versionSpecifier,
|
|
nodeMirrorBaseUrl,
|
|
})
|
|
return process.platform === 'win32' ? nodeDir : path.join(nodeDir, 'bin')
|
|
}
|
|
|
|
export function getNodeVersionsBaseDir (pnpmHomeDir: string) {
|
|
return path.join(pnpmHomeDir, 'nodejs')
|
|
}
|
|
|
|
export async function getNodeDir (fetch: FetchFromRegistry, opts: NvmNodeCommandOptions & { useNodeVersion: string, nodeMirrorBaseUrl: string }) {
|
|
const nodesDir = getNodeVersionsBaseDir(opts.pnpmHomeDir)
|
|
await fs.promises.mkdir(nodesDir, { recursive: true })
|
|
const versionDir = path.join(nodesDir, opts.useNodeVersion)
|
|
if (!fs.existsSync(versionDir)) {
|
|
const storeDir = await storePath({
|
|
pkgRoot: process.cwd(),
|
|
storePath: opts.storeDir,
|
|
pnpmHomeDir: opts.pnpmHomeDir,
|
|
})
|
|
const cafsDir = path.join(storeDir, 'files')
|
|
globalInfo(`Fetching Node.js ${opts.useNodeVersion} ...`)
|
|
await fetchNode(fetch, opts.useNodeVersion, versionDir, {
|
|
...opts,
|
|
cafsDir,
|
|
retry: {
|
|
maxTimeout: opts.fetchRetryMaxtimeout,
|
|
minTimeout: opts.fetchRetryMintimeout,
|
|
retries: opts.fetchRetries,
|
|
factor: opts.fetchRetryFactor,
|
|
},
|
|
})
|
|
}
|
|
return versionDir
|
|
}
|
|
|
|
async function readNodeVersionsManifest (nodesDir: string): Promise<{ default?: string }> {
|
|
try {
|
|
return await loadJsonFile<{ default?: string }>(path.join(nodesDir, 'versions.json'))
|
|
} catch (err: any) { // eslint-disable-line
|
|
if (err.code === 'ENOENT') {
|
|
return {}
|
|
}
|
|
throw err
|
|
}
|
|
}
|