diff --git a/package-lock.json b/package-lock.json index 622cabd7..ec7091b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "concurrently", "version": "7.0.0", "license": "MIT", "dependencies": { diff --git a/src/command-parser/expand-npm-wildcard.spec.ts b/src/command-parser/expand-npm-wildcard.spec.ts index e914a350..cd16ae71 100644 --- a/src/command-parser/expand-npm-wildcard.spec.ts +++ b/src/command-parser/expand-npm-wildcard.spec.ts @@ -100,6 +100,22 @@ for (const npmCmd of ['npm', 'yarn', 'pnpm']) { ]); }); + it('allows negation', () => { + readPkg.mockReturnValue({ + scripts: { + 'lint:js': '', + 'lint:ts': '', + 'lint:fix:js': '', + 'lint:fix:ts': '', + } + }); + + expect(parser.parse(createCommandInfo(`${npmCmd} run lint:*(!fix)`))).toEqual([ + { name: 'js', command: `${npmCmd} run lint:js` }, + { name: 'ts', command: `${npmCmd} run lint:ts` }, + ]); + }); + it('caches scripts upon calls', () => { readPkg.mockReturnValue({}); parser.parse(createCommandInfo(`${npmCmd} run foo-*-baz qux`)); diff --git a/src/command-parser/expand-npm-wildcard.ts b/src/command-parser/expand-npm-wildcard.ts index f7128b61..8f6efe1b 100644 --- a/src/command-parser/expand-npm-wildcard.ts +++ b/src/command-parser/expand-npm-wildcard.ts @@ -3,6 +3,9 @@ import * as _ from 'lodash'; import { CommandInfo } from '../command'; import { CommandParser } from './command-parser'; + +const OMISSION = /\(!([^\)]+)\)/; + /** * Finds wildcards in npm/yarn/pnpm run commands and replaces them with all matching scripts in the * `package.json` file of the current directory. @@ -35,8 +38,10 @@ export class ExpandNpmWildcard implements CommandParser { this.scripts = Object.keys(this.readPackage().scripts || {}); } - const preWildcard = _.escapeRegExp(cmdName.substr(0, wildcardPosition)); - const postWildcard = _.escapeRegExp(cmdName.substr(wildcardPosition + 1)); + const omissionRegex = cmdName.match(OMISSION); + const cmdNameSansOmission = cmdName.replace(OMISSION, ''); + const preWildcard = _.escapeRegExp(cmdNameSansOmission.substr(0, wildcardPosition)); + const postWildcard = _.escapeRegExp(cmdNameSansOmission.substr(wildcardPosition + 1)); const wildcardRegex = new RegExp(`^${preWildcard}(.*?)${postWildcard}$`); const currentName = commandInfo.name || ''; @@ -44,6 +49,14 @@ export class ExpandNpmWildcard implements CommandParser { .map(script => { const match = script.match(wildcardRegex); + if (omissionRegex) { + const toOmit = script.match(new RegExp(omissionRegex[1])); + + if (toOmit) { + return; + } + } + if (match) { return Object.assign({}, commandInfo, { command: `${npmCmd} run ${script}${args}`,