Skip to content

Commit

Permalink
fix(run): only defer to Nx when targetDefaults are defined in nx.json (
Browse files Browse the repository at this point in the history
  • Loading branch information
fahslaj committed Sep 29, 2022
1 parent 7defab3 commit 51f80d9
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 71 deletions.
27 changes: 18 additions & 9 deletions commands/run/index.js
Expand Up @@ -221,8 +221,14 @@ class RunCommand extends Command {
prepNxOptions() {
const nxJsonExists = existsSync(path.join(this.project.rootPath, "nx.json"));

const { readNxJson } = require("nx/src/config/configuration");
const nxJson = readNxJson();
const targetDependenciesAreDefined =
Object.keys(nxJson.targetDependencies || nxJson.targetDefaults || {}).length > 0;
const mimicLernaDefaultBehavior = !(nxJsonExists && targetDependenciesAreDefined);

const targetDependencies =
this.toposort && !this.options.parallel && !nxJsonExists
this.toposort && !this.options.parallel && mimicLernaDefaultBehavior
? {
[this.script]: [
{
Expand All @@ -245,46 +251,49 @@ class RunCommand extends Command {
* To match lerna's own behavior (via pMap's default concurrency), we set parallel to a very large number if
* the flag has been set (we can't use Infinity because that would cause issues with the task runner).
*/
parallel: this.options.parallel && !nxJsonExists ? 999 : this.concurrency,
parallel: this.options.parallel && mimicLernaDefaultBehavior ? 999 : this.concurrency,
nxBail: this.bail,
nxIgnoreCycles: !this.options.rejectCycles,
skipNxCache: this.options.skipNxCache,
verbose: this.options.verbose,
__overrides__: this.args.map((t) => t.toString()),
};

if (nxJsonExists) {
this.logger.verbose(this.name, "nx.json was found. Task dependencies will be automatically included.");
if (!mimicLernaDefaultBehavior) {
this.logger.verbose(
this.name,
"nx.json with targetDefaults was found. Task dependencies will be automatically included."
);

if (this.options.parallel || this.options.sort !== undefined) {
this.logger.warn(
this.name,
`"parallel", "sort", and "no-sort" are ignored when nx.json exists. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.`
`"parallel", "sort", and "no-sort" are ignored when nx.json has targetDefaults defined. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.`
);
}

if (this.options.includeDependencies) {
this.logger.info(
this.name,
`Using the "include-dependencies" option when nx.json exists will include both task dependencies detected by Nx and project dependencies detected by Lerna. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--include-dependencies for details.`
`Using the "include-dependencies" option when nx.json has targetDefaults defined will include both task dependencies detected by Nx and project dependencies detected by Lerna. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--include-dependencies for details.`
);
}

if (this.options.ignore) {
this.logger.info(
this.name,
`Using the "ignore" option when nx.json exists will exclude only tasks that are not determined to be required by Nx. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--ignore for details.`
`Using the "ignore" option when nx.json has targetDefaults defined will exclude only tasks that are not determined to be required by Nx. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--ignore for details.`
);
}
} else {
this.logger.verbose(
this.name,
"nx.json was not found. Task dependencies will not be automatically included."
"nx.json was not found or is missing targetDefaults. Task dependencies will not be automatically included."
);
}

const extraOptions = {
excludeTaskDependencies: !nxJsonExists,
excludeTaskDependencies: mimicLernaDefaultBehavior,
};

return { targetDependencies, options, extraOptions };
Expand Down
109 changes: 53 additions & 56 deletions e2e/tests/lerna-run/lerna-run-nx-include-dependencies.spec.ts
Expand Up @@ -102,52 +102,57 @@ describe("lerna-run-nx-include-dependencies", () => {
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.
lerna verb run nx.json was not found or is missing targetDefaults. Task dependencies will not be automatically included.
`);
});
});

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

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

expect(output.combinedOutput).toMatchInlineSnapshot(`
> package-X:print-name --silent
> package-X:print-name --silent
> package-X@0.0.0 print-name
> echo test-package-X "--silent"
test-package-X --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 (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.
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 or is missing targetDefaults. Task dependencies will not be automatically included.
`);
`);
});
});

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

const output = await fixture.lerna("run print-name --scope package-3 --include-dependencies");
await fixture.updateJson("nx.json", (json) => ({
...json,
targetDefaults: {
"print-name": {
dependsOn: ["^print-name"],
},
},
}));
const output = await fixture.lerna("run print-name --scope package-3");

expect(output.combinedOutput).toMatchInlineSnapshot(`
> Lerna (powered by Nx) Running target print-name for 3 project(s):
- package-X
- package-X
- package-X
> Lerna (powered by Nx) Running target print-name for project package-X and 2 task(s) it depends on
Expand All @@ -169,51 +174,44 @@ 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 3 projects
> 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 notice filter including dependencies
lerna info filter [ 'package-X' ]
lerna verb run nx.json was found. Task dependencies will be automatically included.
lerna info run Using the "include-dependencies" option when nx.json exists will include both task dependencies detected by Nx and project dependencies detected by Lerna. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--include-dependencies for details.
lerna verb run nx.json with targetDefaults was found. Task dependencies will be automatically included.
`);
});
});

describe("with explicit Nx task dependencies", () => {
it("should include dependencies", async () => {
it("should include package dependencies with --include-dependencies", async () => {
await fixture.addNxToWorkspace();

await fixture.updateJson("packages/package-3/package.json", (json) => ({
await fixture.updateJson("nx.json", (json) => ({
...json,
nx: {
targets: {
"print-name": {
inputs: [],
outputs: [],
dependsOn: ["^print-name"],
},
targetDefaults: {
"print-name": {
dependsOn: ["^print-name"],
},
},
}));

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

expect(output.combinedOutput).toMatchInlineSnapshot(`
> Lerna (powered by Nx) Running target print-name for project package-X and 2 task(s) it depends on
> Lerna (powered by Nx) Running target print-name for 3 project(s):
- package-X
- package-X
- package-X
Expand All @@ -235,36 +233,35 @@ 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 project package-X
> Lerna (powered by Nx) Successfully ran target print-name for 3 projects
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 notice filter including dependencies
lerna info filter [ 'package-X' ]
lerna verb run nx.json was found. Task dependencies will be automatically included.
lerna verb run nx.json with targetDefaults was found. Task dependencies will be automatically included.
lerna info run Using the "include-dependencies" option when nx.json has targetDefaults defined will include both task dependencies detected by Nx and project dependencies detected by Lerna. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--include-dependencies for details.
`);
});

it("with --ignore should still include dependencies", async () => {
await fixture.addNxToWorkspace();

await fixture.updateJson("packages/package-3/package.json", (json) => ({
await fixture.updateJson("nx.json", (json) => ({
...json,
nx: {
targets: {
"print-name": {
inputs: [],
outputs: [],
dependsOn: ["^print-name"],
},
targetDefaults: {
"print-name": {
dependsOn: ["^print-name"],
},
},
}));
Expand Down Expand Up @@ -309,8 +306,8 @@ lerna verb rootPath /tmp/lerna-e2e/lerna-run-nx-include-dependencies/lerna-works
lerna notice filter including "package-X"
lerna notice filter excluding "package-X"
lerna info filter [ 'package-X', '!package-X' ]
lerna verb run nx.json was found. Task dependencies will be automatically included.
lerna info run Using the "ignore" option when nx.json exists will exclude only tasks that are not determined to be required by Nx. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--ignore for details.
lerna verb run nx.json with targetDefaults was found. Task dependencies will be automatically included.
lerna info run Using the "ignore" option when nx.json has targetDefaults defined will exclude only tasks that are not determined to be required by Nx. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--ignore for details.
`);
});
Expand Down
16 changes: 12 additions & 4 deletions e2e/tests/lerna-run/lerna-run-nx-incompatible-options.spec.ts
Expand Up @@ -30,6 +30,14 @@ describe("lerna-run-nx-incompatible-options", () => {
});

await fixture.addNxToWorkspace();
await fixture.updateJson("nx.json", (json) => ({
...json,
targetDefaults: {
"print-name": {
dependsOn: ["^print-name"],
},
},
}));

await fixture.lerna("create package-1 -y");
await fixture.addScriptsToPackage({
Expand Down Expand Up @@ -145,7 +153,7 @@ test-package-X
lerna notice cli v999.9.9-e2e.0
lerna WARN run "parallel", "sort", and "no-sort" are ignored when nx.json exists. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.
lerna WARN run "parallel", "sort", and "no-sort" are ignored when nx.json has targetDefaults defined. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.
`);
});
Expand Down Expand Up @@ -193,7 +201,7 @@ test-package-X
lerna notice cli v999.9.9-e2e.0
lerna WARN run "parallel", "sort", and "no-sort" are ignored when nx.json exists. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.
lerna WARN run "parallel", "sort", and "no-sort" are ignored when nx.json has targetDefaults defined. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.
`);
});
Expand Down Expand Up @@ -241,7 +249,7 @@ test-package-X
lerna notice cli v999.9.9-e2e.0
lerna WARN run "parallel", "sort", and "no-sort" are ignored when nx.json exists. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.
lerna WARN run "parallel", "sort", and "no-sort" are ignored when nx.json has targetDefaults defined. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks for details.
`);
});
Expand Down Expand Up @@ -290,7 +298,7 @@ test-package-X
lerna notice cli v999.9.9-e2e.0
lerna notice filter including dependencies
lerna info run Using the "include-dependencies" option when nx.json exists will include both task dependencies detected by Nx and project dependencies detected by Lerna. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--include-dependencies for details.
lerna info run Using the "include-dependencies" option when nx.json has targetDefaults defined will include both task dependencies detected by Nx and project dependencies detected by Lerna. See https://lerna.js.org/docs/recipes/using-lerna-powered-by-nx-to-run-tasks#--include-dependencies for details.
`);
});
Expand Down
2 changes: 1 addition & 1 deletion website/docs/lerna-and-nx.md
Expand Up @@ -51,7 +51,7 @@ Free and open source
- Continue using Lerna as usual

:::note
When Lerna is set to use Nx and detects `nx.json` in the workspace, it will defer to Nx to detect task dependencies. Some options for `lerna run` will behave differently. See [Using Lerna (Powered by Nx) to Run Tasks](./recipes/using-lerna-powered-by-nx-to-run-tasks) for more details.
When Lerna is set to use Nx and detects `nx.json` with `targetDefaults` in the workspace, it will defer to Nx to detect task dependencies. Some options for `lerna run` will behave differently. See [Using Lerna (Powered by Nx) to Run Tasks](./recipes/using-lerna-powered-by-nx-to-run-tasks) for more details.
:::

---
Expand Down
Expand Up @@ -35,6 +35,6 @@ When used with Nx, `--ignore` will never cause `lerna run` to exclude any tasks

:::tip

The effects on the options above will only apply if `nx.json` exists in the root. If `nx.json` does not exist and `useNx` is `true`, then they will behave just as they would with Lerna's base task runner (if `useNx` is `false`).
The effects on the options above will only apply if `nx.json` exists in the root with the `targetDefaults` property defined. Otherwise, they will behave just as they would with Lerna's base task runner (if `useNx` is `false`).

:::

0 comments on commit 51f80d9

Please sign in to comment.