diff --git a/packages/run/package.json b/packages/run/package.json index c1a75009..b1b64e16 100644 --- a/packages/run/package.json +++ b/packages/run/package.json @@ -43,6 +43,8 @@ "devDependencies": { "@types/execa": "^2.0.0", "@types/p-map": "^2.0.0", + "globby": "^11.1.0", + "jest-circus": "^28.1.2", "perf_hooks": "^0.0.1", "yargs-parser": "^21.0.1" } diff --git a/packages/run/src/__fixtures__/powered-by-nx/packages/package-1/package.json b/packages/run/src/__fixtures__/powered-by-nx/packages/package-1/package.json index 23a378d9..9978bcb2 100644 --- a/packages/run/src/__fixtures__/powered-by-nx/packages/package-1/package.json +++ b/packages/run/src/__fixtures__/powered-by-nx/packages/package-1/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "scripts": { "fail": "exit 1", - "my-script": "echo package-1" + "my-script": "echo package-1", + "another-script:but-with-colons": "echo package-1-script-with-colons" } } \ No newline at end of file diff --git a/packages/run/src/__tests__/run-command.spec.ts b/packages/run/src/__tests__/run-command.spec.ts index ac19222a..5b159323 100644 --- a/packages/run/src/__tests__/run-command.spec.ts +++ b/packages/run/src/__tests__/run-command.spec.ts @@ -383,6 +383,13 @@ describe('RunCommand', () => { expect(collectedOutput).toContain('Successfully ran target'); }); + it('runs a script with a colon in the script name', async () => { + collectedOutput = ''; + await lernaRun(testDir)('another-script:but-with-colons'); + expect(collectedOutput).toContain('package-1-script-with-colons'); + expect(collectedOutput).toContain('Successfully ran target'); + }); + it('runs a script only in scoped packages', async () => { collectedOutput = ''; await lernaRun(testDir)('my-script', '--scope', 'package-1'); diff --git a/packages/run/src/run-command.ts b/packages/run/src/run-command.ts index 27b9f5c9..ca10ae3e 100644 --- a/packages/run/src/run-command.ts +++ b/packages/run/src/run-command.ts @@ -205,6 +205,11 @@ export class RunCommand extends Command { return chain; } + /** Nx requires quotes around script names of the form script:name*/ + escapeScriptNameQuotes(scriptName: string) { + return scriptName.includes(':') ? `"${scriptName}"` : scriptName; + } + async runScriptsUsingNx() { if (this.options.ci) { process.env.CI = 'true'; @@ -214,7 +219,8 @@ export class RunCommand extends Command { const { targetDependencies, options } = await this.prepNxOptions(); if (this.packagesWithScript.length === 1) { const { runOne } = await import('nx/src/command-line/run-one'); - const fullQualifiedTarget = this.packagesWithScript.map((p) => p.name)[0] + ':' + this.script; + const fullQualifiedTarget = + this.packagesWithScript.map((p) => p.name)[0] + ':' + this.escapeScriptNameQuotes(this.script); return (runOne as any)( process.cwd(), { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9b8072a0..6d2b481d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -549,6 +549,8 @@ importers: '@types/execa': ^2.0.0 '@types/p-map': ^2.0.0 fs-extra: ^10.1.0 + globby: ^11.1.0 + jest-circus: ^28.1.2 multimatch: ^5.0.0 npmlog: ^6.0.2 p-map: ^4.0.0 @@ -568,6 +570,8 @@ importers: devDependencies: '@types/execa': 2.0.0 '@types/p-map': 2.0.0 + globby: 11.1.0 + jest-circus: 28.1.2 perf_hooks: 0.0.1 yargs-parser: 21.0.1 @@ -6727,7 +6731,7 @@ packages: strip-ansi: 6.0.1 /wrappy/1.0.2: - resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} /write-file-atomic/2.4.3: resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==}