hereby 1.0.3 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +40 -33
- package/dist/cli/reexec.js +7 -9
- package/dist/cli/runner.js +7 -12
- package/dist/cli/utils.js +22 -8
- package/dist/cli.js +2 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -1
- package/dist/runner.js +7 -3
- package/package.json +12 -16
package/dist/cli/index.js
CHANGED
|
@@ -1,74 +1,81 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
+
import { closest, distance } from "fastest-levenshtein";
|
|
2
3
|
import path from "path";
|
|
3
4
|
import { formatTasks } from "./formatTasks.js";
|
|
4
5
|
import { findHerebyfile, loadHerebyfile } from "./loadHerebyfile.js";
|
|
5
6
|
import { getUsage, parseArgs } from "./parseArgs.js";
|
|
6
7
|
import { reexec } from "./reexec.js";
|
|
7
|
-
import {
|
|
8
|
+
import { CLIRunner } from "./runner.js";
|
|
8
9
|
import { ExitCodeError, simplifyPath, UserError } from "./utils.js";
|
|
9
|
-
export async function main(
|
|
10
|
+
export async function main(d) {
|
|
10
11
|
try {
|
|
11
|
-
await mainWorker(
|
|
12
|
+
await mainWorker(d);
|
|
12
13
|
}
|
|
13
14
|
catch (e) {
|
|
14
15
|
if (e instanceof ExitCodeError) {
|
|
15
|
-
|
|
16
|
+
d.setExitCode(e.exitCode);
|
|
16
17
|
}
|
|
17
18
|
else if (e instanceof UserError) {
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
d.error(`${chalk.red("Error")}: ${e.message}`);
|
|
20
|
+
d.setExitCode(1);
|
|
20
21
|
}
|
|
21
22
|
else {
|
|
22
23
|
throw e;
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
|
-
async function mainWorker(
|
|
27
|
-
const args = parseArgs(
|
|
27
|
+
async function mainWorker(d) {
|
|
28
|
+
const args = parseArgs(d.argv.slice(2));
|
|
28
29
|
if (args.help) {
|
|
29
|
-
|
|
30
|
+
d.log(getUsage());
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
|
-
let herebyfilePath = args.herebyfile ?? (await findHerebyfile(
|
|
33
|
-
herebyfilePath = path.resolve(
|
|
34
|
-
if (await reexec(
|
|
33
|
+
let herebyfilePath = args.herebyfile ?? (await findHerebyfile(d.cwd()));
|
|
34
|
+
herebyfilePath = path.resolve(d.cwd(), herebyfilePath);
|
|
35
|
+
if (await reexec(d, herebyfilePath)) {
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
d.chdir(path.dirname(herebyfilePath));
|
|
39
|
+
d.log(`Using ${simplifyPath(herebyfilePath)}`);
|
|
38
40
|
const herebyfile = await loadHerebyfile(herebyfilePath);
|
|
39
41
|
if (args.printTasks) {
|
|
40
|
-
|
|
42
|
+
d.log(formatTasks(herebyfile.tasks, herebyfile.defaultTask));
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
45
|
+
const tasks = selectTasks(herebyfile, args.run);
|
|
46
|
+
try {
|
|
47
|
+
const runner = new CLIRunner(d);
|
|
48
|
+
await runner.runTasks(...tasks);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
// We will have already printed some message here.
|
|
52
|
+
// Set the error code and let the process run to completion,
|
|
53
|
+
// so we don't end up with an unflushed output.
|
|
54
|
+
throw new ExitCodeError(1, e);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function selectTasks(herebyfile, taskNames) {
|
|
43
58
|
const allTasks = new Map();
|
|
44
59
|
for (const task of herebyfile.tasks) {
|
|
45
60
|
allTasks.set(task.options.name, task);
|
|
46
61
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
tasks = args.run.map((name) => {
|
|
62
|
+
if (taskNames && taskNames.length > 0) {
|
|
63
|
+
return taskNames.map((name) => {
|
|
50
64
|
const task = allTasks.get(name);
|
|
51
65
|
if (!task) {
|
|
52
|
-
|
|
66
|
+
let message = `Task "${name}" does not exist or is not exported in the Herebyfile.`;
|
|
67
|
+
const candidate = closest(name, Array.from(allTasks.keys()));
|
|
68
|
+
if (distance(name, candidate) < name.length * 0.4) {
|
|
69
|
+
message += ` Did you mean "${candidate}?"`;
|
|
70
|
+
}
|
|
71
|
+
throw new UserError(message);
|
|
53
72
|
}
|
|
54
73
|
return task;
|
|
55
74
|
});
|
|
56
75
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
throw new UserError("No default task defined; please specify a task name.");
|
|
60
|
-
}
|
|
61
|
-
tasks = [herebyfile.defaultTask];
|
|
62
|
-
}
|
|
63
|
-
system.log(`Using ${simplifyPath(herebyfilePath)}`);
|
|
64
|
-
try {
|
|
65
|
-
await runTasksWithCLIRunner(system, ...tasks);
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// We will have already printed some message here.
|
|
69
|
-
// Set the error code and let the process run to completion,
|
|
70
|
-
// so we don't end up with an unflushed output.
|
|
71
|
-
throw new ExitCodeError(1);
|
|
76
|
+
if (!herebyfile.defaultTask) {
|
|
77
|
+
throw new UserError("No default task defined; please specify a task name.");
|
|
72
78
|
}
|
|
79
|
+
return [herebyfile.defaultTask];
|
|
73
80
|
}
|
|
74
81
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/reexec.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
|
-
import foregroundChild from "foreground-child";
|
|
3
|
-
import { resolve } from "import-meta-resolve";
|
|
4
2
|
import { fileURLToPath, pathToFileURL } from "url";
|
|
5
3
|
import { UserError } from "./utils.js";
|
|
6
|
-
export async function reexec(
|
|
4
|
+
export async function reexec(d, herebyfilePath) {
|
|
7
5
|
// If hereby is installed globally, but run against a Herebyfile in some
|
|
8
6
|
// other package, that Herebyfile's import will resolve to a different
|
|
9
7
|
// installation of the hereby package. There's no guarantee that the two
|
|
@@ -27,12 +25,12 @@ export async function reexec(system, herebyfilePath) {
|
|
|
27
25
|
return false;
|
|
28
26
|
}
|
|
29
27
|
// TODO: If this turns out to be common, remove this warning.
|
|
30
|
-
|
|
31
|
-
const args = [...
|
|
32
|
-
foregroundChild(
|
|
28
|
+
d.error(`${chalk.yellow("Warning")}: re-running hereby as imported by the Herebyfile.`);
|
|
29
|
+
const args = [...d.execArgv, otherCLI, ...d.argv.slice(2)];
|
|
30
|
+
d.foregroundChild(d.execPath, args);
|
|
33
31
|
return true;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
async function resolveToPath(specifier, url) {
|
|
33
|
+
return fileURLToPath(new URL(await d.resolve(specifier, url.toString())));
|
|
34
|
+
}
|
|
37
35
|
}
|
|
38
36
|
//# sourceMappingURL=reexec.js.map
|
package/dist/cli/runner.js
CHANGED
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
import assert from "assert";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import prettyMilliseconds from "pretty-ms";
|
|
4
3
|
import { Runner } from "../runner.js";
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
class CLIRunner extends Runner {
|
|
9
|
-
constructor(options) {
|
|
10
|
-
super(options);
|
|
4
|
+
export class CLIRunner extends Runner {
|
|
5
|
+
constructor(d) {
|
|
6
|
+
super({ concurrency: d.numCPUs });
|
|
11
7
|
this._errored = false;
|
|
12
8
|
this._startTimes = new WeakMap();
|
|
13
|
-
this.
|
|
9
|
+
this._d = d;
|
|
14
10
|
}
|
|
15
11
|
onTaskStart(task) {
|
|
16
12
|
this._startTimes.set(task, Date.now());
|
|
17
13
|
if (this._errored) {
|
|
18
14
|
return; // Skip logging.
|
|
19
15
|
}
|
|
20
|
-
this.
|
|
16
|
+
this._d.log(`Starting ${chalk.blue(task.options.name)}`);
|
|
21
17
|
}
|
|
22
18
|
onTaskFinish(task) {
|
|
23
19
|
if (this._errored) {
|
|
24
20
|
return; // Skip logging.
|
|
25
21
|
}
|
|
26
22
|
const took = Date.now() - checkDefined(this._startTimes.get(task));
|
|
27
|
-
this.
|
|
23
|
+
this._d.log(`Finished ${chalk.green(task.options.name)} in ${this._d.prettyMilliseconds(took)}`);
|
|
28
24
|
}
|
|
29
25
|
onTaskError(task, e) {
|
|
30
26
|
if (this._errored) {
|
|
31
27
|
return; // Skip logging.
|
|
32
28
|
}
|
|
33
29
|
this._errored = true;
|
|
34
|
-
this.
|
|
35
|
-
this._system.error(`${e}`);
|
|
30
|
+
this._d.error(`Error in ${chalk.red(task.options.name)}\n${e}`);
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
function checkDefined(value) {
|
package/dist/cli/utils.js
CHANGED
|
@@ -31,20 +31,34 @@ export class UserError extends Error {
|
|
|
31
31
|
* without logging anything.
|
|
32
32
|
*/
|
|
33
33
|
export class ExitCodeError {
|
|
34
|
-
constructor(exitCode) {
|
|
34
|
+
constructor(exitCode, reason) {
|
|
35
35
|
this.exitCode = exitCode;
|
|
36
|
+
this.reason = reason;
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
export function
|
|
39
|
+
export async function real() {
|
|
40
|
+
const { default: foregroundChild } = await import("foreground-child");
|
|
41
|
+
const { resolve } = await import("import-meta-resolve");
|
|
42
|
+
const { default: prettyMilliseconds } = await import("pretty-ms");
|
|
43
|
+
/* eslint-disable no-restricted-globals */
|
|
39
44
|
return {
|
|
40
|
-
log
|
|
41
|
-
|
|
45
|
+
log: console.log,
|
|
46
|
+
error: console.error,
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
48
|
+
cwd: process.cwd,
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
50
|
+
chdir: process.chdir,
|
|
51
|
+
argv: process.argv,
|
|
52
|
+
execArgv: process.execArgv,
|
|
53
|
+
execPath: process.execPath,
|
|
54
|
+
setExitCode: (code) => {
|
|
55
|
+
process.exitCode = code;
|
|
42
56
|
},
|
|
43
|
-
error(message) {
|
|
44
|
-
process.stderr.write(message + "\n");
|
|
45
|
-
},
|
|
46
|
-
process,
|
|
47
57
|
numCPUs: os.cpus().length,
|
|
58
|
+
foregroundChild,
|
|
59
|
+
resolve,
|
|
60
|
+
prettyMilliseconds,
|
|
48
61
|
};
|
|
62
|
+
/* eslint-enable no-restricted-globals */
|
|
49
63
|
}
|
|
50
64
|
//# sourceMappingURL=utils.js.map
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { main } from "./cli/index.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
await main(createSystem(process));
|
|
3
|
+
import { real } from "./cli/utils.js";
|
|
4
|
+
await main(await real());
|
|
6
5
|
//# sourceMappingURL=cli.js.map
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -34,7 +34,11 @@ export class Task {
|
|
|
34
34
|
if (!options.dependencies?.length && !options.run) {
|
|
35
35
|
throw new Error("Task must have at run function or dependencies.");
|
|
36
36
|
}
|
|
37
|
-
this.
|
|
37
|
+
this._options = options;
|
|
38
|
+
}
|
|
39
|
+
/* @internal */
|
|
40
|
+
get options() {
|
|
41
|
+
return this._options;
|
|
38
42
|
}
|
|
39
43
|
/* @internal */
|
|
40
44
|
static create(options) {
|
package/dist/runner.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import pLimit from "p-limit";
|
|
2
2
|
export class Runner {
|
|
3
3
|
constructor(options) {
|
|
4
4
|
this._addedTasks = new WeakMap();
|
|
5
|
-
this.
|
|
5
|
+
this._limiter = (fn) => fn();
|
|
6
|
+
const concurrency = options?.concurrency;
|
|
7
|
+
if (concurrency !== undefined) {
|
|
8
|
+
this._limiter = pLimit(concurrency);
|
|
9
|
+
}
|
|
6
10
|
}
|
|
7
11
|
async runTasks(...tasks) {
|
|
8
12
|
await Promise.all(tasks.map((task) => {
|
|
@@ -24,7 +28,7 @@ export class Runner {
|
|
|
24
28
|
if (!run) {
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
27
|
-
return this.
|
|
31
|
+
return this._limiter(async () => {
|
|
28
32
|
try {
|
|
29
33
|
this.onTaskStart?.(task);
|
|
30
34
|
await run();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hereby",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "A simple task runner",
|
|
5
5
|
"repository": "github:jakebailey/hereby",
|
|
6
6
|
"type": "module",
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
"LICENSE",
|
|
36
36
|
"./dist/**/*.js",
|
|
37
37
|
"!**/__tests__/**",
|
|
38
|
-
"./dist/index.d.ts"
|
|
39
|
-
"!./dist/testUtils.js"
|
|
38
|
+
"./dist/index.d.ts"
|
|
40
39
|
],
|
|
41
40
|
"dependencies": {
|
|
42
41
|
"chalk": "^5.0.1",
|
|
43
42
|
"command-line-args": "^5.2.1",
|
|
44
43
|
"command-line-usage": "^6.1.3",
|
|
44
|
+
"fastest-levenshtein": "^1.0.16",
|
|
45
45
|
"foreground-child": "^2.0.0",
|
|
46
46
|
"import-meta-resolve": "^2.1.0",
|
|
47
|
-
"p-
|
|
47
|
+
"p-limit": "^4.0.0",
|
|
48
48
|
"pretty-ms": "^8.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
@@ -52,24 +52,22 @@
|
|
|
52
52
|
"@tsconfig/node14": "^1.0.3",
|
|
53
53
|
"@types/command-line-args": "^5.2.0",
|
|
54
54
|
"@types/command-line-usage": "^5.0.2",
|
|
55
|
-
"@types/node": "^14.18.
|
|
56
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
57
|
-
"@typescript-eslint/parser": "^5.
|
|
58
|
-
"ava": "^4.3.
|
|
55
|
+
"@types/node": "^14.18.28",
|
|
56
|
+
"@typescript-eslint/eslint-plugin": "^5.36.2",
|
|
57
|
+
"@typescript-eslint/parser": "^5.36.2",
|
|
58
|
+
"ava": "^4.3.3",
|
|
59
59
|
"c8": "^7.12.0",
|
|
60
|
-
"
|
|
61
|
-
"eslint": "^8.22.0",
|
|
60
|
+
"eslint": "^8.23.0",
|
|
62
61
|
"eslint-config-prettier": "^8.5.0",
|
|
63
62
|
"eslint-plugin-ava": "^13.2.0",
|
|
64
|
-
"eslint-plugin-simple-import-sort": "^
|
|
65
|
-
"esmock": "^1.9.4",
|
|
63
|
+
"eslint-plugin-simple-import-sort": "^8.0.0",
|
|
66
64
|
"execa": "^6.1.0",
|
|
67
65
|
"moq.ts": "^9.0.2",
|
|
68
66
|
"prettier": "^2.7.1",
|
|
69
|
-
"release-it": "^15.
|
|
67
|
+
"release-it": "^15.4.1",
|
|
70
68
|
"rimraf": "^3.0.2",
|
|
71
69
|
"tempy": "^3.0.0",
|
|
72
|
-
"typescript": "
|
|
70
|
+
"typescript": "~4.8.3"
|
|
73
71
|
},
|
|
74
72
|
"packageManager": "npm@8.17.0",
|
|
75
73
|
"volta": {
|
|
@@ -91,8 +89,6 @@
|
|
|
91
89
|
"compile": false
|
|
92
90
|
},
|
|
93
91
|
"environmentVariables": {
|
|
94
|
-
"NODE_OPTIONS": "--loader=esmock",
|
|
95
|
-
"NODE_NO_WARNINGS": "1",
|
|
96
92
|
"FORCE_COLOR": "0"
|
|
97
93
|
}
|
|
98
94
|
},
|