hereby 1.6.4 → 1.7.1
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/README.md +1 -1
- package/dist/cli/formatTasks.js +4 -5
- package/dist/cli/index.js +2 -2
- package/dist/cli/loadHerebyfile.js +5 -5
- package/dist/cli/parseArgs.js +1 -1
- package/dist/cli/reexec.js +12 -13
- package/dist/cli/runner.js +1 -1
- package/dist/cli/utils.js +5 -12
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -16
- package/package.json +18 -15
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ well.
|
|
|
108
108
|
`hereby` does not support running tasks in series; specifying multiple tasks at
|
|
109
109
|
the CLI or as dependencies of another task will run them in parallel. This
|
|
110
110
|
matches the behavior of tools like `make`, which like `hereby` intend to encode
|
|
111
|
-
a
|
|
111
|
+
a dependency graph of tasks, not act as a script.
|
|
112
112
|
|
|
113
113
|
In general, if you're trying to emulate a serial task, you will likely be better
|
|
114
114
|
served by writing out explicit dependencies for your tasks.
|
package/dist/cli/formatTasks.js
CHANGED
|
@@ -2,8 +2,7 @@ import commandLineUsage from "command-line-usage";
|
|
|
2
2
|
import pc from "picocolors";
|
|
3
3
|
import { stringSorter, taskSorter } from "./utils.js";
|
|
4
4
|
export function formatTasks(format, tasks, defaultTask) {
|
|
5
|
-
tasks = tasks
|
|
6
|
-
.slice(0)
|
|
5
|
+
tasks = [...tasks]
|
|
7
6
|
.filter((task) => !task.options.hiddenFromTaskList)
|
|
8
7
|
.sort(taskSorter);
|
|
9
8
|
if (format === "simple") {
|
|
@@ -14,9 +13,9 @@ export function formatTasks(format, tasks, defaultTask) {
|
|
|
14
13
|
header: "Available tasks",
|
|
15
14
|
content: tasks.map((task) => {
|
|
16
15
|
var _a;
|
|
17
|
-
const name = task
|
|
18
|
-
? pc.
|
|
19
|
-
:
|
|
16
|
+
const name = task === defaultTask
|
|
17
|
+
? `${pc.green(task.options.name)} (default)`
|
|
18
|
+
: pc.blue(task.options.name);
|
|
20
19
|
const descriptionParts = [];
|
|
21
20
|
if (task.options.description) {
|
|
22
21
|
descriptionParts.push(task.options.description);
|
package/dist/cli/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import path from "path";
|
|
1
|
+
import path from "node:path";
|
|
2
2
|
import pc from "picocolors";
|
|
3
3
|
import { formatTasks } from "./formatTasks.js";
|
|
4
4
|
import { findHerebyfile, loadHerebyfile } from "./loadHerebyfile.js";
|
|
@@ -79,7 +79,7 @@ export async function selectTasks(d, herebyfile, herebyfilePath, taskNames) {
|
|
|
79
79
|
if (!task) {
|
|
80
80
|
let message = `Task "${name}" does not exist or is not exported from ${d.simplifyPath(herebyfilePath)}.`;
|
|
81
81
|
const { closest, distance } = await import("fastest-levenshtein");
|
|
82
|
-
const candidate = closest(name,
|
|
82
|
+
const candidate = closest(name, [...allTasks.keys()]);
|
|
83
83
|
if (distance(name, candidate) < name.length * 0.4) {
|
|
84
84
|
message += ` Did you mean "${candidate}"?`;
|
|
85
85
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
3
4
|
import pc from "picocolors";
|
|
4
|
-
import { pathToFileURL } from "url";
|
|
5
5
|
import { Task } from "../index.js";
|
|
6
6
|
import { UserError } from "./utils.js";
|
|
7
7
|
const filenames = ["Herebyfile", "herebyfile"];
|
|
8
8
|
const extensions = ["mjs", "js"];
|
|
9
|
-
const allFilenames = new Set(extensions.
|
|
9
|
+
const allFilenames = new Set(extensions.flatMap((e) => filenames.map((f) => `${f}.${e}`)));
|
|
10
10
|
export async function findHerebyfile(dir) {
|
|
11
11
|
const root = path.parse(dir).root;
|
|
12
12
|
for (; dir !== root; dir = path.dirname(dir)) {
|
|
@@ -52,7 +52,7 @@ export async function loadHerebyfile(herebyfilePath) {
|
|
|
52
52
|
if (exportedTasks.size === 0) {
|
|
53
53
|
throw new UserError("No tasks found. Did you forget to export your tasks?");
|
|
54
54
|
}
|
|
55
|
-
const tasks =
|
|
55
|
+
const tasks = [...exportedTasks.values()];
|
|
56
56
|
// We check this here by walking the DAG, as some dependencies may not be
|
|
57
57
|
// exported and therefore would not be seen by the above loop.
|
|
58
58
|
checkTaskInvariants(tasks);
|
package/dist/cli/parseArgs.js
CHANGED
|
@@ -20,7 +20,7 @@ export function parseArgs(argv) {
|
|
|
20
20
|
help: options["help"],
|
|
21
21
|
run: options["run"],
|
|
22
22
|
herebyfile: options["herebyfile"],
|
|
23
|
-
printTasks: options["tasks"] ? "normal" : options["tasks-simple"] ? "simple" : undefined,
|
|
23
|
+
printTasks: options["tasks"] ? "normal" : (options["tasks-simple"] ? "simple" : undefined),
|
|
24
24
|
version: options["version"],
|
|
25
25
|
};
|
|
26
26
|
}
|
package/dist/cli/reexec.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
2
|
import { UserError } from "./utils.js";
|
|
3
|
+
const cliExportName = "hereby/cli";
|
|
4
|
+
/**
|
|
5
|
+
* Checks to see if we need to re-exec another version of hereby.
|
|
6
|
+
* If this function returns true, the caller should return immediately
|
|
7
|
+
* and do no further work.
|
|
8
|
+
*/
|
|
3
9
|
export async function reexec(d, herebyfilePath) {
|
|
4
10
|
// If hereby is installed globally, but run against a Herebyfile in some
|
|
5
11
|
// other package, that Herebyfile's import will resolve to a different
|
|
6
12
|
// installation of the hereby package. There's no guarantee that the two
|
|
7
|
-
// are compatible (in fact, are guaranteed not to
|
|
13
|
+
// are compatible (in fact, they are guaranteed not to as Task is a class).
|
|
8
14
|
//
|
|
9
15
|
// Rather than trying to fix this by messing around with Node's resolution
|
|
10
16
|
// (which won't work in ESM anyway), instead opt to figure out the location
|
|
11
|
-
// of hereby as imported by the Herebyfile, and
|
|
12
|
-
//
|
|
13
|
-
// TODO: Rather than spawning a child process, perhaps we could instead
|
|
14
|
-
// import the CLI from the other version and run it.
|
|
17
|
+
// of hereby as imported by the Herebyfile, and then "reexec" it by importing.
|
|
15
18
|
if (d.isPnP) {
|
|
16
19
|
// When we are running within PnP, we can't really figure out what to
|
|
17
20
|
// do. import-meta-resolve doesn't implement this, so we can't do
|
|
@@ -21,10 +24,10 @@ export async function reexec(d, herebyfilePath) {
|
|
|
21
24
|
// a mismatch.
|
|
22
25
|
return false;
|
|
23
26
|
}
|
|
24
|
-
const thisCLI = await
|
|
27
|
+
const thisCLI = await d.resolve(cliExportName, import.meta.url);
|
|
25
28
|
let otherCLI;
|
|
26
29
|
try {
|
|
27
|
-
otherCLI = await
|
|
30
|
+
otherCLI = await d.resolve(cliExportName, pathToFileURL(herebyfilePath).toString());
|
|
28
31
|
}
|
|
29
32
|
catch {
|
|
30
33
|
throw new UserError("Unable to find hereby; ensure hereby is installed in your package.");
|
|
@@ -32,11 +35,7 @@ export async function reexec(d, herebyfilePath) {
|
|
|
32
35
|
if (thisCLI === otherCLI) {
|
|
33
36
|
return false;
|
|
34
37
|
}
|
|
35
|
-
|
|
36
|
-
await d.foregroundChild(d.execPath, args);
|
|
38
|
+
await import(otherCLI);
|
|
37
39
|
return true;
|
|
38
|
-
async function resolveToPath(specifier, url) {
|
|
39
|
-
return fileURLToPath(new URL(await d.resolve(specifier, url.toString())));
|
|
40
|
-
}
|
|
41
40
|
}
|
|
42
41
|
//# sourceMappingURL=reexec.js.map
|
package/dist/cli/runner.js
CHANGED
package/dist/cli/utils.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import os from "os";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { fileURLToPath } from "url";
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
5
|
export function taskSorter(a, b) {
|
|
6
6
|
return stringSorter(a.options.name, b.options.name);
|
|
7
7
|
}
|
|
@@ -52,8 +52,6 @@ export async function real() {
|
|
|
52
52
|
chdir: process.chdir,
|
|
53
53
|
simplifyPath,
|
|
54
54
|
argv: process.argv,
|
|
55
|
-
execArgv: process.execArgv,
|
|
56
|
-
execPath: process.execPath,
|
|
57
55
|
setExitCode: (code) => {
|
|
58
56
|
process.exitCode = code;
|
|
59
57
|
},
|
|
@@ -61,16 +59,11 @@ export async function real() {
|
|
|
61
59
|
// Not bothering to memoize this function; it will only be called once.
|
|
62
60
|
const resolve = await importResolve();
|
|
63
61
|
const packageJsonPath = fileURLToPath(await resolve("hereby/package.json", import.meta.url));
|
|
64
|
-
const packageJson = await fs.promises.readFile(packageJsonPath, "
|
|
62
|
+
const packageJson = await fs.promises.readFile(packageJsonPath, "utf8");
|
|
65
63
|
const { version } = JSON.parse(packageJson);
|
|
66
64
|
return version;
|
|
67
65
|
},
|
|
68
66
|
isPnP: !!process.versions["pnp"],
|
|
69
|
-
foregroundChild: async (program, args) => {
|
|
70
|
-
// Not bothering to memoize this import; it will only be called once.
|
|
71
|
-
const { default: foregroundChild } = await import("foreground-child");
|
|
72
|
-
foregroundChild(program, args);
|
|
73
|
-
},
|
|
74
67
|
resolve: async (specifier, parent) => {
|
|
75
68
|
const resolve = await importResolve();
|
|
76
69
|
return resolve(specifier, parent);
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export interface TaskOptions {
|
|
|
11
11
|
*/
|
|
12
12
|
description?: string | undefined;
|
|
13
13
|
/**
|
|
14
|
-
* A list of tasks that must
|
|
14
|
+
* A list of tasks that must have been run to completion before
|
|
15
15
|
* this task can execute.
|
|
16
16
|
*/
|
|
17
17
|
dependencies?: readonly Task[] | undefined;
|
package/dist/index.js
CHANGED
|
@@ -2,28 +2,36 @@
|
|
|
2
2
|
* A hereby Task. To get an instance, call `test`.
|
|
3
3
|
*/
|
|
4
4
|
export class Task {
|
|
5
|
+
/* @internal */
|
|
6
|
+
get options() {
|
|
7
|
+
return this._options;
|
|
8
|
+
}
|
|
9
|
+
/* @internal */
|
|
10
|
+
static create(options) {
|
|
11
|
+
return new Task(options);
|
|
12
|
+
}
|
|
5
13
|
constructor(options) {
|
|
6
14
|
// Runtime typecheck; consumers of hereby may not have enabled
|
|
7
15
|
// typechecking, so this is helpful.
|
|
8
16
|
var _a;
|
|
9
17
|
if (typeof options.name !== "string") {
|
|
10
|
-
throw new
|
|
18
|
+
throw new TypeError("Task name is not a string.");
|
|
11
19
|
}
|
|
12
|
-
if (typeof options.description !== "string" &&
|
|
13
|
-
throw new
|
|
20
|
+
if (typeof options.description !== "string" && options.description !== undefined) {
|
|
21
|
+
throw new TypeError("Task description is not a string or undefined.");
|
|
14
22
|
}
|
|
15
|
-
if (!Array.isArray(options.dependencies) &&
|
|
16
|
-
throw new
|
|
23
|
+
if (!Array.isArray(options.dependencies) && options.dependencies !== undefined) {
|
|
24
|
+
throw new TypeError("Task dependencies is not an array or undefined.");
|
|
17
25
|
}
|
|
18
26
|
if (options.dependencies) {
|
|
19
27
|
for (const dep of options.dependencies) {
|
|
20
28
|
if (!(dep instanceof Task)) {
|
|
21
|
-
throw new
|
|
29
|
+
throw new TypeError("Task dependency is not a task.");
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
}
|
|
25
|
-
if (typeof options.run !== "function" &&
|
|
26
|
-
throw new
|
|
33
|
+
if (typeof options.run !== "function" && options.run !== undefined) {
|
|
34
|
+
throw new TypeError("Task run is not a function or undefined.");
|
|
27
35
|
}
|
|
28
36
|
// Non-type checks.
|
|
29
37
|
if (!options.name) {
|
|
@@ -37,14 +45,6 @@ export class Task {
|
|
|
37
45
|
}
|
|
38
46
|
this._options = options;
|
|
39
47
|
}
|
|
40
|
-
/* @internal */
|
|
41
|
-
get options() {
|
|
42
|
-
return this._options;
|
|
43
|
-
}
|
|
44
|
-
/* @internal */
|
|
45
|
-
static create(options) {
|
|
46
|
-
return new Task(options);
|
|
47
|
-
}
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
50
|
* Creates a new Task.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hereby",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "A simple task runner",
|
|
5
5
|
"repository": "github:jakebailey/hereby",
|
|
6
6
|
"type": "module",
|
|
@@ -41,8 +41,7 @@
|
|
|
41
41
|
"command-line-args": "^5.2.1",
|
|
42
42
|
"command-line-usage": "^6.1.3",
|
|
43
43
|
"fastest-levenshtein": "^1.0.16",
|
|
44
|
-
"
|
|
45
|
-
"import-meta-resolve": "^2.1.0",
|
|
44
|
+
"import-meta-resolve": "^2.2.1",
|
|
46
45
|
"picocolors": "^1.0.0",
|
|
47
46
|
"pretty-ms": "^8.0.0"
|
|
48
47
|
},
|
|
@@ -51,23 +50,27 @@
|
|
|
51
50
|
"@tsconfig/node12": "^1.0.11",
|
|
52
51
|
"@types/command-line-args": "^5.2.0",
|
|
53
52
|
"@types/command-line-usage": "^5.0.2",
|
|
54
|
-
"@types/
|
|
55
|
-
"@types/node": "^14.18.32",
|
|
53
|
+
"@types/node": "^14.18.36",
|
|
56
54
|
"@types/tmp": "^0.2.3",
|
|
57
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
58
|
-
"@typescript-eslint/parser": "^5.
|
|
59
|
-
"ava": "
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
|
56
|
+
"@typescript-eslint/parser": "^5.48.2",
|
|
57
|
+
"ava": "~5.0.1",
|
|
60
58
|
"c8": "^7.12.0",
|
|
61
|
-
"dprint": "^0.
|
|
62
|
-
"eslint": "^8.
|
|
63
|
-
"eslint-plugin-ava": "^
|
|
64
|
-
"eslint-plugin-simple-import-sort": "^
|
|
59
|
+
"dprint": "^0.34.4",
|
|
60
|
+
"eslint": "^8.32.0",
|
|
61
|
+
"eslint-plugin-ava": "^14.0.0",
|
|
62
|
+
"eslint-plugin-simple-import-sort": "^9.0.0",
|
|
63
|
+
"eslint-plugin-unicorn": "^45.0.2",
|
|
65
64
|
"execa": "^6.1.0",
|
|
66
65
|
"moq.ts": "^9.0.2",
|
|
67
|
-
"
|
|
68
|
-
"rimraf": "^3.0.2",
|
|
66
|
+
"rimraf": "^4.1.1",
|
|
69
67
|
"tmp": "^0.2.1",
|
|
70
|
-
"typescript": "~4.
|
|
68
|
+
"typescript": "~4.9.4"
|
|
69
|
+
},
|
|
70
|
+
"overrides": {
|
|
71
|
+
"ava": {
|
|
72
|
+
"emittery": "1.0.0"
|
|
73
|
+
}
|
|
71
74
|
},
|
|
72
75
|
"packageManager": "npm@8.17.0",
|
|
73
76
|
"volta": {
|