@jujulego/jill 2.5.2 → 3.0.0-alpha.10
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 -2
- package/bin/jill.js +1 -0
- package/dist/flat-job-tree.js +81 -0
- package/dist/flat-job-tree.js.map +1 -0
- package/dist/inked.js +66 -0
- package/dist/inked.js.map +1 -0
- package/dist/instrument.js +9 -0
- package/dist/instrument.js.map +1 -0
- package/dist/job-command-execute.ink.js +530 -0
- package/dist/job-command-execute.ink.js.map +1 -0
- package/dist/job-plan.js +133 -0
- package/dist/job-plan.js.map +1 -0
- package/dist/list.ink.js +54 -0
- package/dist/list.ink.js.map +1 -0
- package/dist/main.js +1969 -38
- package/dist/main.js.map +1 -1
- package/dist/planner.service.js +63 -0
- package/dist/planner.service.js.map +1 -0
- package/dist/tree.ink.js +189 -0
- package/dist/tree.ink.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +58 -54
- package/dist/ajv.config.d.ts +0 -3
- package/dist/commands/each.d.ts +0 -25
- package/dist/commands/exec.d.ts +0 -26
- package/dist/commands/group.d.ts +0 -16
- package/dist/commands/list.d.ts +0 -30
- package/dist/commands/run.d.ts +0 -24
- package/dist/commands/tree.d.ts +0 -6
- package/dist/commons/context.service.d.ts +0 -23
- package/dist/commons/git.service.d.ts +0 -62
- package/dist/commons/logger/log.gateway.d.ts +0 -18
- package/dist/commons/logger/parameters.d.ts +0 -2
- package/dist/commons/logger/thread.gateway.d.ts +0 -13
- package/dist/commons/logger/types.d.ts +0 -2
- package/dist/commons/logger.service.d.ts +0 -1
- package/dist/config/config-loader.d.ts +0 -4
- package/dist/config/config-options.d.ts +0 -5
- package/dist/config/types.d.ts +0 -8
- package/dist/config/utils.d.ts +0 -5
- package/dist/constants.d.ts +0 -1
- package/dist/core.plugin-Bxu0Sx70.js +0 -642
- package/dist/core.plugin-Bxu0Sx70.js.map +0 -1
- package/dist/core.plugin.d.ts +0 -2
- package/dist/filters/affected.filter.d.ts +0 -12
- package/dist/filters/pipeline.d.ts +0 -11
- package/dist/filters/private.filter.d.ts +0 -7
- package/dist/filters/scripts.filter.d.ts +0 -8
- package/dist/index.d.ts +0 -45
- package/dist/index.js +0 -35
- package/dist/index.js.map +0 -1
- package/dist/ink-command-S3TpJLFi.js +0 -2082
- package/dist/ink-command-S3TpJLFi.js.map +0 -1
- package/dist/ink.config.d.ts +0 -3
- package/dist/inversify.config.d.ts +0 -4
- package/dist/jill.application-CGujSe1_.js +0 -639
- package/dist/jill.application-CGujSe1_.js.map +0 -1
- package/dist/jill.application.d.ts +0 -19
- package/dist/main.d.ts +0 -1
- package/dist/middlewares/load-project.d.ts +0 -21
- package/dist/middlewares/load-workspace.d.ts +0 -20
- package/dist/modules/command.d.ts +0 -20
- package/dist/modules/ink-command.d.ts +0 -11
- package/dist/modules/middleware.d.ts +0 -8
- package/dist/modules/module.d.ts +0 -7
- package/dist/modules/plugin-loader.service.d.ts +0 -10
- package/dist/modules/plugin.d.ts +0 -14
- package/dist/modules/service.d.ts +0 -8
- package/dist/modules/task-command.d.ts +0 -14
- package/dist/project/project.d.ts +0 -27
- package/dist/project/project.repository.d.ts +0 -15
- package/dist/project/types.d.ts +0 -1
- package/dist/project/workspace.d.ts +0 -41
- package/dist/tasks/command-task.d.ts +0 -15
- package/dist/tasks/errors.d.ts +0 -4
- package/dist/tasks/script-task.d.ts +0 -27
- package/dist/tasks/task-expression.service.d.ts +0 -25
- package/dist/tasks/task-manager.config.d.ts +0 -3
- package/dist/types.d.ts +0 -11
- package/dist/ui/hooks/useFlatTaskTree.d.ts +0 -14
- package/dist/ui/hooks/useIsVerbose.d.ts +0 -1
- package/dist/ui/hooks/useStdoutDimensions.d.ts +0 -4
- package/dist/ui/layout.d.ts +0 -5
- package/dist/ui/list.d.ts +0 -5
- package/dist/ui/static-logs.d.ts +0 -1
- package/dist/ui/task-name.d.ts +0 -5
- package/dist/ui/task-spinner.d.ts +0 -5
- package/dist/ui/task-tree-completed.d.ts +0 -5
- package/dist/ui/task-tree-full-spinner.d.ts +0 -5
- package/dist/ui/task-tree-scrollable-spinner.d.ts +0 -5
- package/dist/ui/task-tree-spinner.d.ts +0 -5
- package/dist/ui/task-tree-stats.d.ts +0 -5
- package/dist/ui/workspace-tree.d.ts +0 -8
- package/dist/utils/events.d.ts +0 -3
- package/dist/utils/exit.d.ts +0 -4
- package/dist/utils/import.d.ts +0 -4
- package/dist/utils/json.d.ts +0 -2
- package/dist/utils/streams.d.ts +0 -3
- package/dist/utils/string.d.ts +0 -2
- package/dist/utils/worker-cache.d.ts +0 -4
- package/dist/workspace-tree-CyjZrimj.js +0 -1120
- package/dist/workspace-tree-CyjZrimj.js.map +0 -1
|
@@ -1,1120 +0,0 @@
|
|
|
1
|
-
import { _ } from '@swc/helpers/_/_ts_decorate';
|
|
2
|
-
import { Logger, withLabel } from '@jujulego/logger';
|
|
3
|
-
import { S as Service, u as TASK_MANAGER, n as lazyInject, C as CONFIG, m as container, q as CommandTask, t as ScriptTask, M as Middleware, D as ContextService, l as CURRENT, o as lazyInjectNamed, E as ExitException, i as getRegistry, k as setModule } from './ink-command-S3TpJLFi.js';
|
|
4
|
-
import { _ as _$1 } from '@swc/helpers/_/_ts_param';
|
|
5
|
-
import { inject, injectable, ContainerModule, id } from 'inversify';
|
|
6
|
-
import symbols from 'log-symbols';
|
|
7
|
-
import path from 'node:path';
|
|
8
|
-
import { satisfies } from 'semver';
|
|
9
|
-
import { off$, once$, iterate$ } from '@jujulego/event-tree';
|
|
10
|
-
import { SpawnTask, ParallelGroup, FallbackGroup, SequenceGroup } from '@jujulego/tasks';
|
|
11
|
-
import { Lock } from '@jujulego/utils';
|
|
12
|
-
import { Glob } from 'glob';
|
|
13
|
-
import fs from 'node:fs';
|
|
14
|
-
import normalize from 'normalize-package-data';
|
|
15
|
-
import { PathScurry } from 'path-scurry';
|
|
16
|
-
import fs$1 from 'node:fs/promises';
|
|
17
|
-
import moo from 'moo';
|
|
18
|
-
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
19
|
-
import { Text, Newline } from 'ink';
|
|
20
|
-
import { useState, useEffect } from 'react';
|
|
21
|
-
|
|
22
|
-
// Utils
|
|
23
|
-
async function* combine(...generators) {
|
|
24
|
-
for (const gen of generators){
|
|
25
|
-
yield* gen;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
async function* streamLines(task, stream) {
|
|
29
|
-
// Abort
|
|
30
|
-
const off = off$();
|
|
31
|
-
once$(task, "completed", off);
|
|
32
|
-
// Stream
|
|
33
|
-
let current = "";
|
|
34
|
-
try {
|
|
35
|
-
for await (const chunk of iterate$(task, `stream.${stream}`, {
|
|
36
|
-
off
|
|
37
|
-
})){
|
|
38
|
-
const data = current + chunk.data.toString("utf-8");
|
|
39
|
-
const lines = data.split(/\r?\n/);
|
|
40
|
-
current = lines.pop() ?? "";
|
|
41
|
-
for (const line of lines){
|
|
42
|
-
yield line;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
} catch (err) {
|
|
46
|
-
if (err.message !== "Unsubscribed !") {
|
|
47
|
-
throw err;
|
|
48
|
-
}
|
|
49
|
-
if (current) {
|
|
50
|
-
yield current;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
class GitService {
|
|
56
|
-
// Constructor
|
|
57
|
-
constructor(manager, logger){
|
|
58
|
-
this.manager = manager;
|
|
59
|
-
this.logger = logger;
|
|
60
|
-
}
|
|
61
|
-
// Methods
|
|
62
|
-
/**
|
|
63
|
-
* Runs a git command inside a SpawnTask
|
|
64
|
-
*
|
|
65
|
-
* @param cmd
|
|
66
|
-
* @param args
|
|
67
|
-
* @param options
|
|
68
|
-
*/ command(cmd, args, options = {}) {
|
|
69
|
-
const opts = {
|
|
70
|
-
logger: this.logger,
|
|
71
|
-
...options
|
|
72
|
-
};
|
|
73
|
-
// Create task
|
|
74
|
-
const task = new SpawnTask("git", [
|
|
75
|
-
cmd,
|
|
76
|
-
...args
|
|
77
|
-
], {
|
|
78
|
-
command: cmd,
|
|
79
|
-
hidden: true
|
|
80
|
-
}, opts);
|
|
81
|
-
task.on("stream", ({ data })=>opts.logger.debug(data.toString("utf-8")));
|
|
82
|
-
this.manager.add(task);
|
|
83
|
-
return task;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Runs git branch
|
|
87
|
-
*
|
|
88
|
-
* @param args
|
|
89
|
-
* @param options
|
|
90
|
-
*/ branch(args, options) {
|
|
91
|
-
return this.command("branch", args, options);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Runs git diff
|
|
95
|
-
*
|
|
96
|
-
* @param args
|
|
97
|
-
* @param options
|
|
98
|
-
*/ diff(args, options) {
|
|
99
|
-
return this.command("diff", args, options);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Runs git tag
|
|
103
|
-
*
|
|
104
|
-
* @param args
|
|
105
|
-
* @param options
|
|
106
|
-
*/ tag(args, options) {
|
|
107
|
-
return this.command("tag", args, options);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Uses git diff to detect if given files have been affected since given reference
|
|
111
|
-
*
|
|
112
|
-
* @param reference
|
|
113
|
-
* @param files
|
|
114
|
-
* @param opts
|
|
115
|
-
*/ isAffected(reference, files = [], opts) {
|
|
116
|
-
return new Promise((resolve, reject)=>{
|
|
117
|
-
const task = this.diff([
|
|
118
|
-
"--quiet",
|
|
119
|
-
reference,
|
|
120
|
-
"--",
|
|
121
|
-
...files
|
|
122
|
-
], opts);
|
|
123
|
-
once$(task, "status.done", ()=>resolve(false));
|
|
124
|
-
once$(task, "status.failed", ()=>{
|
|
125
|
-
if (task.exitCode) {
|
|
126
|
-
resolve(true);
|
|
127
|
-
} else {
|
|
128
|
-
reject(new Error(`Task ${task.name} failed`));
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* List git branches
|
|
135
|
-
*
|
|
136
|
-
* @param args
|
|
137
|
-
* @param opts
|
|
138
|
-
*/ async listBranches(args = [], opts) {
|
|
139
|
-
const task = this.branch([
|
|
140
|
-
"-l",
|
|
141
|
-
...args
|
|
142
|
-
], opts);
|
|
143
|
-
const result = [];
|
|
144
|
-
for await (const line of streamLines(task, "stdout")){
|
|
145
|
-
result.push(line.replace(/^[ *] /, ""));
|
|
146
|
-
}
|
|
147
|
-
return result;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* List git tags
|
|
151
|
-
*
|
|
152
|
-
* @param args
|
|
153
|
-
* @param opts
|
|
154
|
-
*/ async listTags(args = [], opts) {
|
|
155
|
-
const task = this.tag([
|
|
156
|
-
"-l",
|
|
157
|
-
...args
|
|
158
|
-
], opts);
|
|
159
|
-
const result = [];
|
|
160
|
-
for await (const line of streamLines(task, "stdout")){
|
|
161
|
-
result.push(line);
|
|
162
|
-
}
|
|
163
|
-
return result;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
GitService = _([
|
|
167
|
-
Service(),
|
|
168
|
-
_$1(0, inject(TASK_MANAGER)),
|
|
169
|
-
_$1(1, inject(Logger))
|
|
170
|
-
], GitService);
|
|
171
|
-
|
|
172
|
-
// Class
|
|
173
|
-
class AffectedFilter {
|
|
174
|
-
// Constructor
|
|
175
|
-
constructor(format, fallback, sort){
|
|
176
|
-
this.format = format;
|
|
177
|
-
this.fallback = fallback;
|
|
178
|
-
this.sort = sort;
|
|
179
|
-
}
|
|
180
|
-
// Methods
|
|
181
|
-
async _formatRevision(wks) {
|
|
182
|
-
const logger = this._logger.child(withLabel(wks.name));
|
|
183
|
-
// Format revision
|
|
184
|
-
let result = this.format;
|
|
185
|
-
result = result.replace(/(?<!\\)((?:\\\\)*)%name/g, `$1${wks.name}`);
|
|
186
|
-
result = result.replace(/\\(.)/g, "$1");
|
|
187
|
-
// Ask git to complete it
|
|
188
|
-
const sortArgs = this.sort ? [
|
|
189
|
-
"--sort",
|
|
190
|
-
this.sort
|
|
191
|
-
] : [];
|
|
192
|
-
// - search in branches
|
|
193
|
-
if (result.includes("*")) {
|
|
194
|
-
const branches = await this._git.listBranches([
|
|
195
|
-
...sortArgs,
|
|
196
|
-
result
|
|
197
|
-
], {
|
|
198
|
-
cwd: wks.cwd,
|
|
199
|
-
logger: logger
|
|
200
|
-
});
|
|
201
|
-
if (branches.length > 0) {
|
|
202
|
-
result = branches[branches.length - 1];
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
// - search in tags
|
|
206
|
-
if (result.includes("*")) {
|
|
207
|
-
const tags = await this._git.listTags([
|
|
208
|
-
...sortArgs,
|
|
209
|
-
result
|
|
210
|
-
], {
|
|
211
|
-
cwd: wks.cwd,
|
|
212
|
-
logger: logger
|
|
213
|
-
});
|
|
214
|
-
if (tags.length > 0) {
|
|
215
|
-
result = tags[tags.length - 1];
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
if (result !== this.format) {
|
|
219
|
-
logger.verbose`Resolved ${this.format} into ${result}`;
|
|
220
|
-
}
|
|
221
|
-
if (result.includes("*")) {
|
|
222
|
-
logger.warning(`No revision found matching ${result}, using fallback ${this.fallback}`);
|
|
223
|
-
return this.fallback;
|
|
224
|
-
}
|
|
225
|
-
return result;
|
|
226
|
-
}
|
|
227
|
-
async test(workspace) {
|
|
228
|
-
const rev = await this._formatRevision(workspace);
|
|
229
|
-
return await workspace.isAffected(rev);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
_([
|
|
233
|
-
lazyInject(Logger)
|
|
234
|
-
], AffectedFilter.prototype, "_logger", void 0);
|
|
235
|
-
_([
|
|
236
|
-
lazyInject(GitService)
|
|
237
|
-
], AffectedFilter.prototype, "_git", void 0);
|
|
238
|
-
|
|
239
|
-
// Class
|
|
240
|
-
class Pipeline {
|
|
241
|
-
// Methods
|
|
242
|
-
add(filter) {
|
|
243
|
-
this._filters.push(filter);
|
|
244
|
-
}
|
|
245
|
-
async _test(workspace) {
|
|
246
|
-
for (const filter of this._filters){
|
|
247
|
-
const res = await filter.test(workspace);
|
|
248
|
-
if (!res) {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return true;
|
|
253
|
-
}
|
|
254
|
-
async *filter(workspaces) {
|
|
255
|
-
for await (const wks of workspaces){
|
|
256
|
-
if (await this._test(wks)) {
|
|
257
|
-
yield wks;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
constructor(){
|
|
262
|
-
// Attributes
|
|
263
|
-
this._filters = [];
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Filter
|
|
268
|
-
class PrivateFilter {
|
|
269
|
-
// Constructor
|
|
270
|
-
constructor(value){
|
|
271
|
-
this.value = value;
|
|
272
|
-
}
|
|
273
|
-
// Methods
|
|
274
|
-
test(workspace) {
|
|
275
|
-
return (workspace.manifest.private ?? false) === this.value;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Filter
|
|
280
|
-
class ScriptsFilter {
|
|
281
|
-
// Constructor
|
|
282
|
-
constructor(scripts, all = false){
|
|
283
|
-
this.scripts = scripts;
|
|
284
|
-
this.all = all;
|
|
285
|
-
}
|
|
286
|
-
// Methods
|
|
287
|
-
test(workspace) {
|
|
288
|
-
const scripts = Object.keys(workspace.manifest.scripts || {});
|
|
289
|
-
if (this.all) {
|
|
290
|
-
return this.scripts.every((scr)=>scripts.includes(scr));
|
|
291
|
-
} else {
|
|
292
|
-
return this.scripts.some((scr)=>scripts.includes(scr));
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
class Workspace {
|
|
298
|
-
// Constructor
|
|
299
|
-
constructor(_cwd, manifest, project){
|
|
300
|
-
this._cwd = _cwd;
|
|
301
|
-
this.manifest = manifest;
|
|
302
|
-
this.project = project;
|
|
303
|
-
this._affectedCache = new Map();
|
|
304
|
-
this._tasks = new Map();
|
|
305
|
-
const logger = container.get(Logger);
|
|
306
|
-
this._logger = logger.child(withLabel(this.manifest.name));
|
|
307
|
-
}
|
|
308
|
-
// Methods
|
|
309
|
-
_satisfies(from, range) {
|
|
310
|
-
if (range.startsWith("file:")) {
|
|
311
|
-
return path.resolve(from.cwd, range.substring(5)) === this.cwd;
|
|
312
|
-
}
|
|
313
|
-
if (range.startsWith("workspace:")) {
|
|
314
|
-
range = range.substring(10);
|
|
315
|
-
}
|
|
316
|
-
return !this.version || satisfies(this.version, range);
|
|
317
|
-
}
|
|
318
|
-
async _buildDependencies(task, opts) {
|
|
319
|
-
// Generators
|
|
320
|
-
const generators = [];
|
|
321
|
-
switch(opts.buildDeps ?? "all"){
|
|
322
|
-
case "all":
|
|
323
|
-
generators.unshift(this.devDependencies());
|
|
324
|
-
// eslint-disable-next no-fallthrough
|
|
325
|
-
case "prod":
|
|
326
|
-
generators.unshift(this.dependencies());
|
|
327
|
-
}
|
|
328
|
-
// Build deps
|
|
329
|
-
for await (const dep of combine(...generators)){
|
|
330
|
-
const build = await dep.build(opts);
|
|
331
|
-
if (build) {
|
|
332
|
-
task.dependsOn(build);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
async _isAffected(reference) {
|
|
337
|
-
const isAffected = await this._git.isAffected(reference, [
|
|
338
|
-
this.cwd
|
|
339
|
-
], {
|
|
340
|
-
cwd: this.project.root,
|
|
341
|
-
logger: this._logger
|
|
342
|
-
});
|
|
343
|
-
if (isAffected) {
|
|
344
|
-
return true;
|
|
345
|
-
}
|
|
346
|
-
// Test dependencies
|
|
347
|
-
const proms = [];
|
|
348
|
-
for await (const dep of combine(this.dependencies(), this.devDependencies())){
|
|
349
|
-
proms.push(dep.isAffected(reference));
|
|
350
|
-
}
|
|
351
|
-
const results = await Promise.all(proms);
|
|
352
|
-
return results.some((r)=>r);
|
|
353
|
-
}
|
|
354
|
-
async isAffected(reference) {
|
|
355
|
-
let isAffected = this._affectedCache.get(reference);
|
|
356
|
-
if (!isAffected) {
|
|
357
|
-
isAffected = this._isAffected(reference);
|
|
358
|
-
this._affectedCache.set(reference, isAffected);
|
|
359
|
-
}
|
|
360
|
-
return await isAffected;
|
|
361
|
-
}
|
|
362
|
-
async *_loadDependencies(dependencies, kind) {
|
|
363
|
-
for (const [dep, range] of Object.entries(dependencies)){
|
|
364
|
-
const ws = await this.project.workspace(dep);
|
|
365
|
-
if (ws) {
|
|
366
|
-
if (ws._satisfies(this, range)) {
|
|
367
|
-
yield ws;
|
|
368
|
-
} else {
|
|
369
|
-
this._logger.warning(`Ignoring ${kind} ${ws.reference} as it does not match requirement ${range}`);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
async *dependencies() {
|
|
375
|
-
if (!this.manifest.dependencies) return;
|
|
376
|
-
for await (const ws of this._loadDependencies(this.manifest.dependencies, "dependency")){
|
|
377
|
-
yield ws;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
async *devDependencies() {
|
|
381
|
-
if (!this.manifest.devDependencies) return;
|
|
382
|
-
for await (const ws of this._loadDependencies(this.manifest.devDependencies, "devDependency")){
|
|
383
|
-
yield ws;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
async exec(command, args = [], opts = {}) {
|
|
387
|
-
const pm = await this.project.packageManager();
|
|
388
|
-
const task = new CommandTask(this, command, args, {
|
|
389
|
-
...opts,
|
|
390
|
-
logger: this._logger.child(withLabel(`${this.name}$${command}`)),
|
|
391
|
-
superCommand: pm === "yarn" ? [
|
|
392
|
-
"yarn",
|
|
393
|
-
"exec"
|
|
394
|
-
] : undefined
|
|
395
|
-
});
|
|
396
|
-
await this._buildDependencies(task, opts);
|
|
397
|
-
return task;
|
|
398
|
-
}
|
|
399
|
-
async run(script, args = [], opts = {}) {
|
|
400
|
-
// Script not found
|
|
401
|
-
if (!this.getScript(script)) {
|
|
402
|
-
return null;
|
|
403
|
-
}
|
|
404
|
-
// Create task if it doesn't exist yet
|
|
405
|
-
let task = this._tasks.get(script);
|
|
406
|
-
if (!task) {
|
|
407
|
-
task = new ScriptTask(this, script, args, {
|
|
408
|
-
...opts,
|
|
409
|
-
logger: this._logger.child(withLabel(`${this.name}#${script}`)),
|
|
410
|
-
runHooks: this._config.hooks
|
|
411
|
-
});
|
|
412
|
-
await task.prepare();
|
|
413
|
-
await this._buildDependencies(task, opts);
|
|
414
|
-
this._tasks.set(script, task);
|
|
415
|
-
}
|
|
416
|
-
return task;
|
|
417
|
-
}
|
|
418
|
-
async build(opts = {}) {
|
|
419
|
-
const task = await this.run(opts?.buildScript ?? "build", [], opts);
|
|
420
|
-
if (!task) {
|
|
421
|
-
this._logger.warning("Will not be built (no build script)");
|
|
422
|
-
}
|
|
423
|
-
return task;
|
|
424
|
-
}
|
|
425
|
-
getScript(script) {
|
|
426
|
-
const { scripts = {} } = this.manifest;
|
|
427
|
-
return scripts[script] || null;
|
|
428
|
-
}
|
|
429
|
-
toJSON() {
|
|
430
|
-
return {
|
|
431
|
-
name: this.name,
|
|
432
|
-
version: this.version,
|
|
433
|
-
cwd: this.cwd
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
// Properties
|
|
437
|
-
get name() {
|
|
438
|
-
return this.manifest.name;
|
|
439
|
-
}
|
|
440
|
-
get version() {
|
|
441
|
-
return this.manifest.version;
|
|
442
|
-
}
|
|
443
|
-
get reference() {
|
|
444
|
-
return this.version ? `${this.name}@${this.version}` : this.name;
|
|
445
|
-
}
|
|
446
|
-
get cwd() {
|
|
447
|
-
return path.resolve(this.project.root, this._cwd);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
_([
|
|
451
|
-
lazyInject(GitService)
|
|
452
|
-
], Workspace.prototype, "_git", void 0);
|
|
453
|
-
_([
|
|
454
|
-
lazyInject(CONFIG)
|
|
455
|
-
], Workspace.prototype, "_config", void 0);
|
|
456
|
-
Workspace = _([
|
|
457
|
-
injectable()
|
|
458
|
-
], Workspace);
|
|
459
|
-
|
|
460
|
-
class Project {
|
|
461
|
-
// Constructor
|
|
462
|
-
constructor(_root, _logger, opts = {}){
|
|
463
|
-
this._root = _root;
|
|
464
|
-
this._logger = _logger;
|
|
465
|
-
this._names = new Map();
|
|
466
|
-
this._workspaces = new Map();
|
|
467
|
-
this._isFullyLoaded = false;
|
|
468
|
-
this._lock = new Lock();
|
|
469
|
-
this._scurry = new PathScurry(this.root, {
|
|
470
|
-
fs
|
|
471
|
-
});
|
|
472
|
-
if (opts.packageManager) {
|
|
473
|
-
this._logger.debug`Forced use of ${opts.packageManager} in #!cwd:${this.root}`;
|
|
474
|
-
this._packageManager = opts.packageManager;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
// Methods
|
|
478
|
-
async _loadManifest(dir) {
|
|
479
|
-
const file = path.resolve(this.root, dir, "package.json");
|
|
480
|
-
const relative = path.relative(this.root, path.dirname(file));
|
|
481
|
-
const logger = this._logger.child(withLabel(relative ? `project@${relative}` : "project"));
|
|
482
|
-
logger.debug("Loading package.json ...");
|
|
483
|
-
const data = await fs.promises.readFile(file, "utf-8");
|
|
484
|
-
const mnf = JSON.parse(data);
|
|
485
|
-
normalize(mnf, (msg)=>logger.verbose(msg));
|
|
486
|
-
return mnf;
|
|
487
|
-
}
|
|
488
|
-
async _loadWorkspace(dir) {
|
|
489
|
-
return await this._lock.with(async ()=>{
|
|
490
|
-
let wks = this._workspaces.get(dir);
|
|
491
|
-
if (!wks) {
|
|
492
|
-
const manifest = await this._loadManifest(dir);
|
|
493
|
-
wks = new Workspace(dir, manifest, this);
|
|
494
|
-
this._workspaces.set(dir, wks);
|
|
495
|
-
this._names.set(wks.name, wks);
|
|
496
|
-
}
|
|
497
|
-
return wks;
|
|
498
|
-
});
|
|
499
|
-
}
|
|
500
|
-
async packageManager() {
|
|
501
|
-
if (!this._packageManager) {
|
|
502
|
-
this._logger.debug`Searching lockfile from #!cwd:${this.root}`;
|
|
503
|
-
const files = await this._scurry.readdir(this.root, {
|
|
504
|
-
withFileTypes: false
|
|
505
|
-
});
|
|
506
|
-
if (files.includes("yarn.lock")) {
|
|
507
|
-
this._logger.debug`Detected yarn in #!cwd:${this.root}`;
|
|
508
|
-
this._packageManager = "yarn";
|
|
509
|
-
} else if (files.includes("package-lock.json")) {
|
|
510
|
-
this._logger.debug`Detected npm in #!cwd:${this.root}`;
|
|
511
|
-
this._packageManager = "npm";
|
|
512
|
-
} else {
|
|
513
|
-
this._logger.debug`No package manager recognized in #!cwd:${this.root}, defaults to npm`;
|
|
514
|
-
this._packageManager = "npm";
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
return this._packageManager;
|
|
518
|
-
}
|
|
519
|
-
async mainWorkspace() {
|
|
520
|
-
if (!this._mainWorkspace) {
|
|
521
|
-
const manifest = await this._loadManifest(".");
|
|
522
|
-
this._mainWorkspace = new Workspace(".", manifest, this);
|
|
523
|
-
this._names.set(this._mainWorkspace.name, this._mainWorkspace);
|
|
524
|
-
}
|
|
525
|
-
return this._mainWorkspace;
|
|
526
|
-
}
|
|
527
|
-
async currentWorkspace(cwd = process.cwd()) {
|
|
528
|
-
let workspace = null;
|
|
529
|
-
cwd = path.resolve(cwd);
|
|
530
|
-
for await (const wks of this.workspaces()){
|
|
531
|
-
if (cwd.startsWith(wks.cwd)) {
|
|
532
|
-
workspace = wks;
|
|
533
|
-
if (wks.cwd !== this.root) return wks;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
return workspace;
|
|
537
|
-
}
|
|
538
|
-
async *workspaces() {
|
|
539
|
-
const main = await this.mainWorkspace();
|
|
540
|
-
yield main;
|
|
541
|
-
if (this._isFullyLoaded) {
|
|
542
|
-
for (const wks of this._names.values()){
|
|
543
|
-
if (wks.name !== main.name) yield wks;
|
|
544
|
-
}
|
|
545
|
-
} else {
|
|
546
|
-
// Load child workspaces
|
|
547
|
-
const { workspaces = [] } = main.manifest;
|
|
548
|
-
this._workspaceGlob ??= new Glob(workspaces, {
|
|
549
|
-
scurry: this._scurry,
|
|
550
|
-
withFileTypes: true
|
|
551
|
-
});
|
|
552
|
-
for await (const dir of this._workspaceGlob){
|
|
553
|
-
try {
|
|
554
|
-
// Check if dir is a directory
|
|
555
|
-
if (dir.isDirectory()) {
|
|
556
|
-
yield await this._loadWorkspace(dir.fullpath());
|
|
557
|
-
}
|
|
558
|
-
} catch (error) {
|
|
559
|
-
if (error.code === "ENOENT") {
|
|
560
|
-
continue;
|
|
561
|
-
}
|
|
562
|
-
throw error;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
this._isFullyLoaded = true;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
async workspace(name) {
|
|
569
|
-
// With current directory
|
|
570
|
-
if (!name) {
|
|
571
|
-
const dir = path.relative(this.root, process.cwd());
|
|
572
|
-
return this._loadWorkspace(dir);
|
|
573
|
-
}
|
|
574
|
-
// Try name index
|
|
575
|
-
const wks = this._names.get(name);
|
|
576
|
-
if (wks) {
|
|
577
|
-
return wks;
|
|
578
|
-
}
|
|
579
|
-
// Load workspaces
|
|
580
|
-
if (!this._isFullyLoaded) {
|
|
581
|
-
for await (const ws of this.workspaces()){
|
|
582
|
-
if (ws.name === name) {
|
|
583
|
-
return ws;
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
this._isFullyLoaded = true;
|
|
587
|
-
}
|
|
588
|
-
return null;
|
|
589
|
-
}
|
|
590
|
-
// Properties
|
|
591
|
-
get root() {
|
|
592
|
-
return path.resolve(this._root);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
Project = _([
|
|
596
|
-
injectable()
|
|
597
|
-
], Project);
|
|
598
|
-
|
|
599
|
-
// Constants
|
|
600
|
-
const MANIFEST = "package.json";
|
|
601
|
-
const LOCK_FILES = [
|
|
602
|
-
"package-lock.json",
|
|
603
|
-
"yarn.lock"
|
|
604
|
-
];
|
|
605
|
-
class ProjectRepository {
|
|
606
|
-
// Constructor
|
|
607
|
-
constructor(logger){
|
|
608
|
-
this._cache = new Map();
|
|
609
|
-
this._roots = new Map();
|
|
610
|
-
this._logger = logger.child(withLabel("projects"));
|
|
611
|
-
}
|
|
612
|
-
// Methods
|
|
613
|
-
async isProjectRoot(dir) {
|
|
614
|
-
const files = await fs$1.readdir(dir);
|
|
615
|
-
return {
|
|
616
|
-
hasManifest: files.includes(MANIFEST),
|
|
617
|
-
hasLockFile: LOCK_FILES.some((lock)=>files.includes(lock))
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
async searchProjectRoot(directory) {
|
|
621
|
-
directory = path.resolve(directory);
|
|
622
|
-
// Test all ancestors
|
|
623
|
-
const steps = [];
|
|
624
|
-
let foundManifest = false;
|
|
625
|
-
let projectRoot = directory;
|
|
626
|
-
let dir = directory;
|
|
627
|
-
let prev = dir;
|
|
628
|
-
do {
|
|
629
|
-
// Check cache
|
|
630
|
-
const root = this._roots.get(dir);
|
|
631
|
-
if (root) {
|
|
632
|
-
projectRoot = root;
|
|
633
|
-
foundManifest = true;
|
|
634
|
-
break;
|
|
635
|
-
}
|
|
636
|
-
// Look for files
|
|
637
|
-
const { hasManifest, hasLockFile } = await this.isProjectRoot(dir);
|
|
638
|
-
steps.push(dir);
|
|
639
|
-
if (hasManifest) {
|
|
640
|
-
projectRoot = dir;
|
|
641
|
-
foundManifest = true;
|
|
642
|
-
}
|
|
643
|
-
if (hasLockFile) {
|
|
644
|
-
break;
|
|
645
|
-
}
|
|
646
|
-
prev = dir;
|
|
647
|
-
dir = path.dirname(dir);
|
|
648
|
-
}while (prev !== dir);
|
|
649
|
-
// Cache result
|
|
650
|
-
for (const dir of steps){
|
|
651
|
-
if (dir.startsWith(projectRoot)) {
|
|
652
|
-
this._roots.set(dir, projectRoot);
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
// Log it
|
|
656
|
-
if (foundManifest) {
|
|
657
|
-
this._logger.debug`Project root found at #!cwd:${projectRoot}`;
|
|
658
|
-
} else {
|
|
659
|
-
this._logger.debug`Project root not found, keeping #!cwd:${projectRoot}`;
|
|
660
|
-
}
|
|
661
|
-
return projectRoot;
|
|
662
|
-
}
|
|
663
|
-
getProject(root, opts) {
|
|
664
|
-
let project = this._cache.get(root);
|
|
665
|
-
if (!project) {
|
|
666
|
-
project = new Project(root, this._logger, opts);
|
|
667
|
-
this._cache.set(root, project);
|
|
668
|
-
}
|
|
669
|
-
return project;
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
ProjectRepository = _([
|
|
673
|
-
Service(),
|
|
674
|
-
_$1(0, inject(Logger))
|
|
675
|
-
], ProjectRepository);
|
|
676
|
-
|
|
677
|
-
class LoadProject {
|
|
678
|
-
// Constructor
|
|
679
|
-
constructor(projects, context){
|
|
680
|
-
this.projects = projects;
|
|
681
|
-
this.context = context;
|
|
682
|
-
}
|
|
683
|
-
// Methods
|
|
684
|
-
builder(parser) {
|
|
685
|
-
return parser.option("project", {
|
|
686
|
-
alias: "p",
|
|
687
|
-
type: "string",
|
|
688
|
-
description: "Project root directory"
|
|
689
|
-
}).option("package-manager", {
|
|
690
|
-
choices: [
|
|
691
|
-
"yarn",
|
|
692
|
-
"npm"
|
|
693
|
-
],
|
|
694
|
-
type: "string",
|
|
695
|
-
description: "Force package manager"
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
async handler(args) {
|
|
699
|
-
if (!this.context.project || args.project) {
|
|
700
|
-
args.project = await this.projects.searchProjectRoot(args.project ?? process.cwd());
|
|
701
|
-
this.context.project = this.projects.getProject(args.project, {
|
|
702
|
-
packageManager: args.packageManager
|
|
703
|
-
});
|
|
704
|
-
} else {
|
|
705
|
-
args.project = this.context.project.root;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
LoadProject = _([
|
|
710
|
-
Middleware(),
|
|
711
|
-
_$1(0, inject(ProjectRepository)),
|
|
712
|
-
_$1(1, inject(ContextService))
|
|
713
|
-
], LoadProject);
|
|
714
|
-
// Lazy injection
|
|
715
|
-
function LazyCurrentProject() {
|
|
716
|
-
return lazyInjectNamed(Project, CURRENT);
|
|
717
|
-
}
|
|
718
|
-
container.bind(Project).toDynamicValue(({ container })=>{
|
|
719
|
-
const ctx = container.get(ContextService);
|
|
720
|
-
const prj = ctx.project;
|
|
721
|
-
if (!prj) {
|
|
722
|
-
throw new Error("Cannot inject current project, it not yet defined");
|
|
723
|
-
}
|
|
724
|
-
return prj;
|
|
725
|
-
}).whenTargetNamed(CURRENT);
|
|
726
|
-
|
|
727
|
-
class LoadWorkspace {
|
|
728
|
-
// Constructor
|
|
729
|
-
constructor(context, logger){
|
|
730
|
-
this.context = context;
|
|
731
|
-
this.logger = logger;
|
|
732
|
-
}
|
|
733
|
-
// Methods
|
|
734
|
-
builder(parser) {
|
|
735
|
-
return parser.option("workspace", {
|
|
736
|
-
alias: "w",
|
|
737
|
-
type: "string",
|
|
738
|
-
desc: "Workspace to use"
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
async handler(args) {
|
|
742
|
-
let workspace = this.context.workspace ?? null;
|
|
743
|
-
if (!workspace || args.workspace) {
|
|
744
|
-
if (args.workspace) {
|
|
745
|
-
workspace = await this.project.workspace(args.workspace);
|
|
746
|
-
} else if (process.cwd().startsWith(this.project.root)) {
|
|
747
|
-
workspace = await this.project.currentWorkspace();
|
|
748
|
-
} else {
|
|
749
|
-
workspace = await this.project.mainWorkspace();
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
if (!workspace) {
|
|
753
|
-
this.logger.error(`${symbols.error} Workspace "${args.workspace || "."}" not found`);
|
|
754
|
-
throw new ExitException(1, "Workspace not found");
|
|
755
|
-
} else {
|
|
756
|
-
this.context.workspace = workspace;
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
_([
|
|
761
|
-
LazyCurrentProject()
|
|
762
|
-
], LoadWorkspace.prototype, "project", void 0);
|
|
763
|
-
LoadWorkspace = _([
|
|
764
|
-
Middleware(),
|
|
765
|
-
_$1(0, inject(ContextService)),
|
|
766
|
-
_$1(1, inject(Logger))
|
|
767
|
-
], LoadWorkspace);
|
|
768
|
-
// Decorators
|
|
769
|
-
function LazyCurrentWorkspace() {
|
|
770
|
-
return lazyInjectNamed(Workspace, CURRENT);
|
|
771
|
-
}
|
|
772
|
-
container.bind(Workspace).toDynamicValue(({ container })=>{
|
|
773
|
-
const ctx = container.get(ContextService);
|
|
774
|
-
const wks = ctx.workspace;
|
|
775
|
-
if (!wks) {
|
|
776
|
-
throw new Error("Cannot inject current workspace, it not yet defined");
|
|
777
|
-
}
|
|
778
|
-
return wks;
|
|
779
|
-
}).whenTargetNamed(CURRENT);
|
|
780
|
-
|
|
781
|
-
class PluginModule extends ContainerModule {
|
|
782
|
-
// Constructor
|
|
783
|
-
constructor(name, commands){
|
|
784
|
-
super((...args)=>{
|
|
785
|
-
for (const command of this.commands){
|
|
786
|
-
const registry = getRegistry(command);
|
|
787
|
-
registry(...args);
|
|
788
|
-
}
|
|
789
|
-
});
|
|
790
|
-
this.name = name;
|
|
791
|
-
this.commands = commands;
|
|
792
|
-
this.id = id();
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
// Decorator
|
|
796
|
-
function Plugin(opts) {
|
|
797
|
-
return (target)=>{
|
|
798
|
-
const name = opts.name ?? target.name;
|
|
799
|
-
const module = new PluginModule(name, opts.commands);
|
|
800
|
-
setModule(target, module);
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
class TaskExpressionError extends Error {
|
|
805
|
-
}
|
|
806
|
-
class TaskSyntaxError extends Error {
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
class TaskExpressionService {
|
|
810
|
-
// Statics
|
|
811
|
-
static isTaskNode(node) {
|
|
812
|
-
return "script" in node;
|
|
813
|
-
}
|
|
814
|
-
static{
|
|
815
|
-
this._sequenceOperatorWarn = true;
|
|
816
|
-
}
|
|
817
|
-
// Constructor
|
|
818
|
-
constructor(_logger){
|
|
819
|
-
this._logger = _logger;
|
|
820
|
-
}
|
|
821
|
-
// Methods
|
|
822
|
-
_lexer() {
|
|
823
|
-
return moo.states({
|
|
824
|
-
task: {
|
|
825
|
-
lparen: "(",
|
|
826
|
-
whitespace: /[ \t]+/,
|
|
827
|
-
script: {
|
|
828
|
-
match: /[-_:a-zA-Z0-9]+/,
|
|
829
|
-
push: "operatorOrArgument"
|
|
830
|
-
},
|
|
831
|
-
string: [
|
|
832
|
-
{
|
|
833
|
-
match: /'(?:\\['\\]|[^\r\n'\\])+'/,
|
|
834
|
-
push: "operator",
|
|
835
|
-
value: (x)=>x.slice(1, -1).replace(/\\(['\\])/g, "$1")
|
|
836
|
-
},
|
|
837
|
-
{
|
|
838
|
-
match: /"(?:\\["\\]|[^\r\n"\\])+"/,
|
|
839
|
-
push: "operator",
|
|
840
|
-
value: (x)=>x.slice(1, -1).replace(/\\(["\\])/g, "$1")
|
|
841
|
-
}
|
|
842
|
-
]
|
|
843
|
-
},
|
|
844
|
-
operator: {
|
|
845
|
-
rparen: ")",
|
|
846
|
-
whitespace: /[ \t]+/,
|
|
847
|
-
operator: {
|
|
848
|
-
match: [
|
|
849
|
-
"->",
|
|
850
|
-
"&&",
|
|
851
|
-
"//",
|
|
852
|
-
"||"
|
|
853
|
-
],
|
|
854
|
-
pop: 1
|
|
855
|
-
}
|
|
856
|
-
},
|
|
857
|
-
operatorOrArgument: {
|
|
858
|
-
rparen: ")",
|
|
859
|
-
whitespace: /[ \t]+/,
|
|
860
|
-
operator: {
|
|
861
|
-
match: [
|
|
862
|
-
"->",
|
|
863
|
-
"&&",
|
|
864
|
-
"//",
|
|
865
|
-
"||"
|
|
866
|
-
],
|
|
867
|
-
pop: 1
|
|
868
|
-
},
|
|
869
|
-
argument: [
|
|
870
|
-
{
|
|
871
|
-
match: /[-_:a-zA-Z0-9]+/
|
|
872
|
-
},
|
|
873
|
-
{
|
|
874
|
-
match: /'(?:\\['\\]|[^\r\n'\\])+'/,
|
|
875
|
-
value: (x)=>x.slice(1, -1).replace(/\\(['\\])/g, "$1")
|
|
876
|
-
},
|
|
877
|
-
{
|
|
878
|
-
match: /"(?:\\["\\]|[^\r\n"\\])+"/,
|
|
879
|
-
value: (x)=>x.slice(1, -1).replace(/\\(["\\])/g, "$1")
|
|
880
|
-
}
|
|
881
|
-
]
|
|
882
|
-
}
|
|
883
|
-
});
|
|
884
|
-
}
|
|
885
|
-
_nextNode(lexer, i = 0) {
|
|
886
|
-
let node = null;
|
|
887
|
-
for (const token of lexer){
|
|
888
|
-
// Ignore whitespaces
|
|
889
|
-
if (token.type === "whitespace") {
|
|
890
|
-
continue;
|
|
891
|
-
}
|
|
892
|
-
// rparen = end of group
|
|
893
|
-
if (token.type === "rparen") {
|
|
894
|
-
break;
|
|
895
|
-
}
|
|
896
|
-
// Handle argument
|
|
897
|
-
if (token.type === "argument") {
|
|
898
|
-
if (!node) {
|
|
899
|
-
throw new TaskSyntaxError(lexer.formatError(token, "Unexpected argument"));
|
|
900
|
-
} else if (TaskExpressionService.isTaskNode(node)) {
|
|
901
|
-
node.args.push(token.value);
|
|
902
|
-
} else {
|
|
903
|
-
const lastTask = node.tasks[node.tasks.length - 1];
|
|
904
|
-
if (!lastTask || !TaskExpressionService.isTaskNode(lastTask)) {
|
|
905
|
-
throw new TaskSyntaxError(lexer.formatError(token, "Unexpected argument"));
|
|
906
|
-
} else {
|
|
907
|
-
lastTask.args.push(token.value);
|
|
908
|
-
}
|
|
909
|
-
}
|
|
910
|
-
continue;
|
|
911
|
-
}
|
|
912
|
-
// Handle operator
|
|
913
|
-
if (token.type === "operator") {
|
|
914
|
-
const operator = token.value;
|
|
915
|
-
if (!node) {
|
|
916
|
-
throw new TaskSyntaxError(lexer.formatError(token, "Unexpected operator"));
|
|
917
|
-
} else if (TaskExpressionService.isTaskNode(node)) {
|
|
918
|
-
node = {
|
|
919
|
-
operator,
|
|
920
|
-
tasks: [
|
|
921
|
-
node
|
|
922
|
-
]
|
|
923
|
-
};
|
|
924
|
-
continue;
|
|
925
|
-
} else {
|
|
926
|
-
if (node.operator !== operator) {
|
|
927
|
-
node = {
|
|
928
|
-
operator,
|
|
929
|
-
tasks: [
|
|
930
|
-
node
|
|
931
|
-
]
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
continue;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
// Build "child"
|
|
938
|
-
let child;
|
|
939
|
-
if (token.type === "script") {
|
|
940
|
-
child = {
|
|
941
|
-
script: token.value,
|
|
942
|
-
args: []
|
|
943
|
-
};
|
|
944
|
-
} else if (token.type === "string") {
|
|
945
|
-
const [script, ...args] = token.value.split(/ +/);
|
|
946
|
-
child = {
|
|
947
|
-
script,
|
|
948
|
-
args
|
|
949
|
-
};
|
|
950
|
-
} else if (token.type === "lparen") {
|
|
951
|
-
const res = this._nextNode(lexer, i + 1);
|
|
952
|
-
if (!res) {
|
|
953
|
-
throw new TaskSyntaxError(lexer.formatError(token, "Empty group found"));
|
|
954
|
-
}
|
|
955
|
-
child = res;
|
|
956
|
-
} else {
|
|
957
|
-
throw new TaskSyntaxError(lexer.formatError(token, "Unexpected token"));
|
|
958
|
-
}
|
|
959
|
-
if (!node) {
|
|
960
|
-
node = child;
|
|
961
|
-
} else if (TaskExpressionService.isTaskNode(node)) {
|
|
962
|
-
throw new TaskSyntaxError(lexer.formatError(token, "Unexpected token, expected an operator"));
|
|
963
|
-
} else {
|
|
964
|
-
node.tasks.push(child);
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
return node;
|
|
968
|
-
}
|
|
969
|
-
parse(expr) {
|
|
970
|
-
const lexer = this._lexer().reset(expr);
|
|
971
|
-
const tree = {
|
|
972
|
-
roots: []
|
|
973
|
-
};
|
|
974
|
-
// eslint-disable-next-line no-constant-condition
|
|
975
|
-
while(true){
|
|
976
|
-
const node = this._nextNode(lexer);
|
|
977
|
-
if (node) {
|
|
978
|
-
tree.roots.push(node);
|
|
979
|
-
} else {
|
|
980
|
-
break;
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
return tree;
|
|
984
|
-
}
|
|
985
|
-
*extractScripts(node) {
|
|
986
|
-
if ("roots" in node) {
|
|
987
|
-
for (const child of node.roots){
|
|
988
|
-
yield* this.extractScripts(child);
|
|
989
|
-
}
|
|
990
|
-
} else if (TaskExpressionService.isTaskNode(node)) {
|
|
991
|
-
yield node.script;
|
|
992
|
-
} else {
|
|
993
|
-
for (const child of node.tasks){
|
|
994
|
-
yield* this.extractScripts(child);
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
async buildTask(node, workspace, opts) {
|
|
999
|
-
if (TaskExpressionService.isTaskNode(node)) {
|
|
1000
|
-
const task = await workspace.run(node.script, node.args, opts);
|
|
1001
|
-
if (!task) {
|
|
1002
|
-
throw new TaskExpressionError(`Workspace ${workspace.name} have no ${node.script} script`);
|
|
1003
|
-
}
|
|
1004
|
-
return task;
|
|
1005
|
-
} else {
|
|
1006
|
-
let group;
|
|
1007
|
-
if (node.operator === "//") {
|
|
1008
|
-
group = new ParallelGroup("In parallel", {
|
|
1009
|
-
workspace
|
|
1010
|
-
}, {
|
|
1011
|
-
logger: this._logger
|
|
1012
|
-
});
|
|
1013
|
-
} else if (node.operator === "||") {
|
|
1014
|
-
group = new FallbackGroup("Fallbacks", {
|
|
1015
|
-
workspace
|
|
1016
|
-
}, {
|
|
1017
|
-
logger: this._logger
|
|
1018
|
-
});
|
|
1019
|
-
} else {
|
|
1020
|
-
if (node.operator === "->" && TaskExpressionService._sequenceOperatorWarn) {
|
|
1021
|
-
this._logger.warn("Sequence operator -> is deprecated in favor of &&. It will be removed in a next major release.");
|
|
1022
|
-
TaskExpressionService._sequenceOperatorWarn = true;
|
|
1023
|
-
}
|
|
1024
|
-
group = new SequenceGroup("In sequence", {
|
|
1025
|
-
workspace
|
|
1026
|
-
}, {
|
|
1027
|
-
logger: this._logger
|
|
1028
|
-
});
|
|
1029
|
-
}
|
|
1030
|
-
for (const child of node.tasks){
|
|
1031
|
-
group.add(await this.buildTask(child, workspace, opts));
|
|
1032
|
-
}
|
|
1033
|
-
return group;
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
TaskExpressionService = _([
|
|
1038
|
-
Service(),
|
|
1039
|
-
_$1(0, inject(Logger))
|
|
1040
|
-
], TaskExpressionService);
|
|
1041
|
-
|
|
1042
|
-
// Utils
|
|
1043
|
-
const style = (dev)=>({
|
|
1044
|
-
color: dev ? "blue" : ""
|
|
1045
|
-
});
|
|
1046
|
-
// Component
|
|
1047
|
-
function WorkspaceTree(props) {
|
|
1048
|
-
const { workspace: wks, dev = false, level = "" } = props;
|
|
1049
|
-
// State
|
|
1050
|
-
const [deps, setDeps] = useState([]);
|
|
1051
|
-
// Effects
|
|
1052
|
-
useEffect(()=>void (async ()=>{
|
|
1053
|
-
const deps = [];
|
|
1054
|
-
for await (const dep of wks.dependencies()){
|
|
1055
|
-
deps.push([
|
|
1056
|
-
dep,
|
|
1057
|
-
null
|
|
1058
|
-
]);
|
|
1059
|
-
}
|
|
1060
|
-
for await (const dep of wks.devDependencies()){
|
|
1061
|
-
deps.push([
|
|
1062
|
-
dep,
|
|
1063
|
-
true
|
|
1064
|
-
]);
|
|
1065
|
-
}
|
|
1066
|
-
setDeps(deps);
|
|
1067
|
-
})(), [
|
|
1068
|
-
wks
|
|
1069
|
-
]);
|
|
1070
|
-
// Render
|
|
1071
|
-
return /*#__PURE__*/ jsxs(Text, {
|
|
1072
|
-
children: [
|
|
1073
|
-
/*#__PURE__*/ jsx(Text, {
|
|
1074
|
-
...style(dev),
|
|
1075
|
-
children: wks.name
|
|
1076
|
-
}),
|
|
1077
|
-
wks.version && /*#__PURE__*/ jsxs(Text, {
|
|
1078
|
-
color: "grey",
|
|
1079
|
-
children: [
|
|
1080
|
-
"@",
|
|
1081
|
-
wks.version
|
|
1082
|
-
]
|
|
1083
|
-
}),
|
|
1084
|
-
deps.length > 0 && /*#__PURE__*/ jsx(Newline, {}),
|
|
1085
|
-
deps.map(([dep, isDev], idx)=>/*#__PURE__*/ jsxs(Text, {
|
|
1086
|
-
children: [
|
|
1087
|
-
level,
|
|
1088
|
-
/*#__PURE__*/ jsxs(Text, {
|
|
1089
|
-
...style(dev),
|
|
1090
|
-
children: [
|
|
1091
|
-
idx === deps.length - 1 ? "└" : "├",
|
|
1092
|
-
"─",
|
|
1093
|
-
" "
|
|
1094
|
-
]
|
|
1095
|
-
}),
|
|
1096
|
-
/*#__PURE__*/ jsx(WorkspaceTree, {
|
|
1097
|
-
workspace: dep,
|
|
1098
|
-
dev: isDev ?? dev,
|
|
1099
|
-
level: /*#__PURE__*/ jsxs(Fragment, {
|
|
1100
|
-
children: [
|
|
1101
|
-
level,
|
|
1102
|
-
/*#__PURE__*/ jsxs(Text, {
|
|
1103
|
-
...style(dev),
|
|
1104
|
-
children: [
|
|
1105
|
-
idx === deps.length - 1 ? " " : "│",
|
|
1106
|
-
" "
|
|
1107
|
-
]
|
|
1108
|
-
})
|
|
1109
|
-
]
|
|
1110
|
-
})
|
|
1111
|
-
}),
|
|
1112
|
-
idx < deps.length - 1 && /*#__PURE__*/ jsx(Newline, {})
|
|
1113
|
-
]
|
|
1114
|
-
}, dep.name))
|
|
1115
|
-
]
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
export { AffectedFilter as A, GitService as G, LoadProject as L, Pipeline as P, ScriptsFilter as S, TaskExpressionService as T, WorkspaceTree as W, PrivateFilter as a, LazyCurrentProject as b, LoadWorkspace as c, LazyCurrentWorkspace as d, PluginModule as e, Plugin as f, Project as g, ProjectRepository as h, Workspace as i, combine as j, TaskExpressionError as k, TaskSyntaxError as l, streamLines as s };
|
|
1120
|
-
//# sourceMappingURL=workspace-tree-CyjZrimj.js.map
|