@hackwaly/task 0.3.0 → 0.3.2
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 +13 -14
- package/package.json +1 -1
- package/src/cli.d.ts +1 -0
- package/src/config.d.ts +21 -0
- package/src/config.js +13 -4
- package/src/errors.d.ts +3 -0
- package/src/index.d.ts +2 -0
- package/src/run.d.ts +2 -0
- package/src/run.js +0 -3
- package/src/scheduler.d.ts +5 -0
- package/src/scheduler.js +1 -4
- package/src/types.d.ts +23 -0
package/README.md
CHANGED
|
@@ -24,9 +24,9 @@ yarn add @hackwaly/task
|
|
|
24
24
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
27
|
-
1. Create a `taskfile.
|
|
27
|
+
1. Create a `taskfile.js` in your project root:
|
|
28
28
|
|
|
29
|
-
```
|
|
29
|
+
```javascript
|
|
30
30
|
import { configInit } from "@hackwaly/task";
|
|
31
31
|
|
|
32
32
|
const { defineTask } = configInit(import.meta);
|
|
@@ -92,7 +92,7 @@ interface TaskConfig {
|
|
|
92
92
|
|
|
93
93
|
Commands can be specified in multiple formats:
|
|
94
94
|
|
|
95
|
-
```
|
|
95
|
+
```javascript
|
|
96
96
|
// String (parsed with shell-like parsing)
|
|
97
97
|
command: "tsc --build --verbose"
|
|
98
98
|
|
|
@@ -110,7 +110,7 @@ command: {
|
|
|
110
110
|
|
|
111
111
|
Tasks can depend on other tasks. Dependencies are resolved automatically:
|
|
112
112
|
|
|
113
|
-
```
|
|
113
|
+
```javascript
|
|
114
114
|
export const generateTypes = defineTask({
|
|
115
115
|
name: "generate-types",
|
|
116
116
|
command: "generate-types src/schema.json",
|
|
@@ -129,7 +129,7 @@ export const build = defineTask({
|
|
|
129
129
|
|
|
130
130
|
For long-running processes like development servers:
|
|
131
131
|
|
|
132
|
-
```
|
|
132
|
+
```javascript
|
|
133
133
|
export const server = defineTask({
|
|
134
134
|
name: "server",
|
|
135
135
|
command: "node server.js",
|
|
@@ -183,7 +183,7 @@ Shows task names and descriptions in a formatted table.
|
|
|
183
183
|
|
|
184
184
|
### Basic Build Pipeline
|
|
185
185
|
|
|
186
|
-
```
|
|
186
|
+
```javascript
|
|
187
187
|
import { configInit } from "@hackwaly/task";
|
|
188
188
|
|
|
189
189
|
const { defineTask } = configInit(import.meta);
|
|
@@ -221,7 +221,7 @@ export const test = defineTask({
|
|
|
221
221
|
|
|
222
222
|
### Development Workflow
|
|
223
223
|
|
|
224
|
-
```
|
|
224
|
+
```javascript
|
|
225
225
|
export const generateSchema = defineTask({
|
|
226
226
|
name: "generate-schema",
|
|
227
227
|
command: "generate-schema api.yaml",
|
|
@@ -251,10 +251,10 @@ export const buildWatch = defineTask({
|
|
|
251
251
|
|
|
252
252
|
### Monorepo Support
|
|
253
253
|
|
|
254
|
-
Each package can have its own `taskfile.
|
|
254
|
+
Each package can have its own `taskfile.js`:
|
|
255
255
|
|
|
256
|
-
```
|
|
257
|
-
// packages/ui/taskfile.
|
|
256
|
+
```javascript
|
|
257
|
+
// packages/ui/taskfile.js
|
|
258
258
|
import { configInit } from "@hackwaly/task";
|
|
259
259
|
|
|
260
260
|
const { defineTask } = configInit(import.meta);
|
|
@@ -266,8 +266,8 @@ export const build = defineTask({
|
|
|
266
266
|
outputs: ["dist/**/*"],
|
|
267
267
|
});
|
|
268
268
|
|
|
269
|
-
// packages/app/taskfile.
|
|
270
|
-
import { build as buildUI } from "../ui/taskfile.
|
|
269
|
+
// packages/app/taskfile.js
|
|
270
|
+
import { build as buildUI } from "../ui/taskfile.js";
|
|
271
271
|
|
|
272
272
|
export const build = defineTask({
|
|
273
273
|
name: "build:app",
|
|
@@ -280,7 +280,7 @@ export const build = defineTask({
|
|
|
280
280
|
|
|
281
281
|
For complex tasks, you can provide custom logic:
|
|
282
282
|
|
|
283
|
-
```
|
|
283
|
+
```javascript
|
|
284
284
|
export const customTask = defineTask({
|
|
285
285
|
name: "custom",
|
|
286
286
|
async run(ctx) {
|
|
@@ -301,7 +301,6 @@ export const customTask = defineTask({
|
|
|
301
301
|
## Requirements
|
|
302
302
|
|
|
303
303
|
- Node.js 18+ with `--experimental-strip-types` support
|
|
304
|
-
- TypeScript 5.0+
|
|
305
304
|
|
|
306
305
|
## License
|
|
307
306
|
|
package/package.json
CHANGED
package/src/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function cliMain(): Promise<void>;
|
package/src/config.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TaskDef, TaskRunContext } from "./types.js";
|
|
2
|
+
export interface TaskConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
run?: (ctx: TaskRunContext) => Promise<void>;
|
|
6
|
+
command?: string | string[] | {
|
|
7
|
+
program: string;
|
|
8
|
+
args?: string[];
|
|
9
|
+
};
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
inputs?: string[];
|
|
13
|
+
outputs?: string[];
|
|
14
|
+
persistent?: boolean;
|
|
15
|
+
interruptible?: boolean;
|
|
16
|
+
dependsOn?: [TaskDef];
|
|
17
|
+
}
|
|
18
|
+
export interface ConfigAPI {
|
|
19
|
+
defineTask(config: TaskConfig): TaskDef;
|
|
20
|
+
}
|
|
21
|
+
export declare function configInit(importMeta: ImportMeta): ConfigAPI;
|
package/src/config.js
CHANGED
|
@@ -2,6 +2,8 @@ import NodePath from "node:path";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { runCommand } from "./run.js";
|
|
4
4
|
import { parseArgsStringToArgv } from "string-argv";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import styles from "ansi-styles";
|
|
5
7
|
function normalizeCommand(command) {
|
|
6
8
|
if (typeof command === "string") {
|
|
7
9
|
const argv = parseArgsStringToArgv(command);
|
|
@@ -31,12 +33,19 @@ export function configInit(importMeta) {
|
|
|
31
33
|
interruptible: config.interruptible ?? false,
|
|
32
34
|
};
|
|
33
35
|
const def = {
|
|
34
|
-
run: config.run
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
run: config.run
|
|
37
|
+
? async (ctx) => {
|
|
38
|
+
process.stdout.write(`▪▪▪▪ ${styles.bold.open}${meta.name}${styles.bold.close}\n`);
|
|
39
|
+
await config.run(ctx);
|
|
40
|
+
}
|
|
41
|
+
: command !== undefined
|
|
42
|
+
? async (ctx) => {
|
|
43
|
+
process.stdout.write(`▪▪▪▪ ${styles.bold.open}${meta.name}${styles.bold.close}\n`);
|
|
37
44
|
await runCommand(command, meta, ctx);
|
|
38
45
|
}
|
|
39
|
-
|
|
46
|
+
: async () => {
|
|
47
|
+
process.stdout.write(`▪▪▪▪ ${styles.bold.open}${meta.name}${styles.bold.close}\n`);
|
|
48
|
+
},
|
|
40
49
|
meta: meta,
|
|
41
50
|
deps: new Set(),
|
|
42
51
|
invDeps: new Set(),
|
package/src/errors.d.ts
ADDED
package/src/index.d.ts
ADDED
package/src/run.d.ts
ADDED
package/src/run.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { execa } from "execa";
|
|
2
|
-
import process from "node:process";
|
|
3
|
-
import styles from "ansi-styles";
|
|
4
2
|
import supportsColor from "supports-color";
|
|
5
3
|
const colorSupport = supportsColor.stdout;
|
|
6
4
|
export async function runCommand(command, meta, ctx) {
|
|
@@ -12,7 +10,6 @@ export async function runCommand(command, meta, ctx) {
|
|
|
12
10
|
const line3 = line2.replace(/\x1bc|\x1b\[2J(?:\x1b\[H)?/g, "");
|
|
13
11
|
yield `\r${name} | ${line3}`;
|
|
14
12
|
};
|
|
15
|
-
process.stdout.write(`▪▪▪▪ ${styles.bold.open}${name}${styles.bold.close}\n`);
|
|
16
13
|
await execa({
|
|
17
14
|
// @ts-expect-error
|
|
18
15
|
cwd: cwd,
|
package/src/scheduler.js
CHANGED
|
@@ -13,9 +13,6 @@ export async function start(taskChan, options) {
|
|
|
13
13
|
const isReady = (task) => {
|
|
14
14
|
if (!dirtySet.has(task))
|
|
15
15
|
throw new InvariantViolation();
|
|
16
|
-
if (pendingSet.has(task)) {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
16
|
for (const dep of task.deps) {
|
|
20
17
|
if (!upToDateSet.has(dep)) {
|
|
21
18
|
return false;
|
|
@@ -26,6 +23,7 @@ export async function start(taskChan, options) {
|
|
|
26
23
|
const checkReady = (task) => {
|
|
27
24
|
if (isReady(task)) {
|
|
28
25
|
dirtySet.delete(task);
|
|
26
|
+
pendingSet.delete(task);
|
|
29
27
|
readySet.add(task);
|
|
30
28
|
readySignal.next();
|
|
31
29
|
// Mark inverse dependencies as pending, so they won't become ready
|
|
@@ -73,7 +71,6 @@ export async function start(taskChan, options) {
|
|
|
73
71
|
upToDateSet.add(task);
|
|
74
72
|
for (const invDep of task.invDeps) {
|
|
75
73
|
if (pendingSet.has(invDep)) {
|
|
76
|
-
pendingSet.delete(invDep);
|
|
77
74
|
checkReady(invDep);
|
|
78
75
|
}
|
|
79
76
|
}
|
package/src/types.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface Command {
|
|
2
|
+
program: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
}
|
|
5
|
+
export interface TaskRunContext {
|
|
6
|
+
abort: AbortSignal;
|
|
7
|
+
}
|
|
8
|
+
export interface TaskMeta {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string | undefined;
|
|
11
|
+
cwd: string;
|
|
12
|
+
env: Record<string, string>;
|
|
13
|
+
inputs: string[];
|
|
14
|
+
outputs: string[];
|
|
15
|
+
persistent: boolean;
|
|
16
|
+
interruptible: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface TaskDef {
|
|
19
|
+
run: (ctx: TaskRunContext) => Promise<void>;
|
|
20
|
+
meta: TaskMeta;
|
|
21
|
+
deps: Set<TaskDef>;
|
|
22
|
+
invDeps: Set<TaskDef>;
|
|
23
|
+
}
|