Skip to content

Commit

Permalink
feat(cli): display name of executing script (#126) (#136)
Browse files Browse the repository at this point in the history
Updated prefix-matches verion and added script name of executed script
  • Loading branch information
Miklet authored and Kent C. Dodds committed May 27, 2017
1 parent 061b5c3 commit 76bee57
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 29 deletions.
13 changes: 11 additions & 2 deletions cli-test/__snapshots__/cli.test.js.snap
Expand Up @@ -12,7 +12,7 @@ lint.sub.hiddenThing
exports[`test with --require 1`] = `
Object {
"stderr": "",
"stdout": "nps executing: echo \"log\"
"stdout": "nps is executing \`log\`: echo \"log\"
log
",
}
Expand All @@ -37,8 +37,17 @@ Object {
exports[`test with config with default script 1`] = `
Object {
"stderr": "",
"stdout": "nps executing: echo \"default script\"
"stdout": "nps is executing \`default\`: echo \"default script\"
default script
",
}
`;

exports[`test with prefix 1`] = `
Object {
"stderr": "",
"stdout": "nps is executing \`lint.sub.thing.script\`: echo \"deeply nested thing\"
deeply nested thing
",
}
`;
3 changes: 3 additions & 0 deletions cli-test/cli.test.js
Expand Up @@ -17,6 +17,9 @@ test('with --require', () =>
test('with --get-yargs-completions', () =>
snapshot('--config ./package-scripts.js --get-yargs-completions li'))

test('with prefix', () =>
snapshot('--config ./package-scripts.js lint.s.t.s'))

function snapshot(args) {
return runNPS(fixturesPath, args).then(results => {
const snapshottableResults = convertResultToLinuxSpecific(results)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -27,7 +27,7 @@
"js-yaml": "^3.7.0",
"lodash": "^4.17.4",
"manage-path": "^2.0.0",
"prefix-matches": "^0.0.9",
"prefix-matches": "^1.0.1",
"readline-sync": "^1.4.6",
"spawn-command-with-kill": "^1.0.0",
"type-detect": "^4.0.0",
Expand Down
20 changes: 11 additions & 9 deletions src/bin-utils/initialize/index.js
Expand Up @@ -55,22 +55,24 @@ function generatePackageScriptsFileContents(scripts) {

function structureScripts(scripts) {
// start out by giving every script a `default`
const defaultedScripts = Object.keys(scripts).reduce((obj, key) => {
const keyParts = key.split(':')
const isKeyScriptHook = isScriptHook(keyParts[0]);
let deepKey = keyParts.map(key => camelCase(key)).join('.')
const defaultedScripts = Object.keys(scripts).reduce((obj, scriptKey) => {
const keyParts = scriptKey.split(':')
const isKeyScriptHook = isScriptHook(keyParts[0])
const deepKey = keyParts.map(key => camelCase(key)).join('.')
let defaultDeepKey = `${deepKey}.default`
if (key.indexOf('start') === 0) {
if (scriptKey.indexOf('start') === 0) {
defaultDeepKey = [
'default',
...keyParts.slice(1, keyParts.length),
'default',
].join('.')
}
let script = scripts[key]
let script = scripts[scriptKey]
if (!isKeyScriptHook) {
const preHook = scripts[`pre${key}`] ? `nps pre${deepKey} && ` : ''
const postHook = scripts[`post${key}`] ? ` && nps post${deepKey}` : ''
const preHook = scripts[`pre${scriptKey}`] ? `nps pre${deepKey} && ` : ''
const postHook = scripts[`post${scriptKey}`] ?
` && nps post${deepKey}` :
''
script = `${preHook}${script}${postHook}`
}
set(obj, defaultDeepKey, script)
Expand Down Expand Up @@ -132,4 +134,4 @@ function isLast(object, index) {

function isScriptHook(script) {
return script.indexOf('pre') === 0 || script.indexOf('post') === 0
}
}
2 changes: 1 addition & 1 deletion src/bin-utils/initialize/index.test.js
Expand Up @@ -14,7 +14,7 @@ test('initialize JS normally', () => {
const expectedPackageScripts = readFileSync(
resolve('./src/bin-utils/initialize/fixtures/_package-scripts.js'),
'utf-8',
).replace(/\r?\n/g, '\n');
).replace(/\r?\n/g, '\n')
const mockWriteFileSync = spy()
const mockFindUpSync = spy(file => {
if (file === 'package.json') {
Expand Down
25 changes: 18 additions & 7 deletions src/get-script-to-run.js
@@ -1,4 +1,4 @@
import {each, cloneDeep, isPlainObject} from 'lodash'
import {each, cloneDeep, isPlainObject, isUndefined, isString} from 'lodash'
import prefixMatches from 'prefix-matches'
import resolveScriptObjectToString from './resolve-script-object-to-string'
import kebabAndCamelCasify from './kebab-and-camel-casify'
Expand All @@ -10,19 +10,30 @@ function getScriptToRun(config, input) {
// remove the default objects/strings so we cancheck
// if the prefix works with another script first
const defaultlessConfig = removeDefaults(cloneDeep(config))
const scriptString = getScriptString(defaultlessConfig, input)
if (scriptString) {
return scriptString
const scriptToRun = getScript(defaultlessConfig, input)
if (!isUndefined(scriptToRun) && isString(scriptToRun.script)) {
return scriptToRun
} else {
// fallback to the defaults if no other script was
// found with the given input
return getScriptString(config, input)
return getScript(config, input)
}
}

function getScriptString(config, input) {
function getScript(config, input) {
const [script] = prefixMatches(input, config)
return resolveScriptObjectToString(script)
if (script) {
const scriptName = Object.keys(script).shift()
let scriptToRun = script[scriptName]
if (scriptName && isPlainObject(scriptToRun)) {
scriptToRun = resolveScriptObjectToString(scriptToRun)
}
return {
scriptName,
script: scriptToRun,
}
}
return undefined
}

function removeDefaults(object) {
Expand Down
29 changes: 22 additions & 7 deletions src/get-script-to-run.test.js
Expand Up @@ -2,12 +2,15 @@ import getScriptToRun from './get-script-to-run'

test('allows a prefix to be provided', () => {
const script = getScriptToRun({build: 'stuff'}, 'b')
expect(script).toBe('stuff')
expect(script).toEqual({scriptName: 'build', script: 'stuff'})
})

test('allows a multi-level prefix to be provided', () => {
const script = getScriptToRun({build: {watch: 'watch stuff'}}, 'b.w')
expect(script).toBe('watch stuff')
expect(script).toEqual({
scriptName: 'build.watch',
script: 'watch stuff',
})
})

test(
Expand All @@ -17,7 +20,10 @@ test(
{build: {watch: 'watch stuff'}},
'build.watch',
)
expect(script).toBe('watch stuff')
expect(script).toEqual({
scriptName: 'build.watch',
script: 'watch stuff',
})
},
)

Expand All @@ -26,7 +32,10 @@ test('can accept snake-case representation of a camelCase name', () => {
{checkCoverage: 'checking coverage'},
'check-coverage',
)
expect(script).toBe('checking coverage')
expect(script).toEqual({
scriptName: 'check-coverage',
script: 'checking coverage',
})
})

test('fallsback to `default` if no prefix is found', () => {
Expand All @@ -35,7 +44,13 @@ test('fallsback to `default` if no prefix is found', () => {
const defaultIsPrefixFallback = getScriptToRun(scripts, 'foo.def')
const script = getScriptToRun(scripts, 'foo.de')

expect(usesDefault).toBe('echo "default"')
expect(defaultIsPrefixFallback).toBe('echo "default"')
expect(script).toBe('echo "dee"')
expect(usesDefault).toEqual({
scriptName: 'foo',
script: 'echo "default"',
})
expect(defaultIsPrefixFallback).toEqual({
scriptName: 'foo.default',
script: 'echo "default"',
})
expect(script).toEqual({scriptName: 'foo.dee', script: 'echo "dee"'})
})
10 changes: 8 additions & 2 deletions src/index.js
Expand Up @@ -42,7 +42,7 @@ function runPackageScripts({scriptConfig, scripts, options = {}}) {
function runPackageScript({scriptConfig, options, input}) {
const [scriptPrefix, ...args] = input.split(' ')
const scripts = getScriptsFromConfig(scriptConfig, scriptPrefix)
const script = getScriptToRun(scripts, scriptPrefix)
const {scriptName, script} = getScriptToRun(scripts, scriptPrefix)
if (!isString(script)) {
return Promise.reject({
message: chalk.red(
Expand All @@ -56,7 +56,13 @@ function runPackageScript({scriptConfig, options, input}) {
}
const command = [script, ...args].join(' ').trim()
const log = getLogger(getLogLevel(options))
log.info(chalk.gray('nps executing: ') + chalk.green(command))
log.info(
oneLine`
${chalk.gray('nps is executing')}
\`${chalk.bold(scriptName)}\`:
${chalk.green(command)}
`,
)
let child
return new Promise((resolve, reject) => {
child = spawn(command, {stdio: 'inherit', env: getEnv()})
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Expand Up @@ -4435,6 +4435,13 @@ prefix-matches@^0.0.9:
is-object "^1.0.1"
starts-with "^1.0.2"

prefix-matches@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/prefix-matches/-/prefix-matches-1.0.1.tgz#02e34ce27f33af48e68bbfce2aac2a004bc2b76c"
dependencies:
is-object "^1.0.1"
starts-with "^1.0.2"

prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
Expand Down

0 comments on commit 76bee57

Please sign in to comment.