Skip to content

Commit

Permalink
feat(run): Extract @lerna/run-topologically
Browse files Browse the repository at this point in the history
  • Loading branch information
evocateur committed May 13, 2019
1 parent f9fa74e commit 3a8b175
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 31 deletions.
31 changes: 6 additions & 25 deletions commands/run/index.js
@@ -1,13 +1,12 @@
"use strict";

const pMap = require("p-map");
const PQueue = require("p-queue");

const Command = require("@lerna/command");
const npmRunScript = require("@lerna/npm-run-script");
const output = require("@lerna/output");
const timer = require("@lerna/timer");
const QueryGraph = require("@lerna/query-graph");
const runTopologically = require("@lerna/run-topologically");
const ValidationError = require("@lerna/validation-error");
const { getFilteredPackages } = require("@lerna/filter-options");

Expand Down Expand Up @@ -129,33 +128,15 @@ class RunCommand extends Command {
}

runScriptInPackagesTopological() {
const queue = new PQueue({ concurrency: this.concurrency });
const graph = new QueryGraph(this.packagesWithScript, this.options.rejectCycles);

const runner = this.options.stream
? pkg => this.runScriptInPackageStreaming(pkg)
: pkg => this.runScriptInPackageCapturing(pkg);

return new Promise((resolve, reject) => {
const returnValues = [];

const queueNextAvailablePackages = () =>
graph.getAvailablePackages().forEach(({ pkg, name }) => {
graph.markAsTaken(name);

queue
.add(() =>
runner(pkg)
.then(value => returnValues.push(value))
.then(() => graph.markAsDone(pkg))
.then(() => queueNextAvailablePackages())
)
.catch(reject);
});

queueNextAvailablePackages();

return queue.onIdle().then(() => resolve(returnValues));
return runTopologically({
packages: this.packagesWithScript,
concurrency: this.concurrency,
rejectCycles: this.options.rejectCycles,
runner,
});
}

Expand Down
5 changes: 2 additions & 3 deletions commands/run/package.json
Expand Up @@ -39,10 +39,9 @@
"@lerna/filter-options": "file:../../core/filter-options",
"@lerna/npm-run-script": "file:../../utils/npm-run-script",
"@lerna/output": "file:../../utils/output",
"@lerna/query-graph": "file:../../utils/query-graph",
"@lerna/run-topologically": "file:../../utils/run-topologically",
"@lerna/timer": "file:../../utils/timer",
"@lerna/validation-error": "file:../../core/validation-error",
"p-map": "^1.2.0",
"p-queue": "^4.0.0"
"p-map": "^1.2.0"
}
}
13 changes: 10 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions utils/run-topologically/README.md
@@ -0,0 +1,9 @@
# `@lerna/run-topologically`

> An internal Lerna tool
## Usage

You probably shouldn't, at least directly.

Install [lerna](https://www.npmjs.com/package/lerna) for access to the `lerna` CLI.
38 changes: 38 additions & 0 deletions utils/run-topologically/package.json
@@ -0,0 +1,38 @@
{
"name": "@lerna/run-topologically",
"version": "3.13.4",
"description": "An internal Lerna tool",
"keywords": [
"lerna",
"utils"
],
"homepage": "https://github.com/lerna/lerna/tree/master/utils/run-topologically#readme",
"license": "MIT",
"author": {
"name": "Daniel Stockman",
"url": "https://github.com/evocateur"
},
"files": [
"run-topologically.js"
],
"main": "run-topologically.js",
"engines": {
"node": ">= 6.9.0"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lerna/lerna.git",
"directory": "utils/run-topologically"
},
"scripts": {
"test": "echo \"Run tests from root\" && exit 1"
},
"dependencies": {
"@lerna/query-graph": "file:../query-graph",
"figgy-pudding": "^3.5.1",
"p-queue": "^4.0.0"
}
}
45 changes: 45 additions & 0 deletions utils/run-topologically/run-topologically.js
@@ -0,0 +1,45 @@
"use strict";

const PQueue = require("p-queue");
const figgyPudding = require("figgy-pudding");
const QueryGraph = require("@lerna/query-graph");

module.exports = runTopologically;

const TopologicalConfig = figgyPudding({
packages: {},
concurrency: {},
"reject-cycles": {},
rejectCycles: "reject-cycles",
runner: {},
});

function runTopologically(_opts) {
const opts = TopologicalConfig(_opts);
const { packages, concurrency, rejectCycles, runner } = opts;

const queue = new PQueue({ concurrency });
const graph = new QueryGraph(packages, rejectCycles);

return new Promise((resolve, reject) => {
const returnValues = [];

const queueNextAvailablePackages = () =>
graph.getAvailablePackages().forEach(({ pkg, name }) => {
graph.markAsTaken(name);

queue
.add(() =>
runner(pkg)
.then(value => returnValues.push(value))
.then(() => graph.markAsDone(pkg))
.then(() => queueNextAvailablePackages())
)
.catch(reject);
});

queueNextAvailablePackages();

return queue.onIdle().then(() => resolve(returnValues));
});
}

0 comments on commit 3a8b175

Please sign in to comment.