diff --git a/packages/hoist/src/index.ts b/packages/hoist/src/index.ts index 85c5651839..a6f0264f24 100644 --- a/packages/hoist/src/index.ts +++ b/packages/hoist/src/index.ts @@ -1,5 +1,5 @@ import { WANTED_LOCKFILE } from '@pnpm/constants' -import linkBins from '@pnpm/link-bins' +import linkBins, { WarnFunction } from '@pnpm/link-bins' import { Lockfile, nameVerFromPkgSnapshot, @@ -62,7 +62,10 @@ export default async function hoistByLockfile ( }) const bin = path.join(opts.modulesDir, '.bin') - const warn = (message: string) => logger.warn({ message, prefix: path.join(opts.modulesDir, '../..') }) + const warn: WarnFunction = (message, code) => { + if (code === 'BINARIES_CONFLICT') return + logger.warn({ message, prefix: path.join(opts.modulesDir, '../..') }) + } try { await linkBins(opts.modulesDir, bin, { allowExoticManifests: true, warn }) } catch (err) { diff --git a/packages/link-bins/src/index.ts b/packages/link-bins/src/index.ts index 7cc95d330a..4dd9e7e773 100644 --- a/packages/link-bins/src/index.ts +++ b/packages/link-bins/src/index.ts @@ -19,7 +19,9 @@ const IS_WINDOWS = isWindows() const EXECUTABLE_SHEBANG_SUPPORTED = !IS_WINDOWS const POWER_SHELL_IS_SUPPORTED = IS_WINDOWS -export type WarnFunction = (msg: string) => void +export type WarningCode = 'BINARIES_CONFLICT' | 'EMPTY_BIN' + +export type WarnFunction = (msg: string, code: WarningCode) => void export default async ( modulesDir: string, @@ -94,7 +96,7 @@ async function linkBins ( const usedNames = R.fromPairs(cmdsWithOwnName.map((cmd) => [cmd.name, cmd.name] as R.KeyValuePair)) const results2 = await pSettle(cmdsWithOtherNames.map((cmd: Command & {pkgName: string}) => { if (usedNames[cmd.name]) { - opts.warn(`Cannot link bin "${cmd.name}" of "${cmd.pkgName}" to "${binsDir}". A package called "${usedNames[cmd.name]}" already has its bin linked.`) + opts.warn(`Cannot link binary '${cmd.name}' of '${cmd.pkgName}' to '${binsDir}': binary of '${usedNames[cmd.name]}' is already linked`, 'BINARIES_CONFLICT') return Promise.resolve(undefined) } usedNames[cmd.name] = cmd.pkgName @@ -133,7 +135,7 @@ async function getPackageBins ( } if (R.isEmpty(manifest.bin) && !await isFromModules(target)) { - opts.warn(`Package in ${target} must have a non-empty bin field to get bin linked.`) + opts.warn(`Package in ${target} must have a non-empty bin field to get bin linked.`, 'EMPTY_BIN') } if (typeof manifest.bin === 'string' && !manifest.name) { diff --git a/packages/link-bins/test/index.ts b/packages/link-bins/test/index.ts index a5c37ee48b..05c959f12a 100644 --- a/packages/link-bins/test/index.ts +++ b/packages/link-bins/test/index.ts @@ -167,7 +167,7 @@ test('linkBins() resolves conflicts. Prefer packages that use their name as bin await linkBins(path.join(binNameConflictsFixture, 'node_modules'), binTarget, { warn }) - t.ok(warn.calledWith(`Cannot link bin "bar" of "foo" to "${binTarget}". A package called "bar" already has its bin linked.`)) + t.equal(warn.args[0][0], `Cannot link binary 'bar' of 'foo' to '${binTarget}': binary of 'bar' is already linked`) t.deepEqual(await fs.readdir(binTarget), getExpectedBins(['bar', 'foofoo'])) { @@ -209,7 +209,7 @@ test('linkBinsOfPackages() resolves conflicts. Prefer packages that use their na { warn }, ) - t.ok(warn.calledWith(`Cannot link bin "bar" of "foo" to "${binTarget}". A package called "bar" already has its bin linked.`)) + t.equal(warn.args[0][0], `Cannot link binary 'bar' of 'foo' to '${binTarget}': binary of 'bar' is already linked`) t.deepEqual(await fs.readdir(binTarget), getExpectedBins(['bar', 'foofoo'])) {