Skip to content

Commit

Permalink
feat(listable): Output JSON adjacency list with --graph
Browse files Browse the repository at this point in the history
Credit: @yacineb
Original PR: #1970
  • Loading branch information
evocateur committed Jul 18, 2019
1 parent d410a58 commit 9457a21
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions commands/changed/README.md
Expand Up @@ -27,6 +27,7 @@ package-2
- [`-l`, `--long`](https://github.com/lerna/lerna/tree/master/commands/list#--long)
- [`-p`, `--parseable`](https://github.com/lerna/lerna/tree/master/commands/list#--parseable)
- [`--toposort`](https://github.com/lerna/lerna/tree/master/commands/list#--toposort)
- [`--graph`](https://github.com/lerna/lerna/tree/master/commands/list#--graph)

Unlike `lerna ls`, however, `lerna changed` **does not** support [filter options](https://www.npmjs.com/package/@lerna/filter-options), as filtering is not supported by `lerna version` or `lerna publish`.

Expand Down
28 changes: 28 additions & 0 deletions commands/list/README.md
Expand Up @@ -32,6 +32,7 @@ In any case, you can always pass `--loglevel silent` to create pristine chains o
- [`-l`, `--long`](#--long)
- [`-p`, `--parseable`](#--parseable)
- [`--toposort`](#--toposort)
- [`--graph`](#--graph)

`lerna ls` also respects all available [Filter Flags](https://www.npmjs.com/package/@lerna/filter-options).

Expand Down Expand Up @@ -143,3 +144,30 @@ $ lerna ls --toposort
package-2
package-1
```

### `--graph`

Show dependency graph as a JSON-formatted [adjacency list](https://en.wikipedia.org/wiki/Adjacency_list).

```sh
$ lerna ls --graph
{
"pkg-1": [
"pkg-2"
],
"pkg-2": []
}

$ lerna ls --graph --all
{
"pkg-1": [
"pkg-2"
],
"pkg-2": [
"pkg-3"
],
"pkg-3": [
"pkg-2"
]
}
```
31 changes: 31 additions & 0 deletions utils/listable/__tests__/listable-format.test.js
Expand Up @@ -166,6 +166,37 @@ pkg-3 v3.0.0 pkgs/pkg-3 (PRIVATE)
`);
});

test("graph output", () => {
const { text } = formatWithOptions({ graph: true });

expect(text).toMatchInlineSnapshot(`
{
"pkg-1": [
"pkg-2"
],
"pkg-2": []
}
`);
});

test("all graph output", () => {
const { text } = formatWithOptions({ graph: true, all: true });

expect(text).toMatchInlineSnapshot(`
{
"pkg-1": [
"pkg-2"
],
"pkg-2": [
"pkg-3"
],
"pkg-3": [
"pkg-2"
]
}
`);
});

test("parseable output", () => {
const { text } = formatWithOptions({ parseable: true });

Expand Down
4 changes: 4 additions & 0 deletions utils/listable/__tests__/listable-options.test.js
Expand Up @@ -41,4 +41,8 @@ describe("listable.options()", () => {
it("provides --toposort", () => {
expect(parsed("--toposort")).toHaveProperty("toposort", true);
});

it("provides --graph", () => {
expect(parsed("--graph")).toHaveProperty("graph", true);
});
});
35 changes: 35 additions & 0 deletions utils/listable/lib/listable-format.js
Expand Up @@ -20,6 +20,8 @@ function listableFormat(pkgList, options) {
text = formatNDJSON(resultList);
} else if (viewOptions.showParseable) {
text = formatParseable(resultList, viewOptions);
} else if (viewOptions.showGraph) {
text = formatJSONGraph(resultList, viewOptions);
} else {
text = formatColumns(resultList, viewOptions);
}
Expand All @@ -37,6 +39,7 @@ function parseViewOptions(options) {
showNDJSON: options.ndjson,
showParseable: options.parseable,
isTopological: options.toposort,
showGraph: options.graph,
};
}

Expand Down Expand Up @@ -71,6 +74,38 @@ function formatNDJSON(resultList) {
.join("\n");
}

function formatJSONGraph(resultList, viewOptions) {
// https://en.wikipedia.org/wiki/Adjacency_list
const graph = {};
const getNeighbors = viewOptions.showAll
? pkg =>
Object.keys(
Object.assign(
{},
pkg.devDependencies,
pkg.peerDependencies,
pkg.optionalDependencies,
pkg.dependencies
)
).sort()
: pkg =>
Object.keys(
Object.assign(
{},
// no devDependencies
// no peerDependencies
pkg.optionalDependencies,
pkg.dependencies
)
).sort();

for (const pkg of resultList) {
graph[pkg.name] = getNeighbors(pkg);
}

return JSON.stringify(graph, null, 2);
}

function makeParseable(pkg) {
const result = [pkg.location, pkg.name];

Expand Down
5 changes: 5 additions & 0 deletions utils/listable/lib/listable-options.js
Expand Up @@ -37,5 +37,10 @@ function listableOptions(yargs) {
describe: "Sort packages in topological order instead of lexical by directory",
type: "boolean",
},
graph: {
group: "Command Options:",
describe: "Show dependency graph as a JSON-formatted adjacency list",
type: "boolean",
},
});
}

0 comments on commit 9457a21

Please sign in to comment.