From 063368b7d5805653121b3f5702fbedc2a8043018 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Thu, 2 May 2019 23:33:10 +0300 Subject: [PATCH] feat: "pnpm run" supports package.{json5,yaml} ref #1803 --- packages/lifecycle/src/runLifecycleHook.ts | 26 +++++++++++--- packages/pnpm/src/bin/pnpm.ts | 2 -- packages/pnpm/src/cmd/index.ts | 2 ++ packages/pnpm/src/cmd/run.ts | 42 ++++++++++++++++++++++ packages/pnpm/src/main.ts | 1 + packages/pnpm/test/run.ts | 1 + 6 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 packages/pnpm/src/cmd/run.ts diff --git a/packages/lifecycle/src/runLifecycleHook.ts b/packages/lifecycle/src/runLifecycleHook.ts index 1432624c169..fff78224bdd 100644 --- a/packages/lifecycle/src/runLifecycleHook.ts +++ b/packages/lifecycle/src/runLifecycleHook.ts @@ -1,13 +1,14 @@ import { lifecycleLogger } from '@pnpm/core-loggers' -import { PackageJson } from '@pnpm/types' +import { DependencyManifest, ImporterManifest } from '@pnpm/types' import lifecycle = require('@zkochan/npm-lifecycle') function noop () {} // tslint:disable-line:no-empty export default async function runLifecycleHook ( stage: string, - pkg: PackageJson, + manifest: ImporterManifest | DependencyManifest, opts: { + args?: string[], depPath: string, optional?: boolean, pkgRoot: string, @@ -22,13 +23,20 @@ export default async function runLifecycleHook ( lifecycleLogger.debug({ depPath: opts.depPath, optional, - script: pkg.scripts![stage], + script: manifest.scripts![stage], stage, wd: opts.pkgRoot, }) } - return lifecycle(pkg, stage, opts.pkgRoot, { + const m = { _id: getId(manifest), ...manifest } + if (opts.args && opts.args.length && m.scripts && m.scripts[stage]) { + m.scripts = { + ...m.scripts, + [stage]: `${m.scripts[stage]} ${opts.args.map((arg) => `"${arg}"`).join(' ')}`, + } + } + return lifecycle(m, stage, opts.pkgRoot, { config: opts.rawNpmConfig, dir: opts.rootNodeModulesDir, log: { @@ -76,3 +84,13 @@ export default async function runLifecycleHook ( } } } + +function getId (manifest: ImporterManifest | DependencyManifest) { + if (!manifest.name) { + return undefined + } + if (!manifest.version) { + return manifest.name + } + return `${manifest.name}@${manifest.version}` +} diff --git a/packages/pnpm/src/bin/pnpm.ts b/packages/pnpm/src/bin/pnpm.ts index b3d8cfacfbb..817da381a7e 100755 --- a/packages/pnpm/src/bin/pnpm.ts +++ b/packages/pnpm/src/bin/pnpm.ts @@ -66,8 +66,6 @@ if (argv.includes('--help') || argv.includes('-h') || argv.includes('--h')) { case 't': case 'tst': case 'test': - case 'run': - case 'run-script': if (argv.includes('--filter')) { await runPnpm() } else { diff --git a/packages/pnpm/src/cmd/index.ts b/packages/pnpm/src/cmd/index.ts index a404e5eb498..a8a66d1fd52 100644 --- a/packages/pnpm/src/cmd/index.ts +++ b/packages/pnpm/src/cmd/index.ts @@ -9,6 +9,7 @@ import prune from './prune' import rebuild from './rebuild' import recursive from './recursive' import root from './root' +import run from './run' import server from './server' import store from './store' import uninstall from './uninstall' @@ -27,6 +28,7 @@ export default { rebuild, recursive, root, + run, server, store, uninstall, diff --git a/packages/pnpm/src/cmd/run.ts b/packages/pnpm/src/cmd/run.ts new file mode 100644 index 00000000000..d324c29d170 --- /dev/null +++ b/packages/pnpm/src/cmd/run.ts @@ -0,0 +1,42 @@ +import runLifecycleHooks from '@pnpm/lifecycle' +import { readImporterManifestOnly } from '@pnpm/read-importer-manifest' +import { realNodeModulesDir } from '@pnpm/utils' + +export default async function ( + args: string[], + opts: { + prefix: string, + rawNpmConfig: object, + argv: { + cooked: string[], + original: string[], + remain: string[], + }, + }, + command: string, +) { + const manifest = await readImporterManifestOnly(opts.prefix) + const scriptName = args[0] + if (!manifest.scripts || !manifest.scripts[scriptName]) { + const err = new Error(`Missing script: ${scriptName}`) + err['code'] = 'ERR_PNPM_NO_SCRIPT' + throw err + } + const dashDashIndex = opts.argv.cooked.indexOf('--') + const lifecycleOpts = { + args: dashDashIndex === -1 ? [] : opts.argv.cooked.slice(dashDashIndex + 1), + depPath: opts.prefix, + pkgRoot: opts.prefix, + rawNpmConfig: opts.rawNpmConfig, + rootNodeModulesDir: await realNodeModulesDir(opts.prefix), + stdio: 'inherit', + unsafePerm: true, // when running scripts explicitly, assume that they're trusted. + } + if (manifest.scripts[`pre${scriptName}`]) { + await runLifecycleHooks(`pre${scriptName}`, manifest, lifecycleOpts) + } + await runLifecycleHooks(scriptName, manifest, lifecycleOpts) + if (manifest.scripts[`post${scriptName}`]) { + await runLifecycleHooks(`post${scriptName}`, manifest, lifecycleOpts) + } +} diff --git a/packages/pnpm/src/main.ts b/packages/pnpm/src/main.ts index af2f1070c2b..9eff5cb634d 100644 --- a/packages/pnpm/src/main.ts +++ b/packages/pnpm/src/main.ts @@ -181,6 +181,7 @@ export default async function run (argv: string[]) { optionalDependencies: opts.optional !== false, } opts.forceSharedLockfile = typeof opts.workspacePrefix === 'string' && opts.sharedWorkspaceLockfile === true + opts.argv = cliConf.argv if (opts.filter) { Array.prototype.push.apply(opts.filter, filterArgs) } else { diff --git a/packages/pnpm/test/run.ts b/packages/pnpm/test/run.ts index 6ccb70d5072..fe6231473a3 100644 --- a/packages/pnpm/test/run.ts +++ b/packages/pnpm/test/run.ts @@ -4,6 +4,7 @@ import promisifyTape from 'tape-promise' import { execPnpmSync } from './utils' const test = promisifyTape(tape) +const testOnly = promisifyTape(tape.only) test('pnpm run: returns correct exit code', async (t: tape.Test) => { const project = prepare(t, {