Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(run): Exclude dependencies with --scope when nx.json is not present #3316

Merged
merged 5 commits into from Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.

`);
});
});
});