@plugjs/plug 0.0.14 → 0.0.16

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.
Files changed (212) hide show
  1. package/dist/async.cjs +20 -19
  2. package/dist/async.cjs.map +1 -1
  3. package/dist/async.d.ts +9 -9
  4. package/dist/async.mjs +18 -17
  5. package/dist/async.mjs.map +1 -1
  6. package/dist/build.cjs +113 -110
  7. package/dist/build.cjs.map +2 -2
  8. package/dist/build.d.ts +14 -56
  9. package/dist/build.mjs +114 -111
  10. package/dist/build.mjs.map +2 -2
  11. package/dist/files.cjs +2 -16
  12. package/dist/files.cjs.map +1 -1
  13. package/dist/files.d.ts +3 -10
  14. package/dist/files.mjs +3 -17
  15. package/dist/files.mjs.map +1 -1
  16. package/dist/fork.cjs +28 -40
  17. package/dist/fork.cjs.map +1 -1
  18. package/dist/fork.d.ts +6 -27
  19. package/dist/fork.mjs +29 -40
  20. package/dist/fork.mjs.map +1 -1
  21. package/dist/helpers.cjs +27 -61
  22. package/dist/helpers.cjs.map +2 -2
  23. package/dist/helpers.d.ts +29 -31
  24. package/dist/helpers.mjs +27 -62
  25. package/dist/helpers.mjs.map +2 -2
  26. package/dist/index.cjs +15 -2
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.ts +9 -13
  29. package/dist/index.mjs +7 -2
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/log/colors.cjs +3 -1
  32. package/dist/log/colors.cjs.map +1 -1
  33. package/dist/log/colors.d.ts +2 -2
  34. package/dist/log/colors.mjs +3 -1
  35. package/dist/log/colors.mjs.map +1 -1
  36. package/dist/log/emit.d.ts +1 -1
  37. package/dist/log/logger.cjs +4 -0
  38. package/dist/log/logger.cjs.map +1 -1
  39. package/dist/log/logger.d.ts +4 -1
  40. package/dist/log/logger.mjs +4 -0
  41. package/dist/log/logger.mjs.map +1 -1
  42. package/dist/log/options.d.ts +1 -1
  43. package/dist/log/report.cjs +2 -11
  44. package/dist/log/report.cjs.map +1 -1
  45. package/dist/log/report.d.ts +36 -4
  46. package/dist/log/report.mjs +1 -10
  47. package/dist/log/report.mjs.map +1 -1
  48. package/dist/log.cjs +1 -1
  49. package/dist/log.cjs.map +1 -1
  50. package/dist/log.d.ts +6 -6
  51. package/dist/log.mjs +2 -2
  52. package/dist/log.mjs.map +1 -1
  53. package/dist/pipe.cjs +69 -26
  54. package/dist/pipe.cjs.map +1 -1
  55. package/dist/pipe.d.ts +178 -119
  56. package/dist/pipe.mjs +71 -24
  57. package/dist/pipe.mjs.map +1 -1
  58. package/dist/plugs/copy.cjs +15 -25
  59. package/dist/plugs/copy.cjs.map +2 -2
  60. package/dist/plugs/copy.d.ts +14 -13
  61. package/dist/plugs/copy.mjs +15 -17
  62. package/dist/plugs/copy.mjs.map +2 -2
  63. package/dist/plugs/coverage/analysis.d.ts +2 -2
  64. package/dist/plugs/coverage/report.cjs +1 -1
  65. package/dist/plugs/coverage/report.cjs.map +1 -1
  66. package/dist/plugs/coverage/report.d.ts +3 -3
  67. package/dist/plugs/coverage/report.mjs +1 -1
  68. package/dist/plugs/coverage/report.mjs.map +1 -1
  69. package/dist/plugs/coverage.cjs +20 -26
  70. package/dist/plugs/coverage.cjs.map +1 -1
  71. package/dist/plugs/coverage.d.ts +33 -30
  72. package/dist/plugs/coverage.mjs +21 -19
  73. package/dist/plugs/coverage.mjs.map +1 -1
  74. package/dist/plugs/debug.cjs +12 -36
  75. package/dist/plugs/debug.cjs.map +1 -1
  76. package/dist/plugs/debug.d.ts +4 -11
  77. package/dist/plugs/debug.mjs +30 -21
  78. package/dist/plugs/debug.mjs.map +1 -1
  79. package/dist/plugs/esbuild/fix-extensions.mjs +1 -1
  80. package/dist/plugs/esbuild/fix-extensions.mjs.map +1 -1
  81. package/dist/plugs/esbuild.cjs +14 -25
  82. package/dist/plugs/esbuild.cjs.map +1 -1
  83. package/dist/plugs/esbuild.d.ts +11 -16
  84. package/dist/plugs/esbuild.mjs +14 -17
  85. package/dist/plugs/esbuild.mjs.map +1 -1
  86. package/dist/plugs/eslint/runner.cjs +5 -6
  87. package/dist/plugs/eslint/runner.cjs.map +1 -1
  88. package/dist/plugs/eslint/runner.d.ts +6 -20
  89. package/dist/plugs/eslint/runner.mjs +6 -7
  90. package/dist/plugs/eslint/runner.mjs.map +1 -1
  91. package/dist/{task.cjs → plugs/eslint.cjs} +7 -24
  92. package/dist/plugs/eslint.cjs.map +6 -0
  93. package/dist/plugs/eslint.d.ts +34 -0
  94. package/dist/plugs/eslint.mjs +5 -0
  95. package/dist/plugs/eslint.mjs.map +6 -0
  96. package/dist/plugs/exec.cjs +20 -24
  97. package/dist/plugs/exec.cjs.map +1 -1
  98. package/dist/plugs/exec.d.ts +53 -53
  99. package/dist/plugs/exec.mjs +20 -23
  100. package/dist/plugs/exec.mjs.map +1 -1
  101. package/dist/plugs/filter.cjs +9 -19
  102. package/dist/plugs/filter.cjs.map +1 -1
  103. package/dist/plugs/filter.d.ts +21 -15
  104. package/dist/plugs/filter.mjs +10 -12
  105. package/dist/plugs/filter.mjs.map +1 -1
  106. package/dist/plugs/mocha/reporter.cjs +12 -6
  107. package/dist/plugs/mocha/reporter.cjs.map +1 -1
  108. package/dist/plugs/mocha/reporter.d.ts +0 -2
  109. package/dist/plugs/mocha/reporter.mjs +11 -4
  110. package/dist/plugs/mocha/reporter.mjs.map +1 -1
  111. package/dist/plugs/mocha/runner.cjs +4 -5
  112. package/dist/plugs/mocha/runner.cjs.map +1 -1
  113. package/dist/plugs/mocha/runner.d.ts +5 -31
  114. package/dist/plugs/mocha/runner.mjs +5 -6
  115. package/dist/plugs/mocha/runner.mjs.map +1 -1
  116. package/dist/plugs/mocha.cjs +22 -0
  117. package/dist/plugs/mocha.cjs.map +6 -0
  118. package/dist/plugs/mocha.d.ts +35 -0
  119. package/dist/plugs/mocha.mjs +5 -0
  120. package/dist/plugs/mocha.mjs.map +6 -0
  121. package/dist/plugs/rmf.cjs +4 -32
  122. package/dist/plugs/rmf.cjs.map +1 -1
  123. package/dist/plugs/rmf.d.ts +8 -12
  124. package/dist/plugs/rmf.mjs +25 -20
  125. package/dist/plugs/rmf.mjs.map +1 -1
  126. package/dist/plugs/tsc/compiler.d.ts +1 -1
  127. package/dist/plugs/tsc/options.d.ts +1 -1
  128. package/dist/plugs/tsc/report.d.ts +2 -2
  129. package/dist/plugs/tsc/runner.cjs +12 -11
  130. package/dist/plugs/tsc/runner.cjs.map +1 -1
  131. package/dist/plugs/tsc/runner.d.ts +4 -9
  132. package/dist/plugs/tsc/runner.mjs +12 -11
  133. package/dist/plugs/tsc/runner.mjs.map +1 -1
  134. package/dist/plugs/tsc.cjs +7 -0
  135. package/dist/plugs/tsc.cjs.map +6 -0
  136. package/dist/plugs/tsc.d.ts +36 -0
  137. package/dist/plugs/tsc.mjs +15 -0
  138. package/dist/plugs/tsc.mjs.map +6 -0
  139. package/dist/plugs.cjs +3 -5
  140. package/dist/plugs.cjs.map +1 -1
  141. package/dist/plugs.d.ts +10 -17
  142. package/dist/plugs.mjs +3 -5
  143. package/dist/plugs.mjs.map +1 -1
  144. package/dist/types.cjs +19 -0
  145. package/dist/types.cjs.map +6 -0
  146. package/dist/types.d.ts +71 -0
  147. package/dist/types.mjs +1 -0
  148. package/dist/types.mjs.map +6 -0
  149. package/dist/utils/caller.cjs +8 -11
  150. package/dist/utils/caller.cjs.map +2 -2
  151. package/dist/utils/caller.d.ts +2 -7
  152. package/dist/utils/caller.mjs +8 -11
  153. package/dist/utils/caller.mjs.map +2 -2
  154. package/dist/utils/options.cjs +4 -6
  155. package/dist/utils/options.cjs.map +1 -1
  156. package/dist/utils/options.d.ts +16 -15
  157. package/dist/utils/options.mjs +4 -6
  158. package/dist/utils/options.mjs.map +1 -1
  159. package/dist/utils/walk.d.ts +2 -2
  160. package/extra/cli.mjs +31 -20
  161. package/extra/ts-loader.mjs +6 -5
  162. package/package.json +8 -9
  163. package/src/async.ts +27 -19
  164. package/src/files.ts +6 -30
  165. package/src/fork.ts +35 -76
  166. package/src/helpers.ts +66 -99
  167. package/src/index.ts +10 -15
  168. package/src/log/colors.ts +4 -3
  169. package/src/log/emit.ts +4 -4
  170. package/src/log/logger.ts +12 -4
  171. package/src/log/options.ts +1 -1
  172. package/src/log/report.ts +8 -22
  173. package/src/log/spinner.ts +3 -3
  174. package/src/log.ts +9 -9
  175. package/src/paths.ts +1 -1
  176. package/src/pipe.ts +255 -170
  177. package/src/plugs/copy.ts +40 -31
  178. package/src/plugs/coverage/analysis.ts +4 -4
  179. package/src/plugs/coverage/report.ts +6 -5
  180. package/src/plugs/coverage.ts +64 -53
  181. package/src/plugs/debug.ts +28 -26
  182. package/src/plugs/esbuild/fix-extensions.ts +2 -2
  183. package/src/plugs/esbuild.ts +42 -46
  184. package/src/plugs/eslint/runner.ts +16 -31
  185. package/src/plugs/eslint.ts +42 -0
  186. package/src/plugs/exec.ts +93 -82
  187. package/src/plugs/filter.ts +42 -27
  188. package/src/plugs/mocha/reporter.ts +10 -5
  189. package/src/plugs/mocha/runner.ts +12 -38
  190. package/src/plugs/mocha.ts +41 -0
  191. package/src/plugs/rmf.ts +21 -25
  192. package/src/plugs/tsc/compiler.ts +1 -1
  193. package/src/plugs/tsc/options.ts +2 -2
  194. package/src/plugs/tsc/report.ts +2 -2
  195. package/src/plugs/tsc/runner.ts +24 -30
  196. package/src/plugs/tsc.ts +45 -0
  197. package/src/plugs.ts +10 -25
  198. package/src/types.ts +116 -0
  199. package/src/utils/caller.ts +11 -22
  200. package/src/utils/options.ts +49 -17
  201. package/src/utils/walk.ts +4 -4
  202. package/dist/run.cjs +0 -90
  203. package/dist/run.cjs.map +0 -6
  204. package/dist/run.d.ts +0 -89
  205. package/dist/run.mjs +0 -65
  206. package/dist/run.mjs.map +0 -6
  207. package/dist/task.cjs.map +0 -6
  208. package/dist/task.d.ts +0 -15
  209. package/dist/task.mjs +0 -14
  210. package/dist/task.mjs.map +0 -6
  211. package/src/run.ts +0 -159
  212. package/src/task.ts +0 -26
package/src/plugs/exec.ts CHANGED
@@ -2,14 +2,13 @@ import path from 'node:path'
2
2
  import reaadline from 'node:readline'
3
3
 
4
4
  import { spawn, SpawnOptions } from 'node:child_process'
5
- import { assert } from '../assert.js'
6
- import { currentRun } from '../async.js'
7
- import { Files } from '../files.js'
8
- import { $p, logOptions } from '../log.js'
9
- import { AbsolutePath, getCurrentWorkingDirectory, resolveDirectory } from '../paths.js'
10
- import { install, Plug } from '../pipe.js'
11
- import { Run } from '../run.js'
12
- import { parseOptions, ParseOptions } from '../utils/options.js'
5
+ import { assert } from '../assert'
6
+ import { Files } from '../files'
7
+ import { $p, logOptions } from '../log'
8
+ import { AbsolutePath, getCurrentWorkingDirectory, resolveDirectory } from '../paths'
9
+ import { Context, install, PipeParameters, Plug } from '../pipe'
10
+ import { parseOptions } from '../utils/options'
11
+ import { requireContext } from '../async'
13
12
 
14
13
  /** Options for executing scripts */
15
14
  export interface ExecOptions {
@@ -31,40 +30,75 @@ export interface ExecOptions {
31
30
  relativePaths?: boolean
32
31
  }
33
32
 
34
- /**
35
- * Execute a shell command, adding to its _arguments_ the list of files from
36
- * the current pipe (much like `xargs` does on Unix systems).
37
- *
38
- * This {@link Plug} returns the same {@link Files} it was given, so that
39
- * executing a shell command doesn't interrupt a {@link Pipe}.
40
- *
41
- * For example:
42
- *
43
- * ```
44
- * import { find, exec } from '@plugjs/plugjs'
45
- *
46
- * export default build({
47
- * async runme() {
48
- * find('*.ts', { directory: 'src' })
49
- * .plug(new Exec('chmod', '755' }))
50
- * .plug(new Exec('chown root:root', { shell: true }))
51
- * },
52
- * })
53
- * ```
54
- */
55
- export class Exec implements Plug<Files> {
33
+ declare module '../pipe' {
34
+ export interface Pipe {
35
+ /**
36
+ * Execute a shell command, adding to its _arguments_ the list of files
37
+ * from the current pipe (much like `xargs` does on Unix systems).
38
+ *
39
+ * For example:
40
+ *
41
+ * ```
42
+ * import { build } from '@plugjs/plugjs'
43
+ *
44
+ * export default build({
45
+ * runme() {
46
+ * this.find('*.ts', { directory: 'src' })
47
+ * .exec('chmod', '755' })
48
+ * .exec('chown root:root', { shell: true })
49
+ * },
50
+ * })
51
+ * ```
52
+ *
53
+ * @param cmd The command to execute
54
+ * @param args Any additional argument for the command to execute
55
+ */
56
+ exec(cmd: string, ...args: string[]): Pipe
57
+
58
+ /**
59
+ * Execute a shell command, adding to its _arguments_ the list of files
60
+ * from the current pipe (much like `xargs` does on Unix systems).
61
+ *
62
+ * For example:
63
+ *
64
+ * ```
65
+ * import { build } from '@plugjs/plugjs'
66
+ *
67
+ * export default build({
68
+ * runme() {
69
+ * this.find('*.ts', { directory: 'src' })
70
+ * .exec('chmod', '755' })
71
+ * .exec('chown root:root', { shell: true })
72
+ * },
73
+ * })
74
+ * ```
75
+ *
76
+ * @param cmd The command to execute
77
+ * @param args Any additional argument for the command to execute
78
+ * @param options Extra {@link ExecOptions | options} for process execution
79
+ */
80
+ exec(cmd: string, ...extra: [ ...args: string[], options: ExecOptions ]): Pipe
81
+ }
82
+ }
83
+
84
+ /* ========================================================================== *
85
+ * INSTALLATION / IMPLEMENTATION *
86
+ * ========================================================================== */
87
+
88
+ install('exec', class Exec implements Plug<Files> {
56
89
  private readonly _cmd: string
57
90
  private readonly _args: readonly string[]
58
91
  private readonly _options: ExecOptions
59
92
 
60
- constructor(cmd: string, ...args: ParseOptions<ExecOptions>) {
93
+ constructor(...args: PipeParameters<'exec'>) {
61
94
  const { params, options } = parseOptions(args, {})
62
- this._cmd = cmd
63
- this._args = params
95
+ const [ _cmd, ..._args ] = params
96
+ this._cmd = _cmd
97
+ this._args = _args
64
98
  this._options = options
65
99
  }
66
100
 
67
- async pipe(files: Files, run: Run): Promise<Files> {
101
+ async pipe(files: Files, context: Context): Promise<Files> {
68
102
  const { relativePaths = true, ...options } = this._options
69
103
 
70
104
  if (! options.cwd) options.cwd = files.directory
@@ -76,12 +110,12 @@ export class Exec implements Plug<Files> {
76
110
  if (options.shell) params.forEach((s, i, a) => a[i] = JSON.stringify(s))
77
111
 
78
112
  // Run our child
79
- await spawnChild(this._cmd, [ ...this._args, ...params ], options, run)
113
+ await spawnChild(this._cmd, [ ...this._args, ...params ], options, context)
80
114
 
81
115
  // Return our files
82
116
  return files
83
117
  }
84
- }
118
+ })
85
119
 
86
120
  /**
87
121
  * Execute a command and await for its result from within a task.
@@ -94,50 +128,27 @@ export class Exec implements Plug<Files> {
94
128
  * export default build({
95
129
  * async runme() {
96
130
  * await exec('ls', '-la', '/')
131
+ * // or similarly letting the shell interpret the command
132
+ * await exec('ls -la /', { shell: true })
97
133
  * },
98
134
  * })
99
135
  * ```
136
+ *
137
+ * @param cmd The command to execute
138
+ * @param args Any additional argument for the command to execute
139
+ * @param options Extra {@link ExecOptions | options} for process execution
100
140
  */
101
-
102
- export function exec(cmd: string, ...args: ParseOptions<ExecOptions>): Promise<void> {
103
- const run = currentRun()
104
- assert(run, 'Unable to execute commands outside a running task')
105
-
106
- const { params, options } = parseOptions(args, {})
107
- return spawnChild(cmd, params, options, run)
141
+ export function exec(
142
+ cmd: string,
143
+ ...args:
144
+ | [ ...args: string[] ]
145
+ | [ ...args: string[], options: ExecOptions ]
146
+ ): Promise<void> {
147
+ const { params, options } = parseOptions(args)
148
+ return spawnChild(cmd, params, options, requireContext())
108
149
  }
109
150
 
110
151
 
111
- /* ========================================================================== *
112
- * INSTALLATION *
113
- * ========================================================================== */
114
-
115
- install('exec', Exec)
116
-
117
- declare module '../pipe.js' {
118
- export interface Pipe {
119
- /**
120
- * Execute a shell command, adding to its _arguments_ the list of files
121
- * from the current pipe (much like `xargs` does on Unix systems).
122
- *
123
- * For example:
124
- *
125
- * ```
126
- * import { find, exec } from '@plugjs/plugjs'
127
- *
128
- * export default build({
129
- * async runme() {
130
- * find('*.ts', { directory: 'src' })
131
- * .exec('chmod', '755' })
132
- * .exec('chown root:root', { shell: true })
133
- * },
134
- * })
135
- * ```
136
- */
137
- exec: PipeExtension<typeof Exec>
138
- }
139
- }
140
-
141
152
  /* ========================================================================== *
142
153
  * INTERNALS *
143
154
  * ========================================================================== */
@@ -146,7 +157,7 @@ async function spawnChild(
146
157
  cmd: string,
147
158
  args: readonly string[],
148
159
  options: ExecOptions = {},
149
- run: Run,
160
+ context: Context,
150
161
  ): Promise<void> {
151
162
  const {
152
163
  env = {}, // default empty environment
@@ -155,18 +166,18 @@ async function spawnChild(
155
166
  ...extraOptions
156
167
  } = options
157
168
 
158
- const childCwd = cwd ? run.resolve(cwd) : getCurrentWorkingDirectory()
169
+ const childCwd = cwd ? context.resolve(cwd) : getCurrentWorkingDirectory()
159
170
  assert(resolveDirectory(childCwd), `Current working directory ${$p(childCwd)} does not exist`)
160
171
 
161
172
  // Figure out the PATH environment variable
162
173
  const childPaths: AbsolutePath[] = []
163
174
 
164
175
  // The `.../node_modules/.bin` path relative to the current working dir */
165
- const baseNodePath = run.resolve('@node_modules', '.bin')
176
+ const baseNodePath = context.resolve('@node_modules', '.bin')
166
177
  if (resolveDirectory(baseNodePath)) childPaths.push(baseNodePath)
167
178
 
168
179
  // The `.../node_bodules/.bin` path relative to the buildDir */
169
- const buildNodePath = run.resolve('./node_modules', '.bin')
180
+ const buildNodePath = context.resolve('./node_modules', '.bin')
170
181
  if (resolveDirectory(buildNodePath)) childPaths.push(buildNodePath)
171
182
 
172
183
  // Any other paths either from `process.env` or `env` (which overrides it)
@@ -175,7 +186,7 @@ async function spawnChild(
175
186
 
176
187
  // Build our environment variables record
177
188
  const PATH = childPaths.join(path.delimiter)
178
- const __LOG_OPTIONS = JSON.stringify(logOptions.fork(run.taskName))
189
+ const __LOG_OPTIONS = JSON.stringify(logOptions.fork(context.taskName))
179
190
  const childEnv = { ...process.env, ...env, PATH, __LOG_OPTIONS }
180
191
 
181
192
  // Prepare the options for calling `spawn`
@@ -188,18 +199,18 @@ async function spawnChild(
188
199
  }
189
200
 
190
201
  // Spawn our subprocess and monitor its stdout/stderr
191
- run.log.info('Executing', [ cmd, ...args ])
192
- run.log.info('Execution options', childOptions)
202
+ context.log.info('Executing', [ cmd, ...args ])
203
+ context.log.info('Execution options', childOptions)
193
204
  const child = spawn(cmd, args, childOptions)
194
205
 
195
206
  if (child.stdout) {
196
207
  const out = reaadline.createInterface(child.stdout)
197
- out.on('line', (line) => line ? run.log.notice(line) : run.log.notice('\u00a0'))
208
+ out.on('line', (line) => line ? context.log.notice(line) : context.log.notice('\u00a0'))
198
209
  }
199
210
 
200
211
  if (child.stderr) {
201
212
  const err = reaadline.createInterface(child.stderr)
202
- err.on('line', (line) => line ? run.log.warn(line) : run.log.warn('\u00a0'))
213
+ err.on('line', (line) => line ? context.log.warn(line) : context.log.warn('\u00a0'))
203
214
  }
204
215
 
205
216
  // Return our promise from the spawn events
@@ -1,9 +1,8 @@
1
- import { Files } from '../files.js'
2
- import { resolveRelativeChildPath } from '../paths.js'
3
- import { install, Plug } from '../pipe.js'
4
- import { Run } from '../run.js'
5
- import { match, MatchOptions } from '../utils/match.js'
6
- import { ParseOptions, parseOptions } from '../utils/options.js'
1
+ import { Files } from '../files'
2
+ import { resolveRelativeChildPath } from '../paths'
3
+ import { Context, install, PipeParameters, Plug } from '../pipe'
4
+ import { match, MatchOptions } from '../utils/match'
5
+ import { parseOptions } from '../utils/options'
7
6
 
8
7
  /** Options for filtering {@link Files}. */
9
8
  export interface FilterOptions extends MatchOptions {
@@ -11,45 +10,61 @@ export interface FilterOptions extends MatchOptions {
11
10
  directory?: string
12
11
  }
13
12
 
13
+ declare module '../pipe' {
14
+ export interface Pipe {
15
+ /**
16
+ * Filter the current {@link Files} using globs.
17
+ *
18
+ * @param glob The glob to use for filtering files
19
+ */
20
+ filter(glob: string): Pipe
21
+ /**
22
+ * Filter the current {@link Files} using globs.
23
+ *
24
+ * @param globs The globs to use for filtering files (at least one)
25
+ */
26
+ filter(...globs: [ string, ...string[] ]): Pipe
27
+ /**
28
+ * Filter the current {@link Files} using globs.
29
+ *
30
+ * @param globs The globs to use for filtering files (at least one)
31
+ * @param options Additional {@link FilterOptions | options} for filtering
32
+ */
33
+ filter(...args: [ ...globs: [ string, ...string[] ], options: FilterOptions ]): Pipe
34
+ }
35
+ }
36
+
37
+ /* ========================================================================== *
38
+ * INSTALLATION / IMPLEMENTATION *
39
+ * ========================================================================== */
40
+
14
41
  /** Filter the current {@link Files} using globs. */
15
- export class Filter implements Plug<Files> {
42
+ install('filter', class Filter implements Plug<Files> {
16
43
  private readonly _globs: readonly [ string, ...readonly string[] ]
17
44
  private readonly _options: FilterOptions
18
45
 
19
- constructor(glob: string, ...args: ParseOptions<FilterOptions>) {
46
+ constructor(...args: PipeParameters<'filter'>) {
20
47
  const { params, options } = parseOptions(args, {})
21
- this._globs = [ glob, ...params ]
22
48
  this._options = options
49
+ this._globs = params
23
50
  }
24
51
 
25
- pipe(files: Files, run: Run): Files {
52
+ pipe(files: Files, context: Context): Files {
26
53
  const { directory, ...options } = this._options
27
54
 
28
- const builder = run.files(directory || files.directory)
55
+ const dir = directory ? context.resolve(directory) : files.directory
56
+ const builder = Files.builder(dir)
29
57
  const matcher = match(this._globs, options)
30
58
 
31
59
  for (const file of files.absolutePaths()) {
32
60
  const relative = resolveRelativeChildPath(builder.directory, file)
33
- if (relative && matcher(relative)) builder.unchecked(relative)
61
+ if (relative && matcher(relative)) builder.add(relative)
34
62
  }
35
63
 
36
64
  const result = builder.build()
37
65
  const discarded = files.length - result.length
38
- run.log.debug('Filtered', result.length, 'files (discarded', discarded, 'files)')
66
+ context.log.debug('Filtered', result.length, 'files (discarded', discarded, 'files)')
39
67
 
40
68
  return result
41
69
  }
42
- }
43
-
44
- /* ========================================================================== *
45
- * INSTALLATION *
46
- * ========================================================================== */
47
-
48
- install('filter', Filter)
49
-
50
- declare module '../pipe.js' {
51
- export interface Pipe {
52
- /** Filter the current {@link Files} using globs. */
53
- filter: PipeExtension<typeof Filter>
54
- }
55
- }
70
+ })
@@ -2,7 +2,7 @@ import RealMocha from 'mocha' // Mocha types pollute the global scope!
2
2
 
3
3
  import { AssertionError } from 'assert'
4
4
  import { diffJson } from 'diff'
5
- import { $blu, $grn, $gry, $ms, $red, $wht, $ylw, ERROR, Logger, NOTICE, WARN } from '../../log.js'
5
+ import { $blu, $grn, $gry, $ms, $red, $wht, $ylw, ERROR, Logger, NOTICE, WARN } from '../../log'
6
6
 
7
7
  const _pending = '\u22EF' // middle ellipsis
8
8
  const _success = '\u2714' // heavy check mark
@@ -15,8 +15,6 @@ const _details = '\u21B3' // downwards arrow with tip rightwards
15
15
 
16
16
  /** Symbol to inject `Logger` in reporter options */
17
17
  export const logSymbol = Symbol()
18
- /** Symbol to inject `Run` in reporter options */
19
- export const runSymbol = Symbol()
20
18
 
21
19
  export class PlugReporter extends RealMocha.reporters.Base {
22
20
  constructor(runner: RealMocha.Runner, options: RealMocha.MochaOptions) {
@@ -26,6 +24,7 @@ export class PlugReporter extends RealMocha.reporters.Base {
26
24
  const log = options.reporterOptions[logSymbol] as Logger
27
25
  const failures: RealMocha.Test[] = []
28
26
  const rootSuite = runner.suite
27
+ let slow = 0
29
28
 
30
29
  // Enter a suite (increase indent)
31
30
  runner.on('suite', (suite) => {
@@ -55,9 +54,14 @@ export class PlugReporter extends RealMocha.reporters.Base {
55
54
 
56
55
  // Leave a test (handle warning/failures and decrease indent)
57
56
  runner.on('test end', (test) => {
58
- // TODO: slow!!!
59
57
  if (test.isPassed()) {
60
- log.leave(NOTICE, `${$grn(_success)} ${test.title}`)
58
+ const duration = test.duration || 0
59
+ if (duration < test.slow()) {
60
+ log.leave(NOTICE, `${$grn(_success)} ${test.title}`)
61
+ } else {
62
+ log.leave(WARN, `${$ylw(_success)} ${test.title} ${$ms(duration, 'slow')}`)
63
+ slow ++
64
+ }
61
65
  } else if (test.isPending()) {
62
66
  const tag = $gry('[') + $ylw('skipped') + $gry(']')
63
67
  log.leave(WARN, `${$ylw(_pending)} ${test.title} ${tag}`)
@@ -147,6 +151,7 @@ export class PlugReporter extends RealMocha.reporters.Base {
147
151
  const { passes, pending, failures, duration = 0 } = runner.stats
148
152
  const fmt = (n: number): string => n === 1 ? `${n} test` : `${n} tests`
149
153
  if (passes) log.notice($grn(fmt(passes)), 'passing', $ms(duration))
154
+ if (slow) log.warn($ylw(fmt(slow)), 'slow')
150
155
  if (pending) log.warn($ylw(fmt(pending)), 'pending')
151
156
  if (failures) log.error($red(fmt(failures)), 'pending')
152
157
  }
@@ -1,47 +1,22 @@
1
1
  import RealMocha from 'mocha' // Mocha types pollute the global scope!
2
2
 
3
- import { failure } from '../../assert.js'
4
- import { Files } from '../../files.js'
5
- import { $wht, NOTICE } from '../../log.js'
6
- import { Plug } from '../../pipe.js'
7
- import { Run } from '../../run.js'
8
- import { logSymbol, PlugReporter, runSymbol } from './reporter.js'
9
-
10
- /** Options to construct our {@link Mocha} plug. */
11
- export interface MochaOptions {
12
- /** Specify the directory where coverage data will be saved */
13
- coverageDir?: string,
14
- /** Bail after first test failure? */
15
- bail?: boolean,
16
- /** Show diff on failure? */
17
- diff?: boolean,
18
- /** Report tests without running them? */
19
- dryRun?: boolean,
20
- /** Tests marked `only` fail the suite? */
21
- forbidOnly?: boolean,
22
- /** Pending tests fail the suite? */
23
- forbidPending?: false,
24
- /** Reporter name. */
25
- reporter?: string
26
- /** Options for the reporter */
27
- reporterOptions?: Record<string, any>,
28
- /** Number of times to retry failed tests. */
29
- retries?: number,
30
- /** Slow threshold value. */
31
- slow?: number,
32
- /** Timeout threshold value. */
33
- timeout?: number,
34
- }
3
+ import { failure } from '../../assert'
4
+ import { Files } from '../../files'
5
+ import { $wht, NOTICE } from '../../log'
6
+ import { PipeParameters, Plug, Context } from '../../pipe'
7
+ import { MochaOptions } from '../mocha'
8
+ import { logSymbol, PlugReporter } from './reporter'
35
9
 
36
10
  /** Writes some info about the current {@link Files} being passed around. */
37
- export default class Mocha implements Plug<undefined> {
11
+ export default class Mocha implements Plug<void> {
12
+ constructor(...args: PipeParameters<'mocha'>)
38
13
  constructor(private readonly _options: MochaOptions = {}) {}
39
14
 
40
- async pipe(files: Files, run: Run): Promise<undefined> {
15
+ async pipe(files: Files, context: Context): Promise<void> {
41
16
  // Enter log here, so that log messages called when loading files get
42
17
  // properly indented by our logger
43
- run.log.notice('') // empty line
44
- run.log.enter(NOTICE, $wht('Starting Mocha'))
18
+ context.log.notice('') // empty line
19
+ context.log.enter(NOTICE, $wht('Starting Mocha'))
45
20
 
46
21
  // Create the mocha runner
47
22
  const mocha = new RealMocha({
@@ -50,8 +25,7 @@ export default class Mocha implements Plug<undefined> {
50
25
  ...this._options, // override defaults with all other options
51
26
  reporterOptions: {
52
27
  ...this._options.reporterOptions,
53
- [logSymbol]: run.log, // always force a log
54
- [runSymbol]: run, // always force a run
28
+ [logSymbol]: context.log, // always force a log
55
29
  },
56
30
  allowUncaught: false, // never allow uncaught exceptions
57
31
  delay: false, // never delay running
@@ -0,0 +1,41 @@
1
+ import { requireResolve } from '../paths'
2
+ import { installForking } from '../pipe'
3
+
4
+ /** Options to construct our {@link Mocha} plug. */
5
+ export interface MochaOptions {
6
+ /** Specify the directory where coverage data will be saved */
7
+ coverageDir?: string,
8
+ /** Bail after first test failure? */
9
+ bail?: boolean,
10
+ /** Show diff on failure? */
11
+ diff?: boolean,
12
+ /** Report tests without running them? */
13
+ dryRun?: boolean,
14
+ /** Tests marked `only` fail the suite? */
15
+ forbidOnly?: boolean,
16
+ /** Pending tests fail the suite? */
17
+ forbidPending?: false,
18
+ /** Reporter name. */
19
+ reporter?: string
20
+ /** Options for the reporter */
21
+ reporterOptions?: Record<string, any>,
22
+ /** Number of times to retry failed tests. */
23
+ retries?: number,
24
+ /** Slow threshold value. */
25
+ slow?: number,
26
+ /** Timeout threshold value. */
27
+ timeout?: number,
28
+ }
29
+
30
+ declare module '../pipe' {
31
+ export interface Pipe {
32
+ /**
33
+ * Run tests using {@link https://mochajs.org/ _Mocha_}.
34
+ *
35
+ * @param options Optional {@link MochaOptions | options} for _Mocha_.
36
+ */
37
+ mocha(options?: MochaOptions): Promise<undefined>
38
+ }
39
+ }
40
+
41
+ installForking('mocha', requireResolve(__fileurl, './mocha/runner'))
package/src/plugs/rmf.ts CHANGED
@@ -1,42 +1,38 @@
1
- import { Files } from '../files.js'
2
- import { $gry, $p } from '../log.js'
3
- import { install, Plug } from '../pipe.js'
4
- import { Run } from '../run.js'
5
- import { rm } from '../utils/asyncfs.js'
1
+ import { Files } from '../files'
2
+ import { $gry, $p } from '../log'
3
+ import { install, PipeParameters, Plug, Context } from '../pipe'
4
+ import { rm } from '../utils/asyncfs'
5
+
6
+ declare module '../pipe' {
7
+ export interface Pipe {
8
+ /**
9
+ * Remove all {@link Files} piped in.
10
+ *
11
+ * @param dryRun If `true` only log what would be removed (default `false`)
12
+ */
13
+ rmf(dryRun?: boolean): Promise<undefined>
14
+ }
15
+ }
6
16
 
7
17
  /** Remove some files using globs. */
8
- export class Rmf implements Plug<undefined> {
18
+ install('rmf', class Rmf implements Plug<void> {
9
19
  private readonly _dryRun: boolean
10
20
 
21
+ constructor(...args: PipeParameters<'rmf'>)
11
22
  constructor(dryRun?: boolean) {
12
23
  this._dryRun = !! dryRun
13
24
  }
14
25
 
15
- async pipe(files: Files, run: Run): Promise<undefined> {
26
+ async pipe(files: Files, context: Context): Promise<void> {
16
27
  if (this._dryRun) {
17
28
  for (const file of files.absolutePaths()) {
18
- run.log.notice('Not removing file', $p(file), $gry('(dry-run)'))
29
+ context.log.notice('Not removing file', $p(file), $gry('(dry-run)'))
19
30
  }
20
31
  } else {
21
32
  for (const file of files.absolutePaths()) {
22
- run.log.notice('Removing file', $p(file))
33
+ context.log.notice('Removing file', $p(file))
23
34
  await rm(file)
24
35
  }
25
36
  }
26
-
27
- return undefined
28
- }
29
- }
30
-
31
- /* ========================================================================== *
32
- * INSTALLATION *
33
- * ========================================================================== */
34
-
35
- install('rmf', Rmf)
36
-
37
- declare module '../pipe.js' {
38
- export interface Pipe {
39
- /** Remove all {@link Files} piped in. */
40
- rmf: PipeExtension<typeof Rmf>
41
37
  }
42
- }
38
+ })
@@ -1,6 +1,6 @@
1
1
  import ts from 'typescript' // TypeScript does NOT support ESM modules
2
2
 
3
- import { AbsolutePath, resolveAbsolutePath } from '../../paths.js'
3
+ import { AbsolutePath, resolveAbsolutePath } from '../../paths'
4
4
 
5
5
  export class TypeScriptHost
6
6
  implements ts.CompilerHost {
@@ -1,7 +1,7 @@
1
1
  import ts from 'typescript' // TypeScript does NOT support ESM modules
2
2
 
3
- import { AbsolutePath, getAbsoluteParent, resolveAbsolutePath } from '../../paths.js'
4
- import { readFile } from '../../utils/asyncfs.js'
3
+ import { AbsolutePath, getAbsoluteParent, resolveAbsolutePath } from '../../paths'
4
+ import { readFile } from '../../utils/asyncfs'
5
5
 
6
6
  /* ========================================================================== */
7
7
 
@@ -1,7 +1,7 @@
1
1
  import ts from 'typescript' // TypeScript does NOT support ESM modules
2
2
 
3
- import { ERROR, NOTICE, Report, ReportLevel, ReportRecord, WARN } from '../../log.js'
4
- import { AbsolutePath, resolveAbsolutePath } from '../../paths.js'
3
+ import { ERROR, NOTICE, Report, ReportLevel, ReportRecord, WARN } from '../../log'
4
+ import { AbsolutePath, resolveAbsolutePath } from '../../paths'
5
5
 
6
6
  function convertMessageChain(chain: ts.DiagnosticMessageChain, indent = 0): string[] {
7
7
  const message = `${''.padStart(indent * 2)}${chain.messageText}`