Skip to content

Commit

Permalink
fix(publish): Add --graph-type option to control packages included …
Browse files Browse the repository at this point in the history
…in topological sort (#2152)

Allow for configuration of a specific `graphType` so that users can opt-in to using `devDependencies` when building a package graph to determine a topological sort.

Closes #1437
  • Loading branch information
padraig-meaney authored and evocateur committed Jul 18, 2019
1 parent b335763 commit ae87669
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
23 changes: 23 additions & 0 deletions commands/publish/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ This is useful when a previous `lerna publish` failed to publish all packages to
- [`--contents <dir>`](#--contents-dir)
- [`--dist-tag <tag>`](#--dist-tag-tag)
- [`--git-head <sha>`](#--git-head-sha)
- [`--graph-type <all|dependencies>`](#--graph-type-alldependencies)
- [`--no-git-reset`](#--no-git-reset)
- [`--no-verify-access`](#--no-verify-access)
- [`--otp`](#--otp)
Expand Down Expand Up @@ -127,6 +128,28 @@ lerna publish from-package --git-head ${CODEBUILD_RESOLVED_SOURCE_VERSION}

Under all other circumstances, this value is derived from a local `git` command.

### `--graph-type <all|dependencies>`

Set which kind of dependencies to use when building a package graph. The default value is `dependencies`, whereby only packages listed in the `dependencies` section of a package's `package.json` are included. Pass `all` to include both `dependencies` _and_ `devDependencies` when constructing the package graph and determining topological order.

When using traditional peer + dev dependency pairs, this option should be configured to `all` so the peers are always published before their dependents.

```sh
lerna publish --graph-type all
```

Configured via `lerna.json`:

```json
{
"command": {
"publish": {
"graphType": "all"
}
}
}
```

### `--no-git-reset`

By default, `lerna publish` ensures any changes to the working tree have been reset.
Expand Down
29 changes: 29 additions & 0 deletions commands/publish/__tests__/publish-command.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,35 @@ Map {
});
});

describe("--graph-type", () => {
it("produces a topological ordering that _includes_ devDependencies when value is 'all'", async () => {
const cwd = await initFixture("normal");

await lernaPublish(cwd)("--graph-type", "all");

expect(npmPublish.order()).toEqual([
"package-1",
"package-4",
"package-2",
// package-3 has a peer/devDependency on package-2
"package-3",
// package-5 is private
]);
});

it("throws an error when value is _not_ 'all' or 'dependencies'", async () => {
const testDir = await initFixture("normal");

try {
await lernaPublish(testDir)("--graph-type", "poopy-pants");
} catch (err) {
expect(err.message).toMatch("poopy-pants");
}

expect.hasAssertions();
});
});

describe("--otp", () => {
otplease.getOneTimePassword.mockImplementation(() => Promise.resolve("654321"));

Expand Down
5 changes: 5 additions & 0 deletions commands/publish/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ exports.builder = yargs => {
type: "string",
requiresArg: true,
},
"graph-type": {
describe: "Type of dependency to use when determining package hierarchy.",
choices: ["all", "dependencies"],
defaultDescription: "dependencies",
},
otp: {
describe: "Supply a one-time password for publishing with two-factor authentication.",
type: "string",
Expand Down
9 changes: 5 additions & 4 deletions commands/publish/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,10 +589,11 @@ class PublishCommand extends Command {
return runTopologically(this.packagesToPublish, mapper, {
concurrency: this.concurrency,
rejectCycles: this.options.rejectCycles,
// Don't sort based on devDependencies because that
// would increase the chance of dependency cycles
// causing less-than-ideal a publishing order.
graphType: "dependencies",
// By default, do not include devDependencies in the graph because it would
// increase the chance of dependency cycles, causing less-than-ideal order.
// If the user has opted-in to --graph-type=all (or "graphType": "all" in lerna.json),
// devDependencies _will_ be included in the graph construction.
graphType: this.options.graphType === "all" ? "allDependencies" : "dependencies",
});
}

Expand Down

0 comments on commit ae87669

Please sign in to comment.