@plugjs/plug 0.0.12 → 0.0.15
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/{types → dist}/assert.d.ts +0 -0
- package/dist/async.cjs +20 -19
- package/dist/async.cjs.map +1 -1
- package/dist/async.d.ts +20 -0
- package/dist/async.mjs +18 -17
- package/dist/async.mjs.map +1 -1
- package/dist/build.cjs +144 -110
- package/dist/build.cjs.map +2 -2
- package/dist/build.d.ts +12 -0
- package/dist/build.mjs +146 -112
- package/dist/build.mjs.map +2 -2
- package/dist/files.cjs +2 -16
- package/dist/files.cjs.map +1 -1
- package/{types → dist}/files.d.ts +3 -10
- package/dist/files.mjs +3 -17
- package/dist/files.mjs.map +1 -1
- package/dist/fork.cjs +28 -40
- package/dist/fork.cjs.map +1 -1
- package/dist/fork.d.ts +36 -0
- package/dist/fork.mjs +29 -40
- package/dist/fork.mjs.map +1 -1
- package/dist/helpers.cjs +61 -63
- package/dist/helpers.cjs.map +2 -2
- package/dist/helpers.d.ts +21 -0
- package/dist/helpers.mjs +61 -64
- package/dist/helpers.mjs.map +2 -2
- package/dist/index.cjs +3 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/log/colors.cjs +3 -1
- package/dist/log/colors.cjs.map +1 -1
- package/{types → dist}/log/colors.d.ts +2 -2
- package/dist/log/colors.mjs +3 -1
- package/dist/log/colors.mjs.map +1 -1
- package/{types → dist}/log/emit.d.ts +1 -1
- package/{types → dist}/log/levels.d.ts +0 -0
- package/dist/log/logger.cjs +4 -0
- package/dist/log/logger.cjs.map +1 -1
- package/{types → dist}/log/logger.d.ts +4 -1
- package/dist/log/logger.mjs +4 -0
- package/dist/log/logger.mjs.map +1 -1
- package/{types → dist}/log/options.d.ts +1 -1
- package/dist/log/report.cjs +4 -13
- package/dist/log/report.cjs.map +1 -1
- package/{types → dist}/log/report.d.ts +36 -4
- package/dist/log/report.mjs +3 -12
- package/dist/log/report.mjs.map +1 -1
- package/{types → dist}/log/spinner.d.ts +0 -0
- package/dist/log.cjs +1 -1
- package/dist/log.cjs.map +1 -1
- package/{types → dist}/log.d.ts +6 -6
- package/dist/log.mjs +2 -2
- package/dist/log.mjs.map +1 -1
- package/{types → dist}/paths.d.ts +0 -0
- package/dist/pipe.cjs +41 -34
- package/dist/pipe.cjs.map +1 -1
- package/dist/pipe.d.ts +182 -0
- package/dist/pipe.mjs +38 -32
- package/dist/pipe.mjs.map +1 -1
- package/dist/plugs/copy.cjs +15 -25
- package/dist/plugs/copy.cjs.map +2 -2
- package/dist/plugs/copy.d.ts +28 -0
- package/dist/plugs/copy.mjs +15 -17
- package/dist/plugs/copy.mjs.map +2 -2
- package/{types → dist}/plugs/coverage/analysis.d.ts +2 -2
- package/dist/plugs/coverage/report.cjs +4 -2
- package/dist/plugs/coverage/report.cjs.map +1 -1
- package/{types → dist}/plugs/coverage/report.d.ts +3 -3
- package/dist/plugs/coverage/report.mjs +4 -2
- package/dist/plugs/coverage/report.mjs.map +1 -1
- package/dist/plugs/coverage.cjs +23 -27
- package/dist/plugs/coverage.cjs.map +1 -1
- package/dist/plugs/coverage.d.ts +49 -0
- package/dist/plugs/coverage.mjs +24 -20
- package/dist/plugs/coverage.mjs.map +1 -1
- package/dist/plugs/debug.cjs +8 -37
- package/dist/plugs/debug.cjs.map +1 -1
- package/dist/plugs/debug.d.ts +7 -0
- package/dist/plugs/debug.mjs +24 -20
- package/dist/plugs/debug.mjs.map +1 -1
- package/{types → dist}/plugs/esbuild/bundle-locals.d.ts +0 -0
- package/{types → dist}/plugs/esbuild/fix-extensions.d.ts +0 -0
- package/dist/plugs/esbuild/fix-extensions.mjs +1 -1
- package/dist/plugs/esbuild/fix-extensions.mjs.map +1 -1
- package/dist/plugs/esbuild.cjs +14 -25
- package/dist/plugs/esbuild.cjs.map +1 -1
- package/dist/plugs/esbuild.d.ts +18 -0
- package/dist/plugs/esbuild.mjs +14 -17
- package/dist/plugs/esbuild.mjs.map +1 -1
- package/dist/plugs/eslint/runner.cjs +5 -6
- package/dist/plugs/eslint/runner.cjs.map +1 -1
- package/dist/plugs/eslint/runner.d.ts +8 -0
- package/dist/plugs/eslint/runner.mjs +6 -7
- package/dist/plugs/eslint/runner.mjs.map +1 -1
- package/dist/{task.cjs → plugs/eslint.cjs} +7 -24
- package/dist/plugs/eslint.cjs.map +6 -0
- package/dist/plugs/eslint.d.ts +34 -0
- package/dist/plugs/eslint.mjs +5 -0
- package/dist/plugs/eslint.mjs.map +6 -0
- package/dist/plugs/exec.cjs +20 -24
- package/dist/plugs/exec.cjs.map +1 -1
- package/dist/plugs/exec.d.ts +90 -0
- package/dist/plugs/exec.mjs +20 -23
- package/dist/plugs/exec.mjs.map +1 -1
- package/dist/plugs/filter.cjs +9 -19
- package/dist/plugs/filter.cjs.map +1 -1
- package/dist/plugs/filter.d.ts +29 -0
- package/dist/plugs/filter.mjs +10 -12
- package/dist/plugs/filter.mjs.map +1 -1
- package/dist/plugs/mocha/reporter.cjs +19 -6
- package/dist/plugs/mocha/reporter.cjs.map +1 -1
- package/{types → dist}/plugs/mocha/reporter.d.ts +0 -2
- package/dist/plugs/mocha/reporter.mjs +18 -4
- package/dist/plugs/mocha/reporter.mjs.map +1 -1
- package/dist/plugs/mocha/runner.cjs +4 -5
- package/dist/plugs/mocha/runner.cjs.map +1 -1
- package/dist/plugs/mocha/runner.d.ts +8 -0
- package/dist/plugs/mocha/runner.mjs +5 -6
- package/dist/plugs/mocha/runner.mjs.map +1 -1
- package/dist/plugs/mocha.cjs +22 -0
- package/dist/plugs/mocha.cjs.map +6 -0
- package/{types/plugs/mocha/runner.d.ts → dist/plugs/mocha.d.ts} +9 -8
- package/dist/plugs/mocha.mjs +5 -0
- package/dist/plugs/mocha.mjs.map +6 -0
- package/dist/plugs/rmf.cjs +4 -32
- package/dist/plugs/rmf.cjs.map +1 -1
- package/dist/plugs/rmf.d.ts +11 -0
- package/dist/plugs/rmf.mjs +25 -20
- package/dist/plugs/rmf.mjs.map +1 -1
- package/{types → dist}/plugs/tsc/compiler.d.ts +1 -1
- package/{types → dist}/plugs/tsc/options.d.ts +1 -1
- package/{types → dist}/plugs/tsc/report.d.ts +2 -2
- package/dist/plugs/tsc/runner.cjs +12 -11
- package/dist/plugs/tsc/runner.cjs.map +1 -1
- package/dist/plugs/tsc/runner.d.ts +8 -0
- package/dist/plugs/tsc/runner.mjs +12 -11
- package/dist/plugs/tsc/runner.mjs.map +1 -1
- package/dist/plugs/tsc.cjs +7 -0
- package/dist/plugs/tsc.cjs.map +6 -0
- package/dist/plugs/tsc.d.ts +36 -0
- package/dist/plugs/tsc.mjs +15 -0
- package/dist/plugs/tsc.mjs.map +6 -0
- package/dist/plugs.cjs +3 -5
- package/dist/plugs.cjs.map +1 -1
- package/dist/plugs.d.ts +10 -0
- package/dist/plugs.mjs +3 -5
- package/dist/plugs.mjs.map +1 -1
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +6 -0
- package/dist/types.d.ts +72 -0
- package/dist/types.mjs +1 -0
- package/dist/types.mjs.map +6 -0
- package/{types → dist}/utils/asyncfs.d.ts +0 -0
- package/dist/utils/caller.cjs +8 -11
- package/dist/utils/caller.cjs.map +2 -2
- package/dist/utils/caller.d.ts +2 -0
- package/dist/utils/caller.mjs +8 -11
- package/dist/utils/caller.mjs.map +2 -2
- package/{types → dist}/utils/match.d.ts +0 -0
- package/dist/utils/options.cjs +4 -6
- package/dist/utils/options.cjs.map +1 -1
- package/dist/utils/options.d.ts +16 -0
- package/dist/utils/options.mjs +4 -6
- package/dist/utils/options.mjs.map +1 -1
- package/{types → dist}/utils/walk.d.ts +2 -2
- package/extra/cli.mjs +31 -20
- package/extra/ts-loader.mjs +6 -5
- package/package.json +10 -10
- package/src/async.ts +27 -19
- package/src/files.ts +6 -30
- package/src/fork.ts +35 -76
- package/src/helpers.ts +89 -101
- package/src/index.ts +10 -15
- package/src/log/colors.ts +4 -3
- package/src/log/emit.ts +4 -4
- package/src/log/logger.ts +12 -4
- package/src/log/options.ts +1 -1
- package/src/log/report.ts +10 -24
- package/src/log/spinner.ts +3 -3
- package/src/log.ts +9 -9
- package/src/paths.ts +1 -1
- package/src/pipe.ts +191 -178
- package/src/plugs/copy.ts +40 -31
- package/src/plugs/coverage/analysis.ts +4 -4
- package/src/plugs/coverage/report.ts +9 -6
- package/src/plugs/coverage.ts +68 -55
- package/src/plugs/debug.ts +22 -27
- package/src/plugs/esbuild/fix-extensions.ts +2 -2
- package/src/plugs/esbuild.ts +42 -46
- package/src/plugs/eslint/runner.ts +16 -31
- package/src/plugs/eslint.ts +42 -0
- package/src/plugs/exec.ts +93 -82
- package/src/plugs/filter.ts +42 -27
- package/src/plugs/mocha/reporter.ts +19 -5
- package/src/plugs/mocha/runner.ts +12 -38
- package/src/plugs/mocha.ts +41 -0
- package/src/plugs/rmf.ts +21 -25
- package/src/plugs/tsc/compiler.ts +1 -1
- package/src/plugs/tsc/options.ts +2 -2
- package/src/plugs/tsc/report.ts +2 -2
- package/src/plugs/tsc/runner.ts +24 -30
- package/src/plugs/tsc.ts +45 -0
- package/src/plugs.ts +10 -25
- package/src/types.ts +123 -0
- package/src/utils/caller.ts +11 -22
- package/src/utils/options.ts +49 -17
- package/src/utils/walk.ts +4 -4
- package/dist/run.cjs +0 -90
- package/dist/run.cjs.map +0 -6
- package/dist/run.mjs +0 -65
- package/dist/run.mjs.map +0 -6
- package/dist/task.cjs.map +0 -6
- package/dist/task.mjs +0 -14
- package/dist/task.mjs.map +0 -6
- package/src/run.ts +0 -159
- package/src/task.ts +0 -26
- package/types/async.d.ts +0 -20
- package/types/build.d.ts +0 -56
- package/types/fork.d.ts +0 -57
- package/types/helpers.d.ts +0 -43
- package/types/index.d.ts +0 -14
- package/types/pipe.d.ts +0 -152
- package/types/plugs/copy.d.ts +0 -27
- package/types/plugs/coverage.d.ts +0 -46
- package/types/plugs/debug.d.ts +0 -14
- package/types/plugs/esbuild.d.ts +0 -23
- package/types/plugs/eslint/runner.d.ts +0 -22
- package/types/plugs/exec.d.ts +0 -90
- package/types/plugs/filter.d.ts +0 -23
- package/types/plugs/rmf.d.ts +0 -15
- package/types/plugs/tsc/runner.d.ts +0 -13
- package/types/plugs.d.ts +0 -17
- package/types/run.d.ts +0 -89
- package/types/task.d.ts +0 -15
- package/types/utils/caller.d.ts +0 -7
- package/types/utils/options.d.ts +0 -15
package/src/fork.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { fork } from 'node:child_process'
|
|
2
|
-
import { assert, failure } from './assert
|
|
3
|
-
import { runAsync } from './async
|
|
4
|
-
import { Files } from './files
|
|
5
|
-
import { $gry, $p, LogOptions, logOptions } from './log
|
|
6
|
-
import { AbsolutePath,
|
|
7
|
-
import {
|
|
8
|
-
import { Run, RunImpl } from './run.js'
|
|
2
|
+
import { assert, failure } from './assert'
|
|
3
|
+
import { runAsync } from './async'
|
|
4
|
+
import { Files } from './files'
|
|
5
|
+
import { $gry, $p, LogOptions, logOptions } from './log'
|
|
6
|
+
import { AbsolutePath, requireFilename, resolveFile } from './paths'
|
|
7
|
+
import { Plug, PlugResult, Context } from './pipe'
|
|
9
8
|
|
|
10
9
|
/** Fork data, from parent to child process */
|
|
11
10
|
export interface ForkData {
|
|
@@ -17,8 +16,6 @@ export interface ForkData {
|
|
|
17
16
|
taskName: string,
|
|
18
17
|
/** Build file name */
|
|
19
18
|
buildFile: AbsolutePath,
|
|
20
|
-
/** Build directory */
|
|
21
|
-
buildDir: AbsolutePath,
|
|
22
19
|
/** Files directory */
|
|
23
20
|
filesDir: AbsolutePath,
|
|
24
21
|
/** All files to pipe */
|
|
@@ -37,67 +34,30 @@ export interface ForkResult {
|
|
|
37
34
|
filesList?: AbsolutePath[] | undefined,
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
/* ========================================================================== *
|
|
41
|
-
* PIPE INSTALLATION *
|
|
42
|
-
* ========================================================================== */
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Install a _forking_ {@link Plug} in the {@link Pipe}, in other words
|
|
46
|
-
* execute the plug in a separate process.
|
|
47
|
-
*
|
|
48
|
-
* As a contract, if the _last non-null_ parameter of the constructor is an
|
|
49
|
-
* object and contains the key `coverageDir`, the process will be forked with
|
|
50
|
-
* the approptiately resolved `NODE_V8_COVERAGE` environment variable.
|
|
51
|
-
*
|
|
52
|
-
* Also, forking plugs require some special attention:
|
|
53
|
-
*
|
|
54
|
-
* * plug functions are not supported, only classes implementing the
|
|
55
|
-
* {@link Plug} interface can be used with this.
|
|
56
|
-
*
|
|
57
|
-
* * the class itself _MUST_ be exported as the _default_ export for the
|
|
58
|
-
* `scriptFile` specified below. This is to simplify interoperability between
|
|
59
|
-
* CommonJS and ESM modules as we use dynamic `import(...)` statements.
|
|
60
|
-
*/
|
|
61
|
-
export function installForking(
|
|
62
|
-
plugName: PlugName,
|
|
63
|
-
scriptFile: AbsolutePath,
|
|
64
|
-
): void {
|
|
65
|
-
/** Extend out our ForkingPlug below */
|
|
66
|
-
const ctor = class extends ForkingPlug {
|
|
67
|
-
constructor(...args: any[]) {
|
|
68
|
-
super(scriptFile, args)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Install the plug in */
|
|
73
|
-
install(plugName, ctor)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
37
|
/* ========================================================================== *
|
|
77
38
|
* PARENT PROCESS SIDE OF THE FORKING PLUG IMPLEMENTATION *
|
|
78
39
|
* ========================================================================== */
|
|
79
40
|
|
|
80
|
-
export abstract class ForkingPlug implements Plug<
|
|
41
|
+
export abstract class ForkingPlug implements Plug<PlugResult> {
|
|
81
42
|
constructor(
|
|
82
43
|
private readonly _scriptFile: AbsolutePath,
|
|
83
44
|
private readonly _arguments: any[],
|
|
84
45
|
) {}
|
|
85
46
|
|
|
86
|
-
pipe(files: Files,
|
|
47
|
+
pipe(files: Files, context: Context): Promise<PlugResult> {
|
|
87
48
|
const message: ForkData = {
|
|
88
49
|
scriptFile: this._scriptFile,
|
|
89
50
|
constructorArgs: this._arguments,
|
|
90
|
-
taskName:
|
|
91
|
-
buildFile:
|
|
92
|
-
buildDir: run.buildDir,
|
|
51
|
+
taskName: context.taskName,
|
|
52
|
+
buildFile: context.buildFile,
|
|
93
53
|
filesDir: files.directory,
|
|
94
54
|
filesList: [ ...files.absolutePaths() ],
|
|
95
|
-
logOpts: logOptions.fork(
|
|
55
|
+
logOpts: logOptions.fork(context.taskName),
|
|
96
56
|
}
|
|
97
57
|
|
|
98
58
|
/* Get _this_ filename to spawn */
|
|
99
59
|
const script = requireFilename(__fileurl)
|
|
100
|
-
|
|
60
|
+
context.log.debug('About to fork plug from', $p(script))
|
|
101
61
|
|
|
102
62
|
/* Environment variables */
|
|
103
63
|
const env = { ...process.env }
|
|
@@ -107,8 +67,8 @@ export abstract class ForkingPlug implements Plug<Files | undefined> {
|
|
|
107
67
|
if (this._arguments[i] == null) continue // null or undefined... optionals
|
|
108
68
|
if (typeof this._arguments[i] === 'object') {
|
|
109
69
|
if (typeof this._arguments[i].coverageDir === 'string') {
|
|
110
|
-
const dir = env.NODE_V8_COVERAGE =
|
|
111
|
-
|
|
70
|
+
const dir = env.NODE_V8_COVERAGE = context.resolve(this._arguments[i].coverageDir)
|
|
71
|
+
context.log.debug('Forked process will produce coverage in', $p(dir))
|
|
112
72
|
}
|
|
113
73
|
}
|
|
114
74
|
}
|
|
@@ -119,32 +79,32 @@ export abstract class ForkingPlug implements Plug<Files | undefined> {
|
|
|
119
79
|
env,
|
|
120
80
|
})
|
|
121
81
|
|
|
122
|
-
|
|
82
|
+
context.log.info('Running', $p(script), $gry(`(pid=${child.pid})`))
|
|
123
83
|
|
|
124
84
|
/* Return a promise from the child process events */
|
|
125
85
|
let done = false // this will be fixed up in "finally" below
|
|
126
|
-
return new Promise<
|
|
86
|
+
return new Promise<PlugResult>((resolve, reject) => {
|
|
127
87
|
let result: ForkResult | undefined = undefined
|
|
128
88
|
|
|
129
89
|
child.on('error', (error) => {
|
|
130
|
-
|
|
90
|
+
context.log.error('Child process error', error)
|
|
131
91
|
return done || reject(failure())
|
|
132
92
|
})
|
|
133
93
|
|
|
134
94
|
child.on('message', (message: ForkResult) => {
|
|
135
|
-
|
|
95
|
+
context.log.debug('Message from child process', message)
|
|
136
96
|
result = message
|
|
137
97
|
})
|
|
138
98
|
|
|
139
99
|
child.on('exit', (code, signal) => {
|
|
140
100
|
if (signal) {
|
|
141
|
-
|
|
101
|
+
context.log.error(`Child process exited with signal ${signal}`, $gry(`(pid=${child.pid})`))
|
|
142
102
|
return done || reject(failure())
|
|
143
103
|
} else if (code !== 0) {
|
|
144
|
-
|
|
104
|
+
context.log.error(`Child process exited with code ${code}`, $gry(`(pid=${child.pid})`))
|
|
145
105
|
return done || reject(failure())
|
|
146
106
|
} else if (! result) {
|
|
147
|
-
|
|
107
|
+
context.log.error('Child process exited with no result', $gry(`(pid=${child.pid})`))
|
|
148
108
|
return done || reject(failure())
|
|
149
109
|
} else if (result.failed) {
|
|
150
110
|
// definitely logged on the child side
|
|
@@ -153,7 +113,7 @@ export abstract class ForkingPlug implements Plug<Files | undefined> {
|
|
|
153
113
|
|
|
154
114
|
/* We definitely have a successful result! */
|
|
155
115
|
return done || resolve(message.filesDir && message.filesList ?
|
|
156
|
-
|
|
116
|
+
Files.builder(message.filesDir).add(...message.filesList).build() :
|
|
157
117
|
undefined)
|
|
158
118
|
})
|
|
159
119
|
|
|
@@ -161,16 +121,16 @@ export abstract class ForkingPlug implements Plug<Files | undefined> {
|
|
|
161
121
|
try {
|
|
162
122
|
const result = child.send(message, (error) => {
|
|
163
123
|
if (error) {
|
|
164
|
-
|
|
124
|
+
context.log.error('Error sending message to child process (callback failure)', error)
|
|
165
125
|
reject(failure())
|
|
166
126
|
}
|
|
167
127
|
})
|
|
168
128
|
if (! result) {
|
|
169
|
-
|
|
129
|
+
context.log.error('Error sending message to child process (send returned false)')
|
|
170
130
|
reject(failure())
|
|
171
131
|
}
|
|
172
132
|
} catch (error) {
|
|
173
|
-
|
|
133
|
+
context.log.error('Error sending message to child process (exception caught)', error)
|
|
174
134
|
reject(failure())
|
|
175
135
|
}
|
|
176
136
|
}).finally(() => done = true)
|
|
@@ -204,7 +164,6 @@ if ((process.argv[1] === requireFilename(__fileurl)) && (process.send)) {
|
|
|
204
164
|
constructorArgs,
|
|
205
165
|
taskName,
|
|
206
166
|
buildFile,
|
|
207
|
-
buildDir,
|
|
208
167
|
filesDir,
|
|
209
168
|
filesList,
|
|
210
169
|
logOpts,
|
|
@@ -213,12 +172,12 @@ if ((process.argv[1] === requireFilename(__fileurl)) && (process.send)) {
|
|
|
213
172
|
/* Restore logging options first */
|
|
214
173
|
Object.assign(logOptions, logOpts)
|
|
215
174
|
|
|
216
|
-
/* First of all, our
|
|
217
|
-
const
|
|
218
|
-
|
|
175
|
+
/* First of all, our plug context */
|
|
176
|
+
const context = new Context(buildFile, taskName)
|
|
177
|
+
context.log.debug('Message from parent process', message)
|
|
219
178
|
|
|
220
179
|
/* Contextualize this run, and go! */
|
|
221
|
-
const result = runAsync(
|
|
180
|
+
const result = runAsync(context, taskName, async () => {
|
|
222
181
|
/* Check that we have a proper script file name */
|
|
223
182
|
assert(resolveFile(scriptFile), `Script file ${$p(scriptFile)} not found`)
|
|
224
183
|
const script = await import(scriptFile)
|
|
@@ -232,11 +191,11 @@ if ((process.argv[1] === requireFilename(__fileurl)) && (process.send)) {
|
|
|
232
191
|
`Script ${$p(scriptFile)} does not export a default constructor`)
|
|
233
192
|
|
|
234
193
|
/* Create the Plug instance and our Files instance */
|
|
235
|
-
const plug = new Ctor(...constructorArgs) as Plug<
|
|
236
|
-
const files =
|
|
194
|
+
const plug = new Ctor(...constructorArgs) as Plug<PlugResult>
|
|
195
|
+
const files = Files.builder(filesDir).add(...filesList).build()
|
|
237
196
|
|
|
238
197
|
/* Run and return the result */
|
|
239
|
-
return plug.pipe(files,
|
|
198
|
+
return plug.pipe(files, context)
|
|
240
199
|
})
|
|
241
200
|
|
|
242
201
|
/* The result promise generates a message back to the parent process */
|
|
@@ -248,7 +207,7 @@ if ((process.argv[1] === requireFilename(__fileurl)) && (process.send)) {
|
|
|
248
207
|
process.send!(message, (err: Error) => err ? reject(err) : resolve())
|
|
249
208
|
})
|
|
250
209
|
}, (error) => {
|
|
251
|
-
|
|
210
|
+
context.log.error(error)
|
|
252
211
|
return new Promise<void>((resolve, reject) => {
|
|
253
212
|
process.send!({ failed: true }, (err: Error) => err ? reject(err) : resolve())
|
|
254
213
|
})
|
|
@@ -256,10 +215,10 @@ if ((process.argv[1] === requireFilename(__fileurl)) && (process.send)) {
|
|
|
256
215
|
|
|
257
216
|
/* The promise generated by `process.send()` simply triggers process exit */
|
|
258
217
|
promise.then(() => {
|
|
259
|
-
|
|
218
|
+
context.log.debug('Forked plug exiting')
|
|
260
219
|
process.exit(0)
|
|
261
220
|
}, (error) => {
|
|
262
|
-
|
|
221
|
+
context.log.error('Error sending message back to parent process', error)
|
|
263
222
|
process.exit(1)
|
|
264
223
|
})
|
|
265
224
|
})
|
package/src/helpers.ts
CHANGED
|
@@ -1,133 +1,121 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from './
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import { rm } from './utils/asyncfs.js'
|
|
16
|
-
import { ParseOptions } from './utils/options.js'
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Recursively remove the specified directory _**(use with care)**_.
|
|
20
|
-
*/
|
|
21
|
-
export async function rmrf(directory: string): Promise<void> {
|
|
22
|
-
const run = currentRun()
|
|
23
|
-
assert(run, 'Unable to find files outside a running task')
|
|
24
|
-
const dir = run.resolve(directory)
|
|
25
|
-
|
|
26
|
-
assert(dir !== getCurrentWorkingDirectory(),
|
|
27
|
-
`Cowardly refusing to wipe current working directory ${$p(dir)}`)
|
|
28
|
-
|
|
29
|
-
assert(dir !== run.buildDir,
|
|
30
|
-
`Cowardly refusing to wipe build file directory ${$p(dir)}`)
|
|
1
|
+
import { assert } from './assert'
|
|
2
|
+
import { requireContext } from './async'
|
|
3
|
+
import { Files } from './files'
|
|
4
|
+
import { $p, log } from './log'
|
|
5
|
+
import { AbsolutePath, commonPath, getCurrentWorkingDirectory, resolveDirectory, resolveFile } from './paths'
|
|
6
|
+
import { Context, Pipe, Plug, PlugFunction, PlugResult } from './pipe'
|
|
7
|
+
import { rm } from './utils/asyncfs'
|
|
8
|
+
import { ParseOptions, parseOptions } from './utils/options'
|
|
9
|
+
import { walk, WalkOptions } from './utils/walk'
|
|
10
|
+
|
|
11
|
+
class PipeImpl extends Pipe implements Pipe {
|
|
12
|
+
constructor(private readonly _start: (context: Context) => Promise<Files>) {
|
|
13
|
+
super()
|
|
14
|
+
}
|
|
31
15
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
16
|
+
plug(plug: Plug<Files>): Pipe
|
|
17
|
+
plug(plug: PlugFunction<Files>): Pipe
|
|
18
|
+
plug(plug: Plug<void | undefined>): Promise<undefined>
|
|
19
|
+
plug(plug: PlugFunction<void | undefined>): Promise<undefined>
|
|
20
|
+
plug(arg: Plug<PlugResult> | PlugFunction<PlugResult>): Pipe | Promise<undefined> {
|
|
21
|
+
const plug = typeof arg === 'function' ? { pipe: arg } : arg
|
|
22
|
+
|
|
23
|
+
const parent = this
|
|
24
|
+
return new PipeImpl(async (context: Context): Promise<Files> => {
|
|
25
|
+
const files = await parent._start(context)
|
|
26
|
+
const files2 = await plug.pipe(files, context)
|
|
27
|
+
assert(files2, 'Unable to extend pipe (part tres)')
|
|
28
|
+
return files2
|
|
29
|
+
})
|
|
35
30
|
}
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
async run(): Promise<Files> {
|
|
33
|
+
return this._start(requireContext())
|
|
34
|
+
}
|
|
39
35
|
}
|
|
40
36
|
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
*/
|
|
46
|
-
export function setLogLevel(level: LogLevelString): void {
|
|
47
|
-
const run = currentRun()
|
|
48
|
-
assert(run, 'Unable to find files outside a running task')
|
|
49
|
-
return run.setLogLevel(level)
|
|
37
|
+
/** The {@link FindOptions} interface defines the options for finding files. */
|
|
38
|
+
export interface FindOptions extends WalkOptions {
|
|
39
|
+
/** The directory where to start looking for files. */
|
|
40
|
+
directory?: string
|
|
50
41
|
}
|
|
51
42
|
|
|
52
|
-
/**
|
|
53
|
-
* Resolve a path into an {@link AbsolutePath}.
|
|
54
|
-
*
|
|
55
|
-
* If the path starts with `@...` it is considered to be relative to the
|
|
56
|
-
* _directory containing the build file where the task was defined_, otherwise
|
|
57
|
-
* it will be relative to the {@link process.cwd | current working directory}.
|
|
58
|
-
*/
|
|
59
|
-
export function resolve(...paths: string[]): AbsolutePath {
|
|
60
|
-
const run = currentRun()
|
|
61
|
-
assert(run, 'Unable to find files outside a running task')
|
|
62
|
-
return run.resolve(...paths)
|
|
63
|
-
}
|
|
64
43
|
|
|
44
|
+
export function find(glob: string): Pipe
|
|
45
|
+
export function find(glob: string, ...globs: string[]): Pipe
|
|
46
|
+
export function find(glob: string, options: FindOptions): Pipe
|
|
47
|
+
export function find(glob: string, ...extra: [...globs: string[], options: FindOptions]): Pipe
|
|
65
48
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return
|
|
80
|
-
}
|
|
49
|
+
export function find(...args: ParseOptions<FindOptions>): Pipe {
|
|
50
|
+
const { params: globs, options } = parseOptions(args, {})
|
|
51
|
+
|
|
52
|
+
return new PipeImpl(async (context: Context): Promise<Files> => {
|
|
53
|
+
const directory = options.directory ?
|
|
54
|
+
context.resolve(options.directory) :
|
|
55
|
+
getCurrentWorkingDirectory()
|
|
56
|
+
|
|
57
|
+
const builder = Files.builder(directory)
|
|
58
|
+
for await (const file of walk(directory, globs, options)) {
|
|
59
|
+
builder.add(file)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return builder.build()
|
|
63
|
+
})
|
|
81
64
|
}
|
|
82
65
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
assert(run, 'Unable to create files builder outside a running task')
|
|
66
|
+
export function merge(...pipes: Pipe[]): Pipe {
|
|
67
|
+
return new PipeImpl(async (): Promise<Files> => {
|
|
68
|
+
if (pipes.length === 0) return Files.builder(getCurrentWorkingDirectory()).build()
|
|
69
|
+
|
|
70
|
+
const results: Files[] = []
|
|
89
71
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
72
|
+
for (const pipe of pipes) {
|
|
73
|
+
const result = await pipe.run()
|
|
74
|
+
assert(result, 'Pipe did not return a Files result')
|
|
75
|
+
results.push(result)
|
|
76
|
+
}
|
|
93
77
|
|
|
94
|
-
|
|
95
|
-
const instances = await Promise.all(args)
|
|
96
|
-
const [ first, ...others ] = instances
|
|
78
|
+
const [ first, ...others ] = results
|
|
97
79
|
|
|
98
80
|
const firstDir = first.directory
|
|
99
81
|
const otherDirs = others.map((f) => f.directory)
|
|
100
82
|
|
|
101
83
|
const directory = commonPath(firstDir, ...otherDirs)
|
|
102
84
|
|
|
103
|
-
return
|
|
85
|
+
return Files.builder(directory).merge(first, ...others).build()
|
|
104
86
|
})
|
|
105
|
-
|
|
106
|
-
return run.pipe(promise)
|
|
107
87
|
}
|
|
108
88
|
|
|
109
89
|
/**
|
|
110
|
-
*
|
|
90
|
+
* Recursively remove the specified directory _**(use with care)**_.
|
|
111
91
|
*/
|
|
112
|
-
export function
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
return run.find(glob, ...args)
|
|
116
|
-
}
|
|
92
|
+
export async function rmrf(directory: string): Promise<void> {
|
|
93
|
+
const context = requireContext()
|
|
94
|
+
const dir = context.resolve(directory)
|
|
117
95
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
assert(
|
|
122
|
-
|
|
96
|
+
assert(dir !== getCurrentWorkingDirectory(),
|
|
97
|
+
`Cowardly refusing to wipe current working directory ${$p(dir)}`)
|
|
98
|
+
|
|
99
|
+
assert(dir !== context.resolve('@'),
|
|
100
|
+
`Cowardly refusing to wipe build file directory ${$p(dir)}`)
|
|
101
|
+
|
|
102
|
+
if (! resolveDirectory(dir)) {
|
|
103
|
+
log.info('Directory', $p(dir), 'not found')
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
log.notice('Removing directory', $p(dir), 'recursively')
|
|
108
|
+
await rm(dir, { recursive: true })
|
|
123
109
|
}
|
|
124
110
|
|
|
125
111
|
/** Return an absolute path of the file if it exist on disk */
|
|
126
|
-
export function isFile(...paths: string[]): AbsolutePath | undefined {
|
|
127
|
-
|
|
112
|
+
export function isFile(...paths: [ string, ...string[] ]): AbsolutePath | undefined {
|
|
113
|
+
const path = requireContext().resolve(...paths)
|
|
114
|
+
return resolveFile(path)
|
|
128
115
|
}
|
|
129
116
|
|
|
130
117
|
/** Return an absolute path of the file if it exist on disk */
|
|
131
|
-
export function isDirectory(...paths: string[]): AbsolutePath | undefined {
|
|
132
|
-
|
|
118
|
+
export function isDirectory(...paths: [ string, ...string[] ]): AbsolutePath | undefined {
|
|
119
|
+
const path = requireContext().resolve(...paths)
|
|
120
|
+
return resolveDirectory(path)
|
|
133
121
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
/// <reference path="../extra/webassembly.d.ts" />
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export * from './plugs.js'
|
|
7
|
-
export * from './log.js'
|
|
8
|
-
export * from './helpers.js'
|
|
3
|
+
export type { AbsolutePath } from './paths'
|
|
4
|
+
export type { Files, FilesBuilder } from './files'
|
|
5
|
+
export type { Pipe } from './pipe'
|
|
9
6
|
|
|
10
|
-
//
|
|
11
|
-
export
|
|
12
|
-
export
|
|
13
|
-
export
|
|
7
|
+
// Our minimal exports
|
|
8
|
+
export * from './assert'
|
|
9
|
+
export * from './build'
|
|
10
|
+
export * from './helpers'
|
|
11
|
+
export * from './log'
|
|
14
12
|
|
|
15
13
|
// PlugJS types
|
|
16
|
-
export
|
|
17
|
-
export
|
|
18
|
-
export type { FindOptions, Run } from './run.js'
|
|
19
|
-
export type { Pipe, Plug, PlugFunction } from './pipe.js'
|
|
20
|
-
export type { Task } from './task.js'
|
|
14
|
+
export * from './plugs'
|
|
15
|
+
export * from './types'
|
package/src/log/colors.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { sep } from 'node:path'
|
|
2
|
-
import { AbsolutePath, getCurrentWorkingDirectory, resolveRelativeChildPath } from '../paths
|
|
3
|
-
import { logOptions } from './options
|
|
2
|
+
import { AbsolutePath, getCurrentWorkingDirectory, resolveRelativeChildPath } from '../paths'
|
|
3
|
+
import { logOptions } from './options'
|
|
4
4
|
|
|
5
5
|
/* ========================================================================== */
|
|
6
6
|
|
|
@@ -49,7 +49,7 @@ export function $t(task: string): string {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/** Colorize milliseconds. */
|
|
52
|
-
export function $ms(millis: number): string {
|
|
52
|
+
export function $ms(millis: number, note?: string): string {
|
|
53
53
|
let string: string
|
|
54
54
|
if (millis >= 60000) {
|
|
55
55
|
// One minute or more: style is Xm Ys
|
|
@@ -70,6 +70,7 @@ export function $ms(millis: number): string {
|
|
|
70
70
|
// Milliseconds: style is 123ms
|
|
71
71
|
string = `${millis}ms`
|
|
72
72
|
}
|
|
73
|
+
if (note) string = `${note} ${string}`
|
|
73
74
|
return _colors ? `${gry}[${string}]${rst}` : `[${string}]`
|
|
74
75
|
}
|
|
75
76
|
|
package/src/log/emit.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { formatWithOptions } from 'node:util'
|
|
2
|
-
import { $blu, $grn, $gry, $red, $t, $ylw } from './colors
|
|
3
|
-
import { DEBUG, INFO, LogLevel, NOTICE, TRACE, WARN } from './levels
|
|
4
|
-
import { logOptions } from './options
|
|
5
|
-
import { zapSpinner } from './spinner
|
|
2
|
+
import { $blu, $grn, $gry, $red, $t, $ylw } from './colors'
|
|
3
|
+
import { DEBUG, INFO, LogLevel, NOTICE, TRACE, WARN } from './levels'
|
|
4
|
+
import { logOptions } from './options'
|
|
5
|
+
import { zapSpinner } from './spinner'
|
|
6
6
|
|
|
7
7
|
/* ========================================================================== */
|
|
8
8
|
|
package/src/log/logger.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { isBuildError, isBuildFailure } from '../assert
|
|
2
|
-
import { emitColor, emitPlain, LogEmitter } from './emit
|
|
3
|
-
import { DEBUG, ERROR, INFO, LogLevel, NOTICE, TRACE, WARN } from './levels
|
|
4
|
-
import { logOptions } from './options
|
|
1
|
+
import { isBuildError, isBuildFailure } from '../assert'
|
|
2
|
+
import { emitColor, emitPlain, LogEmitter } from './emit'
|
|
3
|
+
import { DEBUG, ERROR, INFO, LogLevel, NOTICE, TRACE, WARN } from './levels'
|
|
4
|
+
import { logOptions } from './options'
|
|
5
|
+
import { Report, ReportImpl } from './report'
|
|
5
6
|
|
|
6
7
|
/* ========================================================================== */
|
|
7
8
|
|
|
@@ -48,6 +49,8 @@ export interface Logger extends Log {
|
|
|
48
49
|
leave(): this
|
|
49
50
|
/** Leave a sub-level of logging, decreasing indent */
|
|
50
51
|
leave(level: LogLevel, message: string): this
|
|
52
|
+
/** Create a {@link Report} associated with this instance */
|
|
53
|
+
report(title: string): Report
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
/** Return a {@link Logger} associated with the specified task name. */
|
|
@@ -149,6 +152,7 @@ class LoggerImpl implements Logger {
|
|
|
149
152
|
const [ level, message ] = args
|
|
150
153
|
this._stack.push({ level, message, indent: this._indent })
|
|
151
154
|
}
|
|
155
|
+
|
|
152
156
|
this._indent ++
|
|
153
157
|
return this
|
|
154
158
|
}
|
|
@@ -168,4 +172,8 @@ class LoggerImpl implements Logger {
|
|
|
168
172
|
|
|
169
173
|
return this
|
|
170
174
|
}
|
|
175
|
+
|
|
176
|
+
report(title: string): Report {
|
|
177
|
+
return new ReportImpl(title, this._task, this._emitter)
|
|
178
|
+
}
|
|
171
179
|
}
|
package/src/log/options.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events'
|
|
2
2
|
import { Writable } from 'node:stream'
|
|
3
3
|
import { InspectOptions } from 'node:util'
|
|
4
|
-
import { getLevelNumber, LogLevel, LogLevelString, NOTICE } from './levels
|
|
4
|
+
import { getLevelNumber, LogLevel, LogLevelString, NOTICE } from './levels'
|
|
5
5
|
|
|
6
6
|
/* ========================================================================== */
|
|
7
7
|
|
package/src/log/report.ts
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import { fail, failure } from '../assert
|
|
2
|
-
import { AbsolutePath } from '../paths
|
|
3
|
-
import { readFile } from '../utils/asyncfs
|
|
4
|
-
import { $blu, $cyn, $gry, $red, $und, $wht, $ylw } from './colors
|
|
5
|
-
import {
|
|
6
|
-
import { ERROR, LogLevels, NOTICE, WARN } from './levels
|
|
7
|
-
import { logOptions } from './options
|
|
1
|
+
import { fail, failure } from '../assert'
|
|
2
|
+
import { AbsolutePath } from '../paths'
|
|
3
|
+
import { readFile } from '../utils/asyncfs'
|
|
4
|
+
import { $blu, $cyn, $gry, $red, $und, $wht, $ylw } from './colors'
|
|
5
|
+
import { LogEmitter } from './emit'
|
|
6
|
+
import { ERROR, LogLevels, NOTICE, WARN } from './levels'
|
|
7
|
+
import { logOptions } from './options'
|
|
8
8
|
|
|
9
9
|
/* ========================================================================== */
|
|
10
10
|
|
|
11
|
-
/* Track changes for colors */
|
|
12
|
-
let _colors = logOptions.colors
|
|
13
|
-
logOptions.on('changed', ({ colors }) => {
|
|
14
|
-
_colors = colors
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
/* ========================================================================== *
|
|
18
|
-
|
|
19
11
|
/** Levels used in a {@link Report} */
|
|
20
12
|
export type ReportLevel = LogLevels['NOTICE' | 'WARN' | 'ERROR']
|
|
21
13
|
|
|
@@ -91,12 +83,6 @@ export interface Report {
|
|
|
91
83
|
done(showSources?: boolean | undefined): void
|
|
92
84
|
}
|
|
93
85
|
|
|
94
|
-
/** Create a new {@link Report} with the given title */
|
|
95
|
-
export function createReport(title: string, taskName: string): Report {
|
|
96
|
-
const emitter = _colors ? emitColor : emitPlain
|
|
97
|
-
return new ReportImpl(title, taskName, emitter)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
86
|
/* ========================================================================== *
|
|
101
87
|
* REPORT IMPLEMENTATION *
|
|
102
88
|
* ========================================================================== */
|
|
@@ -118,7 +104,7 @@ interface ReportInternalAnnotation {
|
|
|
118
104
|
readonly note: string
|
|
119
105
|
}
|
|
120
106
|
|
|
121
|
-
class ReportImpl implements Report {
|
|
107
|
+
export class ReportImpl implements Report {
|
|
122
108
|
private readonly _sources = new Map<AbsolutePath, string[]>()
|
|
123
109
|
private readonly _annotations = new Map<AbsolutePath, ReportInternalAnnotation>()
|
|
124
110
|
private readonly _records = new Map<AbsolutePath | Null, Set<ReportInternalRecord>>()
|
|
@@ -354,8 +340,8 @@ class ReportImpl implements Report {
|
|
|
354
340
|
if (file && file !== nul && annotation) {
|
|
355
341
|
const { level, note } = annotation
|
|
356
342
|
const $col = level === NOTICE ? $blu : level === WARN ? $ylw : $red
|
|
357
|
-
const ann = `${$gry('[')}${$col(note
|
|
358
|
-
const pad = ''.padStart(fPad - file.length
|
|
343
|
+
const ann = `${$gry('[')}${$col(note)}${$gry(']')}`
|
|
344
|
+
const pad = ''.padStart((fPad + aPad) - (file.length + note.length))
|
|
359
345
|
|
|
360
346
|
this._emitter({ ...options, level }, [ $wht($und(file)), pad, ann ])
|
|
361
347
|
} else if (file !== nul ) {
|
package/src/log/spinner.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { runningTasks } from '../async
|
|
2
|
-
import { $cyn, $gry, $t } from './colors
|
|
3
|
-
import { logOptions } from './options
|
|
1
|
+
import { runningTasks } from '../async'
|
|
2
|
+
import { $cyn, $gry, $t } from './colors'
|
|
3
|
+
import { logOptions } from './options'
|
|
4
4
|
|
|
5
5
|
/* ========================================================================== */
|
|
6
6
|
|