feat: script-shell

close #2942
PR #2943
This commit is contained in:
Zoltan Kochan
2020-10-21 01:16:59 +03:00
committed by GitHub
parent 68aedc3e73
commit 50b360ec1e
17 changed files with 74 additions and 6 deletions

View File

@@ -0,0 +1,12 @@
---
"@pnpm/build-modules": minor
"@pnpm/config": minor
"@pnpm/headless": minor
"@pnpm/lifecycle": minor
"@pnpm/plugin-commands-installation": minor
"@pnpm/plugin-commands-rebuild": minor
"@pnpm/plugin-commands-script-runners": minor
"supi": patch
---
A new option added for specifying the shell to use, when running scripts: scriptShell.

View File

@@ -22,7 +22,7 @@
"@commitlint/config-conventional": "^11.0.0",
"@commitlint/prompt-cli": "^11.0.0",
"@pnpm/eslint-config": "workspace:*",
"@pnpm/registry-mock": "^2.1.0",
"@pnpm/registry-mock": "^2.2.0",
"@pnpm/tsconfig": "workspace:*",
"@types/jest": "^26.0.14",
"@types/node": "^12.12.68",

View File

@@ -24,6 +24,8 @@ export default async (
rawConfig: object
unsafePerm: boolean
userAgent: string
scriptShell?: string
shellEmulator?: boolean
sideEffectsCacheWrite: boolean
storeController: StoreController
rootModulesDir: string
@@ -69,6 +71,8 @@ async function buildDependency (
optional: boolean
rawConfig: object
rootModulesDir: string
scriptShell?: string
shellEmulator?: boolean
sideEffectsCacheWrite: boolean
storeController: StoreController
unsafePerm: boolean
@@ -88,6 +92,8 @@ async function buildDependency (
prepare: depNode.prepare,
rawConfig: opts.rawConfig,
rootModulesDir: opts.rootModulesDir,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
unsafePerm: opts.unsafePerm || false,
})
if (hasSideEffects && opts.sideEffectsCacheWrite) {

View File

@@ -32,6 +32,7 @@ export interface Config {
saveOptional?: boolean
savePeer?: boolean
saveWorkspaceProtocol?: boolean
scriptShell?: string
stream?: boolean
production?: boolean
fetchRetries?: number

View File

@@ -66,6 +66,7 @@ export const types = Object.assign({
reporter: String,
'save-peer': Boolean,
'save-workspace-protocol': Boolean,
'script-shell': String,
'shamefully-flatten': Boolean,
'shamefully-hoist': Boolean,
'shared-workspace-lockfile': Boolean,

View File

@@ -94,6 +94,8 @@ export interface HeadlessOptions {
lockfileDir: string
modulesDir?: string
virtualStoreDir?: string
scriptShell?: string
shellEmulator?: boolean
storeController: StoreController
sideEffectsCacheRead: boolean
sideEffectsCacheWrite: boolean
@@ -147,6 +149,8 @@ export default async (opts: HeadlessOptions) => {
const scriptsOpts = {
optional: false,
rawConfig: opts.rawConfig,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
stdio: opts.ownLifecycleHooksStdio ?? 'inherit',
unsafePerm: opts.unsafePerm || false,
}
@@ -341,6 +345,8 @@ export default async (opts: HeadlessOptions) => {
optional: opts.include.optionalDependencies,
rawConfig: opts.rawConfig,
rootModulesDir: virtualStoreDir,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
sideEffectsCacheWrite: opts.sideEffectsCacheWrite,
storeController: opts.storeController,
unsafePerm: opts.unsafePerm,

View File

@@ -14,6 +14,7 @@ export interface RunLifecycleHookOptions {
pkgRoot: string
rawConfig: object
rootModulesDir: string
scriptShell?: string
silent?: boolean
shellEmulator?: boolean
stdio?: string
@@ -71,6 +72,7 @@ export default async function runLifecycleHook (
warn: noop,
},
runConcurrently: true,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
stdio: opts.stdio ?? 'pipe',
unsafePerm: opts.unsafePerm,

View File

@@ -54,6 +54,7 @@ export type InstallDepsOptions = Pick<Config,
| 'savePrefix'
| 'saveProd'
| 'saveWorkspaceProtocol'
| 'scriptShell'
| 'selectedProjectsGraph'
| 'sideEffectsCache'
| 'sideEffectsCacheReadonly'

View File

@@ -9,6 +9,7 @@ export interface StrictRebuildOptions {
childConcurrency: number
extraBinPaths: string[]
lockfileDir: string
scriptShell?: string
sideEffectsCacheRead: boolean
shellEmulator: boolean
storeDir: string // TODO: remove this property

View File

@@ -155,6 +155,7 @@ export async function rebuild (
const scriptsOpts = {
extraBinPaths: ctx.extraBinPaths,
rawConfig: opts.rawConfig,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
unsafePerm: opts.unsafePerm || false,
}

View File

@@ -71,6 +71,7 @@ export async function handler (
| 'engineStrict'
| 'rawLocalConfig'
| 'registries'
| 'scriptShell'
| 'selectedProjectsGraph'
| 'sideEffectsCache'
| 'sideEffectsCacheReadonly'

View File

@@ -107,7 +107,7 @@ For options that may be used with `-r`, see "pnpm help recursive"',
export type RunOpts =
& Omit<RecursiveRunOpts, 'allProjects' | 'selectedProjectsGraph' | 'workspaceDir'>
& { recursive?: boolean }
& Pick<Config, 'dir' | 'engineStrict' | 'reporter' | 'shellEmulator'>
& Pick<Config, 'dir' | 'engineStrict' | 'reporter' | 'scriptShell' | 'shellEmulator'>
& (
& { recursive?: false }
& Partial<Pick<Config, 'allProjects' | 'selectedProjectsGraph' | 'workspaceDir'>>
@@ -154,6 +154,7 @@ so you may run "pnpm -w ${scriptName}"`,
pkgRoot: dir,
rawConfig: opts.rawConfig,
rootModulesDir: await realpathMissing(path.join(dir, 'node_modules')),
scriptShell: opts.scriptShell,
silent: opts.reporter === 'silent',
shellEmulator: opts.shellEmulator,
stdio: 'inherit',

View File

@@ -15,6 +15,7 @@ import realpathMissing = require('realpath-missing')
export type RecursiveRunOpts = Pick<Config,
| 'unsafePerm'
| 'rawConfig'
| 'scriptShell'
| 'shellEmulator'
> & Required<Pick<Config, 'allProjects' | 'selectedProjectsGraph' | 'workspaceDir'>> &
Partial<Pick<Config, 'extraBinPaths' | 'bail' | 'sort' | 'workspaceConcurrency'>> &
@@ -67,6 +68,7 @@ export default async (
pkgRoot: prefix,
rawConfig: opts.rawConfig,
rootModulesDir: await realpathMissing(path.join(prefix, 'node_modules')),
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
stdio,
unsafePerm: true, // when running scripts explicitly, assume that they're trusted.

View File

@@ -7,6 +7,7 @@ import {
test as testCommand,
} from '@pnpm/plugin-commands-script-runners'
import prepare, { preparePackages } from '@pnpm/prepare'
import { REGISTRY_MOCK_PORT } from '@pnpm/registry-mock'
import './exec'
import './runCompletion'
import './runRecursive'
@@ -390,3 +391,31 @@ test('scripts work with PnP', async (t) => {
t.deepEqual(scriptsRan, ['foo'])
t.end()
})
test('pnpm run with custom shell', async (t) => {
prepare(t, {
scripts: {
build: 'foo bar',
},
dependencies: {
'shell-mock': '0.0.0',
},
})
await execa(pnpmBin, [
'install',
`--registry=http://localhost:${REGISTRY_MOCK_PORT}`,
'--store-dir',
path.resolve(DEFAULT_OPTS.storeDir),
])
await run.handler({
dir: process.cwd(),
extraBinPaths: [],
rawConfig: {},
scriptShell: path.resolve('node_modules/.bin/shell-mock'),
}, ['build'])
t.deepEqual(await import(path.resolve('shell-input.json')), ['-c', 'foo bar'])
t.end()
})

View File

@@ -24,6 +24,7 @@ export interface StrictInstallOptions {
preferFrozenLockfile: boolean
saveWorkspaceProtocol: boolean
preserveWorkspaceProtocol: boolean
scriptShell?: string
shellEmulator: boolean
storeController: StoreController
storeDir: string

View File

@@ -254,6 +254,7 @@ export async function mutateModules (
const scriptsOpts: RunLifecycleHooksConcurrentlyOptions = {
extraBinPaths: opts.extraBinPaths,
rawConfig: opts.rawConfig,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
stdio: opts.ownLifecycleHooksStdio,
unsafePerm: opts.unsafePerm || false,
@@ -753,6 +754,8 @@ async function installInContext (
optional: opts.include.optionalDependencies,
rawConfig: opts.rawConfig,
rootModulesDir: ctx.virtualStoreDir,
scriptShell: opts.scriptShell,
shellEmulator: opts.shellEmulator,
sideEffectsCacheWrite: opts.sideEffectsCacheWrite,
storeController: opts.storeController,
unsafePerm: opts.unsafePerm,

8
pnpm-lock.yaml generated
View File

@@ -6,7 +6,7 @@ importers:
'@commitlint/config-conventional': 11.0.0
'@commitlint/prompt-cli': 11.0.0
'@pnpm/eslint-config': 'link:utils/eslint-config'
'@pnpm/registry-mock': 2.1.0
'@pnpm/registry-mock': 2.2.0
'@pnpm/tsconfig': 'link:utils/tsconfig'
'@types/jest': 26.0.14
'@types/node': 12.12.68
@@ -34,7 +34,7 @@ importers:
'@commitlint/config-conventional': ^11.0.0
'@commitlint/prompt-cli': ^11.0.0
'@pnpm/eslint-config': 'workspace:*'
'@pnpm/registry-mock': ^2.1.0
'@pnpm/registry-mock': ^2.2.0
'@pnpm/tsconfig': 'workspace:*'
'@types/jest': ^26.0.14
'@types/node': ^12.12.68
@@ -4024,7 +4024,7 @@ packages:
node: '>=10.13'
resolution:
integrity: sha512-4XVzYoO77hziiJRVTk5pv+9KD631tlqR5+MVu2BlDyrTpgfp+7Su5XPI/2Cek46X2L71vTpYW6LMW22DpmjocA==
/@pnpm/registry-mock/2.1.0:
/@pnpm/registry-mock/2.2.0:
dependencies:
anonymous-npm-registry-client: 0.1.2
cpr: 3.0.1
@@ -4038,7 +4038,7 @@ packages:
node: '>=10.13'
hasBin: true
resolution:
integrity: sha512-taMFAtACZ1eXLonoAzjmw6WP06OlUIBhv5VLoVHI09RlQUm2Ihji99UIURtIhq6Q7kEDgfZ/kH1xx2U7XYbLUA==
integrity: sha512-xB7i7JV1j8Hrajjy2Zp8tHsRVBRzZQ/GqC4Tb+x0Ew7JMrjzdtFQazyJ8wUBGx0nQyYy9YdCWSPdZaK+2tZpXQ==
/@pnpm/self-installer/2.1.0:
dev: false
engines: