From b56df30796da9c7cb0ba5e1bb7152c81582abba6 Mon Sep 17 00:00:00 2001 From: Kristoffer K Date: Tue, 29 Sep 2020 15:02:59 -0700 Subject: [PATCH] fix: avoid symlinks to work on Windows (#13) --- sources/Engine.ts | 7 ++++++- sources/commands/Prepare.ts | 4 ++-- sources/fsUtils.ts | 7 ------- sources/main.ts | 4 ++-- sources/pmmUtils.ts | 35 ++++++++++++++++------------------- 5 files changed, 26 insertions(+), 31 deletions(-) diff --git a/sources/Engine.ts b/sources/Engine.ts index 892e283c1..dc38e1e99 100644 --- a/sources/Engine.ts +++ b/sources/Engine.ts @@ -77,9 +77,14 @@ export class Engine { if (typeof range === `undefined`) throw new Error(`Assertion failed: Specified resolution (${locator.reference}) isn't supported by any of ${ranges.join(`, `)}`); - return await pmmUtils.installVersion(folderUtils.getInstallFolder(), locator, { + const installedLocation = await pmmUtils.installVersion(folderUtils.getInstallFolder(), locator, { spec: definition.ranges[range], }); + + return { + location: installedLocation, + spec: definition.ranges[range], + }; } async resolveDescriptor(descriptor: Descriptor, {useCache = true}: {useCache?: boolean} = {}) { diff --git a/sources/commands/Prepare.ts b/sources/commands/Prepare.ts index 20a9d3349..4d196a79c 100644 --- a/sources/commands/Prepare.ts +++ b/sources/commands/Prepare.ts @@ -75,7 +75,7 @@ export class PrepareCommand extends Command { throw new UsageError(`Failed to successfully resolve '${spec.range}' to a valid ${spec.name} release`); const baseInstallFolder = folderUtils.getInstallFolder(); - const installFolder = await this.context.engine.ensurePackageManager(resolved); + const installSpec = await this.context.engine.ensurePackageManager(resolved); if (this.activate) await this.context.engine.activatePackageManager(resolved); @@ -87,7 +87,7 @@ export class PrepareCommand extends Command { ? path.join(this.context.cwd, `corepack-${resolved.name}-${resolved.reference}.tgz`) : path.join(this.context.cwd, `corepack-${resolved.name}.tgz`); - await tar.c({gzip: true, cwd: baseInstallFolder, file: fileName}, [path.relative(baseInstallFolder, installFolder)]); + await tar.c({gzip: true, cwd: baseInstallFolder, file: fileName}, [path.relative(baseInstallFolder, installSpec.location)]); if (this.json) { this.context.stdout.write(`${JSON.stringify(fileName)}\n`); diff --git a/sources/fsUtils.ts b/sources/fsUtils.ts index 5ee9d78dc..660052f58 100644 --- a/sources/fsUtils.ts +++ b/sources/fsUtils.ts @@ -1,10 +1,3 @@ -import fs from 'fs'; -import {dirname, relative} from 'path'; - export async function mutex(p: string, cb: () => Promise) { return await cb(); } - -export async function makeShim(target: string, path: string) { - await fs.promises.symlink(relative(dirname(target), path), target, `file`); -} diff --git a/sources/main.ts b/sources/main.ts index 17ad91246..ec68403ac 100644 --- a/sources/main.ts +++ b/sources/main.ts @@ -48,8 +48,8 @@ export async function main(argv: Array, context: CustomContext & Partial if (resolved === null) throw new UsageError(`Failed to successfully resolve '${descriptor.range}' to a valid ${descriptor.name} release`); - const installTarget = await context.engine.ensurePackageManager(resolved); - const exitCode = await pmmUtils.runVersion(installTarget, resolved, binaryName, this.proxy, this.context); + const installSpec = await context.engine.ensurePackageManager(resolved); + const exitCode = await pmmUtils.runVersion(installSpec, resolved, binaryName, this.proxy, this.context); return exitCode; } diff --git a/sources/pmmUtils.ts b/sources/pmmUtils.ts index bd39cdfe3..455d56352 100644 --- a/sources/pmmUtils.ts +++ b/sources/pmmUtils.ts @@ -119,22 +119,6 @@ export async function installVersion(installTarget: string, locator: Locator, {s sendTo.on(`finish`, resolve); }); - await fs.promises.mkdir(path.join(tmpFolder, `.bin`)); - - if (Array.isArray(spec.bin)) { - if (outputFile !== null) { - for (const name of spec.bin) { - await fsUtils.makeShim(path.join(tmpFolder, `.bin`, name), outputFile); - } - } else { - throw new Error(`Assertion failed`); - } - } else { - for (const [name, dest] of Object.entries(spec.bin)) { - fsUtils.makeShim(path.join(tmpFolder, `.bin`, name), path.join(tmpFolder, dest)); - } - } - await fs.promises.mkdir(path.dirname(installFolder), {recursive: true}); await fs.promises.rename(tmpFolder, installFolder); @@ -143,8 +127,21 @@ export async function installVersion(installTarget: string, locator: Locator, {s }); } -export async function runVersion(installTarget: string, locator: Locator, binName: string, args: Array, context: Context) { - const binPath = path.join(installTarget, `.bin`, binName); +export async function runVersion(installSpec: { location: string, spec: PackageManagerSpec }, locator: Locator, binName: string, args: Array, context: Context) { + let binPath: string | null = null; + if (Array.isArray(installSpec.spec.bin)) { + binPath = path.join(installSpec.location, `${binName}.js`); + } else { + for (const [name, dest] of Object.entries(installSpec.spec.bin)) { + if (name === binName) { + binPath = path.join(installSpec.location, dest); + break; + } + } + } + + if (!binPath) + throw new Error(`Assertion failed: Unable to locate bin path`); return new Promise((resolve, reject) => { process.on(`SIGINT`, () => { @@ -162,7 +159,7 @@ export async function runVersion(installTarget: string, locator: Locator, binNam if (context.stderr === process.stderr) stdio[2] = `inherit`; - const sub = spawn(process.execPath, [binPath, ...args], { + const sub = spawn(process.execPath, [binPath!, ...args], { cwd: context.cwd, stdio, });