diff --git a/commands/run/__tests__/__fixtures__/powered-by-nx/packages/package-1/package.json b/commands/run/__tests__/__fixtures__/powered-by-nx/packages/package-1/package.json index b6b638e487..9978bcb211 100644 --- a/commands/run/__tests__/__fixtures__/powered-by-nx/packages/package-1/package.json +++ b/commands/run/__tests__/__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/commands/run/__tests__/run-command.test.js b/commands/run/__tests__/run-command.test.js index 83dfbecbe6..3e95157577 100644 --- a/commands/run/__tests__/run-command.test.js +++ b/commands/run/__tests__/run-command.test.js @@ -331,6 +331,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/commands/run/index.js b/commands/run/index.js index 298af74d8f..56dbeb5ed9 100644 --- a/commands/run/index.js +++ b/commands/run/index.js @@ -170,6 +170,15 @@ class RunCommand extends Command { return chain; } + addQuotesAroundScriptNameIfItHasAColon(scriptName) { + // Nx requires quotes around script names of the form script:name + if (scriptName.includes(":")) { + return `"${scriptName}"`; + } else { + return scriptName; + } + } + runScriptsUsingNx() { if (this.options.ci) { process.env.CI = "true"; @@ -179,7 +188,10 @@ class RunCommand extends Command { const { targetDependencies, options } = this.prepNxOptions(); if (this.packagesWithScript.length === 1) { const { runOne } = require("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.addQuotesAroundScriptNameIfItHasAColon(this.script); return runOne( process.cwd(), { diff --git a/e2e/tests/lerna-run/lerna-run.spec.ts b/e2e/tests/lerna-run/lerna-run.spec.ts index 99c7e5b986..947fc04ea8 100644 --- a/e2e/tests/lerna-run/lerna-run.spec.ts +++ b/e2e/tests/lerna-run/lerna-run.spec.ts @@ -310,6 +310,22 @@ describe("useNx", () => { "print-name": "echo test-package-3", }, }); + await fixture.lerna("create package-4 -y"); + await fixture.addScriptsToPackage({ + packagePath: "packages/package-4", + scripts: { + "print:name": "echo test-package-4", + "print-name-run-one-only": "echo test-package-4-run-one-only", + "print:name:run-one-only": "echo test-package-4-run-one-only-with-colon", + }, + }); + await fixture.lerna("create package-5 -y"); + await fixture.addScriptsToPackage({ + packagePath: "packages/package-5", + scripts: { + "print:name": "echo test-package-5", + }, + }); }); afterAll(() => fixture.destroy()); @@ -355,6 +371,92 @@ test-package-X > Lerna (powered by Nx) Successfully ran target print-name for 3 projects +lerna notice cli v999.9.9-e2e.0 + +`); + }); + + describe("run one", () => { + it("should run script on single child package using nx", async () => { + const output = await fixture.lerna(`run print-name-run-one-only`); + + expect(output.combinedOutput).toMatchInlineSnapshot(` + + > package-X:print-name-run-one-only + + + > package-X@0.0.0 print-name-run-one-only + > echo test-package-X-run-one-only + + test-package-X-run-one-only + + + + > Lerna (powered by Nx) Successfully ran target print-name-run-one-only for project package-X + + + lerna notice cli v999.9.9-e2e.0 + + `); + }); + + it("should run script with colon on single child package using nx", async () => { + const output = await fixture.lerna(`run print:name:run-one-only`); + + expect(output.combinedOutput).toMatchInlineSnapshot(` + + > package-X:"print:name:run-one-only" + + + > package-X@0.0.0 print:name:run-one-only + > echo test-package-X-run-one-only-with-colon + + test-package-X-run-one-only-with-colon + + + + > Lerna (powered by Nx) Successfully ran target print:name:run-one-only for project package-X + + + lerna notice cli v999.9.9-e2e.0 + + `); + }); + }); + + it("should run script with colon on all child package using nx", async () => { + const output = await fixture.lerna(`run print:name`); + + expect(output.combinedOutput).toMatchInlineSnapshot(` + + > Lerna (powered by Nx) Running target print:name for 2 project(s): + + - package-X + - package-X + + + +> package-X:"print:name" + + +> package-X@0.0.0 print:name +> echo test-package-X + +test-package-X + +> package-X:"print:name" + + +> package-X@0.0.0 print:name +> echo test-package-X + +test-package-X + + + + > Lerna (powered by Nx) Successfully ran target print:name for 2 projects + + lerna notice cli v999.9.9-e2e.0 `);