Skip to content

Commit

Permalink
fix(run): exclude dependencies with --scope when nx.json is not prese…
Browse files Browse the repository at this point in the history
…nt (#3316)
  • Loading branch information
fahslaj committed Sep 9, 2022
1 parent 1343b9f commit 99a13a9
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 4 deletions.
5 changes: 5 additions & 0 deletions commands/run/command.js
Expand Up @@ -73,6 +73,11 @@ exports.builder = (yargs) => {
hidden: true,
type: "boolean",
},
verbose: {
group: "Command Options:",
describe: "When useNx is true, show verbose output from dependent tasks.",
type: "boolean",
},
});

return filterOptions(yargs);
Expand Down
28 changes: 24 additions & 4 deletions commands/run/index.js
Expand Up @@ -2,6 +2,8 @@
"use strict";

const pMap = require("p-map");
const path = require("path");
const { existsSync } = require("fs-extra");

const { Command } = require("@lerna/command");
const { npmRunScript, npmRunScriptStreaming } = require("@lerna/npm-run-script");
Expand Down Expand Up @@ -184,7 +186,8 @@ class RunCommand extends Command {
}
performance.mark("init-local");
this.configureNxOutput();
const { targetDependencies, options } = this.prepNxOptions();
const { targetDependencies, options, extraOptions } = this.prepNxOptions();

if (this.packagesWithScript.length === 1) {
const { runOne } = require("nx/src/command-line/run-one");
const fullQualifiedTarget =
Expand All @@ -197,7 +200,8 @@ class RunCommand extends Command {
"project:target:configuration": fullQualifiedTarget,
...options,
},
targetDependencies
targetDependencies,
extraOptions
);
} else {
const { runMany } = require("nx/src/command-line/run-many");
Expand All @@ -208,7 +212,8 @@ class RunCommand extends Command {
target: this.script,
...options,
},
targetDependencies
targetDependencies,
extraOptions
);
}
}
Expand Down Expand Up @@ -246,10 +251,25 @@ class RunCommand extends Command {
nxBail: this.bail,
nxIgnoreCycles: !this.options.rejectCycles,
skipNxCache: this.options.skipNxCache,
verbose: this.options.verbose,
__overrides__: this.args.map((t) => t.toString()),
};

return { targetDependencies, options };
const excludeTaskDependencies = !existsSync(path.join(this.project.rootPath, "nx.json"));
if (excludeTaskDependencies) {
this.logger.verbose(
this.name,
"nx.json was not found. Task dependencies will not be automatically included."
);
} else {
this.logger.verbose(this.name, "nx.json was found. Task dependencies will be automatically included.");
}

const extraOptions = {
excludeTaskDependencies,
};

return { targetDependencies, options, extraOptions };
}

runScriptInPackagesParallel() {
Expand Down
99 changes: 99 additions & 0 deletions core/command/__tests__/command.test.js
Expand Up @@ -407,4 +407,103 @@ describe("core-command", () => {
);
});
});

describe("loglevel with verbose option true", () => {
it("should be set to verbose if loglevel is error", async () => {
const command = testFactory({
loglevel: "error",
verbose: true,
});
await command;

expect(command.options.loglevel).toEqual("verbose");
});

it("should be set to verbose if loglevel is warn", async () => {
const command = testFactory({
loglevel: "warn",
verbose: true,
});
await command;

expect(command.options.loglevel).toEqual("verbose");
});

it("should be set to verbose if loglevel is info", async () => {
const command = testFactory({
loglevel: "info",
verbose: true,
});
await command;

expect(command.options.loglevel).toEqual("verbose");
});

it("should remain set to verbose if loglevel is verbose", async () => {
const command = testFactory({
loglevel: "verbose",
verbose: true,
});
await command;

expect(command.options.loglevel).toEqual("verbose");
});

it("should not be set to verbose if loglevel is silly", async () => {
const command = testFactory({
loglevel: "silly",
verbose: true,
});
await command;

expect(command.options.loglevel).toEqual("silly");
});
});

describe("loglevel without verbose option", () => {
it("should remain set to error if loglevel is error", async () => {
const command = testFactory({
loglevel: "error",
});
await command;

expect(command.options.loglevel).toEqual("error");
});

it("should remain set to warn if loglevel is warn", async () => {
const command = testFactory({
loglevel: "warn",
});
await command;

expect(command.options.loglevel).toEqual("warn");
});

it("should remain set to info if loglevel is info", async () => {
const command = testFactory({
loglevel: "info",
});
await command;

expect(command.options.loglevel).toEqual("info");
});

it("should remain set to verbose if loglevel is verbose", async () => {
const command = testFactory({
loglevel: "verbose",
});
await command;

expect(command.options.loglevel).toEqual("verbose");
});

it("should remain set to silly if loglevel is silly", async () => {
const command = testFactory({
loglevel: "silly",
});
await command;

expect(command.options.loglevel).toEqual("silly");
});
});
});
4 changes: 4 additions & 0 deletions core/command/index.js
Expand Up @@ -171,6 +171,10 @@ class Command {
// Environmental defaults prepared in previous step
this.envDefaults
);

if (this.options.verbose && this.options.loglevel !== "silly") {
this.options.loglevel = "verbose";
}
}

configureProperties() {
Expand Down
10 changes: 10 additions & 0 deletions core/lerna/schemas/lerna-schema.json
Expand Up @@ -905,6 +905,9 @@
"profileLocation": {
"$ref": "#/$defs/commandOptions/shared/profileLocation"
},
"verbose": {
"$ref": "#/$defs/commandOptions/shared/verbose"
},
"skipNxCache": {
"$ref": "#/$defs/commandOptions/run/skipNxCache"
},
Expand Down Expand Up @@ -1395,6 +1398,9 @@
},
"ignorePrepublish": {
"$ref": "#/$defs/commandOptions/shared/ignorePrepublish"
},
"verbose": {
"$ref": "#/$defs/commandOptions/shared/verbose"
}
},
"$defs": {
Expand Down Expand Up @@ -1828,6 +1834,10 @@
"ignorePrepublish": {
"type": "boolean",
"description": "During `lerna publish` and `lerna bootstrap`, when true, disable deprecated 'prepublish' lifecycle script."
},
"verbose": {
"type": "boolean",
"description": "When true, escalates loglevel to 'verbose' and shows nx verbose output if useNx is true."
}
}
}
Expand Down
163 changes: 163 additions & 0 deletions e2e/tests/lerna-run/lerna-run-nx-include-dependencies.spec.ts
@@ -0,0 +1,163 @@
import { remove } from "fs-extra";
import { Fixture } from "../../utils/fixture";
import { normalizeCommandOutput, normalizeEnvironment } from "../../utils/snapshot-serializer-utils";

expect.addSnapshotSerializer({
serialize(str: string) {
return normalizeCommandOutput(normalizeEnvironment(str));
},
test(val: string) {
return val != null && typeof val === "string";
},
});

describe("lerna-run-nx-include-dependencies", () => {
let fixture: Fixture;

beforeEach(async () => {
fixture = await Fixture.create({
name: "lerna-run-nx-include-dependencies",
packageManager: "npm",
initializeGit: true,
runLernaInit: true,
installDependencies: true,
/**
* Because lerna run involves spawning further child processes, the tests would be too flaky
* if we didn't force deterministic terminal output by appending stderr to stdout instead
* of interleaving them.
*/
forceDeterministicTerminalOutput: true,
});

await fixture.lerna("create package-1 -y");
await fixture.addScriptsToPackage({
packagePath: "packages/package-1",
scripts: {
"print-name": "echo test-package-1",
},
});
await fixture.lerna("create package-2 -y");
await fixture.addScriptsToPackage({
packagePath: "packages/package-2",
scripts: {
"print-name": "echo test-package-2",
},
});
await fixture.lerna("create package-3 -y --dependencies package-1 package-2");
await fixture.addScriptsToPackage({
packagePath: "packages/package-3",
scripts: {
"print-name": "echo test-package-3",
},
});

await fixture.updateJson("lerna.json", (json) => ({
...json,
loglevel: "verbose",
}));
});
afterEach(() => fixture.destroy());

describe("without nx enabled", () => {
it("should exclude dependencies by default", async () => {
const output = await fixture.lerna("run print-name --scope package-3 -- --silent");

expect(output.combinedOutput).toMatchInlineSnapshot(`
test-package-X
lerna notice cli v999.9.9-e2e.0
lerna verb rootPath /tmp/lerna-e2e/lerna-run-nx-include-dependencies/lerna-workspace
lerna notice filter including "package-X"
lerna info filter [ 'package-X' ]
lerna info Executing command in 1 package: "npm run print-name --silent"
lerna info run Ran npm script 'print-name' in 'package-X' in X.Xs:
lerna success run Ran npm script 'print-name' in 1 package in X.Xs:
lerna success - package-X
`);
});
});

describe("with nx enabled, but no nx.json", () => {
it("should exclude dependencies by default", async () => {
await fixture.addNxToWorkspace();

await remove(fixture.getWorkspacePath("nx.json"));

const output = await fixture.lerna("run print-name --scope package-3 -- --silent");

expect(output.combinedOutput).toMatchInlineSnapshot(`
> package-X:print-name --silent
> package-X@0.0.0 print-name
> echo test-package-X "--silent"
test-package-X --silent
> Lerna (powered by Nx) Successfully ran target print-name for project package-X
lerna notice cli v999.9.9-e2e.0
lerna verb rootPath /tmp/lerna-e2e/lerna-run-nx-include-dependencies/lerna-workspace
lerna notice filter including "package-X"
lerna info filter [ 'package-X' ]
lerna verb run nx.json was not found. Task dependencies will not be automatically included.
`);
});
});

describe("with nx enabled and with nx.json", () => {
it("should include dependencies by default", async () => {
await fixture.addNxToWorkspace();

const output = await fixture.lerna("run print-name --scope package-3 -- --silent");

expect(output.combinedOutput).toMatchInlineSnapshot(`
> Lerna (powered by Nx) Running target print-name for project package-X and 2 task(s) it depends on
> 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
> package-X:print-name --silent
> package-X@0.0.0 print-name
> echo test-package-X "--silent"
test-package-X --silent
> Lerna (powered by Nx) Successfully ran target print-name for project package-X
lerna notice cli v999.9.9-e2e.0
lerna verb rootPath /tmp/lerna-e2e/lerna-run-nx-include-dependencies/lerna-workspace
lerna notice filter including "package-X"
lerna info filter [ 'package-X' ]
lerna verb run nx.json was found. Task dependencies will be automatically included.
`);
});
});
});

0 comments on commit 99a13a9

Please sign in to comment.