@enspirit/emb 0.5.1 → 0.5.3
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 +83 -3
- package/dist/src/cli/commands/components/logs.js +4 -3
- package/dist/src/cli/commands/restart.d.ts +14 -0
- package/dist/src/cli/commands/restart.js +38 -0
- package/dist/src/cli/commands/stop.d.ts +8 -0
- package/dist/src/cli/commands/stop.js +22 -0
- package/dist/src/cli/commands/tasks/index.js +1 -1
- package/dist/src/cli/commands/tasks/run.d.ts +1 -0
- package/dist/src/cli/commands/tasks/run.js +1 -0
- package/dist/src/config/schema.d.ts +6 -0
- package/dist/src/config/schema.json +7 -0
- package/dist/src/docker/compose/operations/ComposeExecOperation.d.ts +1 -0
- package/dist/src/docker/compose/operations/ComposeExecOperation.js +12 -1
- package/dist/src/docker/compose/operations/ComposeRestartOperation.d.ts +14 -0
- package/dist/src/docker/compose/operations/ComposeRestartOperation.js +46 -0
- package/dist/src/docker/compose/operations/ComposeStopOperation.d.ts +13 -0
- package/dist/src/docker/compose/operations/ComposeStopOperation.js +23 -0
- package/dist/src/docker/compose/operations/index.d.ts +2 -0
- package/dist/src/docker/compose/operations/index.js +2 -0
- package/dist/src/docker/operations/containers/ContainerExecOperation.d.ts +0 -3
- package/dist/src/docker/operations/containers/ContainerExecOperation.js +3 -19
- package/dist/src/monorepo/config.js +1 -1
- package/dist/src/monorepo/operations/resources/BuildResourcesOperation.js +0 -1
- package/dist/src/monorepo/operations/shell/ExecuteLocalCommandOperation.js +1 -0
- package/dist/src/monorepo/operations/tasks/RunTasksOperation.d.ts +5 -1
- package/dist/src/monorepo/operations/tasks/RunTasksOperation.js +20 -4
- package/dist/src/monorepo/types.d.ts +6 -1
- package/dist/src/monorepo/utils/EMBCollection.d.ts +0 -3
- package/dist/src/monorepo/utils/EMBCollection.js +0 -14
- package/dist/src/monorepo/utils/index.d.ts +7 -4
- package/dist/src/monorepo/utils/index.js +14 -8
- package/oclif.manifest.json +123 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @enspirit/emb
|
|
|
14
14
|
$ emb COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ emb (--version)
|
|
17
|
-
@enspirit/emb/0.5.
|
|
17
|
+
@enspirit/emb/0.5.3 darwin-x64 node-v22.18.0
|
|
18
18
|
$ emb --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ emb COMMAND
|
|
@@ -40,7 +40,10 @@ USAGE
|
|
|
40
40
|
* [`emb ps`](#emb-ps)
|
|
41
41
|
* [`emb resources`](#emb-resources)
|
|
42
42
|
* [`emb resources build [COMPONENT]`](#emb-resources-build-component)
|
|
43
|
+
* [`emb restart [COMPONENT]`](#emb-restart-component)
|
|
44
|
+
* [`emb run TASK`](#emb-run-task)
|
|
43
45
|
* [`emb shell COMPONENT`](#emb-shell-component)
|
|
46
|
+
* [`emb stop`](#emb-stop)
|
|
44
47
|
* [`emb tasks`](#emb-tasks)
|
|
45
48
|
* [`emb tasks run TASK`](#emb-tasks-run-task)
|
|
46
49
|
* [`emb up [COMPONENT]`](#emb-up-component)
|
|
@@ -131,7 +134,7 @@ ARGUMENTS
|
|
|
131
134
|
COMPONENT The component you want to see the logs of
|
|
132
135
|
|
|
133
136
|
FLAGS
|
|
134
|
-
-f, --follow Follow log output
|
|
137
|
+
-f, --[no-]follow Follow log output
|
|
135
138
|
|
|
136
139
|
DESCRIPTION
|
|
137
140
|
Get components logs.
|
|
@@ -347,7 +350,7 @@ ARGUMENTS
|
|
|
347
350
|
COMPONENT The component you want to see the logs of
|
|
348
351
|
|
|
349
352
|
FLAGS
|
|
350
|
-
-f, --follow Follow log output
|
|
353
|
+
-f, --[no-]follow Follow log output
|
|
351
354
|
|
|
352
355
|
DESCRIPTION
|
|
353
356
|
Get components logs.
|
|
@@ -430,6 +433,59 @@ EXAMPLES
|
|
|
430
433
|
$ emb resources build build --flavor development
|
|
431
434
|
```
|
|
432
435
|
|
|
436
|
+
## `emb restart [COMPONENT]`
|
|
437
|
+
|
|
438
|
+
Restart the whole project.
|
|
439
|
+
|
|
440
|
+
```
|
|
441
|
+
USAGE
|
|
442
|
+
$ emb restart [COMPONENT...] [--json] [-f]
|
|
443
|
+
|
|
444
|
+
ARGUMENTS
|
|
445
|
+
COMPONENT... The component(s) to restart
|
|
446
|
+
|
|
447
|
+
FLAGS
|
|
448
|
+
-f, --no-deps Don't restart depdendent components
|
|
449
|
+
|
|
450
|
+
GLOBAL FLAGS
|
|
451
|
+
--json Format output as json.
|
|
452
|
+
|
|
453
|
+
DESCRIPTION
|
|
454
|
+
Restart the whole project.
|
|
455
|
+
|
|
456
|
+
EXAMPLES
|
|
457
|
+
$ emb restart
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
## `emb run TASK`
|
|
461
|
+
|
|
462
|
+
Run tasks.
|
|
463
|
+
|
|
464
|
+
```
|
|
465
|
+
USAGE
|
|
466
|
+
$ emb run TASK... [--json] [-x container|local] [-a]
|
|
467
|
+
|
|
468
|
+
ARGUMENTS
|
|
469
|
+
TASK... List of tasks to run. You can provide either ids or names (eg: component:task or task)
|
|
470
|
+
|
|
471
|
+
FLAGS
|
|
472
|
+
-a, --all-matching Run all tasks matching (when multiple matches)
|
|
473
|
+
-x, --executor=<option> Where to run the task. (experimental!)
|
|
474
|
+
<options: container|local>
|
|
475
|
+
|
|
476
|
+
GLOBAL FLAGS
|
|
477
|
+
--json Format output as json.
|
|
478
|
+
|
|
479
|
+
DESCRIPTION
|
|
480
|
+
Run tasks.
|
|
481
|
+
|
|
482
|
+
ALIASES
|
|
483
|
+
$ emb run
|
|
484
|
+
|
|
485
|
+
EXAMPLES
|
|
486
|
+
$ emb run
|
|
487
|
+
```
|
|
488
|
+
|
|
433
489
|
## `emb shell COMPONENT`
|
|
434
490
|
|
|
435
491
|
Get a shell on a running component.
|
|
@@ -454,6 +510,27 @@ EXAMPLES
|
|
|
454
510
|
$ emb shell
|
|
455
511
|
```
|
|
456
512
|
|
|
513
|
+
## `emb stop`
|
|
514
|
+
|
|
515
|
+
Stop the whole project.
|
|
516
|
+
|
|
517
|
+
```
|
|
518
|
+
USAGE
|
|
519
|
+
$ emb stop [--json] [--flavor <value>]
|
|
520
|
+
|
|
521
|
+
FLAGS
|
|
522
|
+
--flavor=<value> Specify the flavor to use.
|
|
523
|
+
|
|
524
|
+
GLOBAL FLAGS
|
|
525
|
+
--json Format output as json.
|
|
526
|
+
|
|
527
|
+
DESCRIPTION
|
|
528
|
+
Stop the whole project.
|
|
529
|
+
|
|
530
|
+
EXAMPLES
|
|
531
|
+
$ emb stop
|
|
532
|
+
```
|
|
533
|
+
|
|
457
534
|
## `emb tasks`
|
|
458
535
|
|
|
459
536
|
List tasks.
|
|
@@ -494,6 +571,9 @@ GLOBAL FLAGS
|
|
|
494
571
|
DESCRIPTION
|
|
495
572
|
Run tasks.
|
|
496
573
|
|
|
574
|
+
ALIASES
|
|
575
|
+
$ emb run
|
|
576
|
+
|
|
497
577
|
EXAMPLES
|
|
498
578
|
$ emb tasks run
|
|
499
579
|
```
|
|
@@ -10,8 +10,9 @@ export default class ComponentsLogs extends BaseCommand {
|
|
|
10
10
|
follow: Flags.boolean({
|
|
11
11
|
name: 'follow',
|
|
12
12
|
char: 'f',
|
|
13
|
+
allowNo: true,
|
|
13
14
|
description: 'Follow log output',
|
|
14
|
-
default:
|
|
15
|
+
default: true,
|
|
15
16
|
}),
|
|
16
17
|
};
|
|
17
18
|
static args = {
|
|
@@ -26,11 +27,11 @@ export default class ComponentsLogs extends BaseCommand {
|
|
|
26
27
|
const { monorepo, docker } = await getContext();
|
|
27
28
|
const component = monorepo.component(args.component);
|
|
28
29
|
const containers = await monorepo.run(new ListContainersOperation(), {
|
|
30
|
+
all: true,
|
|
29
31
|
filters: {
|
|
30
32
|
label: [
|
|
31
33
|
`emb/project=${monorepo.name}`,
|
|
32
34
|
`emb/component=${component.name}`,
|
|
33
|
-
`emb/flavor=${monorepo.currentFlavor}`,
|
|
34
35
|
],
|
|
35
36
|
},
|
|
36
37
|
});
|
|
@@ -47,7 +48,7 @@ export default class ComponentsLogs extends BaseCommand {
|
|
|
47
48
|
stderr: true,
|
|
48
49
|
stdout: true,
|
|
49
50
|
});
|
|
50
|
-
|
|
51
|
+
docker.modem.demuxStream(stream, process.stdout, process.stderr);
|
|
51
52
|
}
|
|
52
53
|
else {
|
|
53
54
|
const res = await container.logs({
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../index.js';
|
|
2
|
+
export default class RestartComand extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
'no-deps': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
9
|
+
static args: {
|
|
10
|
+
component: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
static strict: boolean;
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { BaseCommand, getContext } from '../index.js';
|
|
3
|
+
import { ComposeRestartOperation } from '../../docker/index.js';
|
|
4
|
+
export default class RestartComand extends BaseCommand {
|
|
5
|
+
static description = 'Restart the whole project.';
|
|
6
|
+
static enableJsonFlag = true;
|
|
7
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
|
+
static flags = {
|
|
9
|
+
'no-deps': Flags.boolean({
|
|
10
|
+
char: 'f',
|
|
11
|
+
default: false,
|
|
12
|
+
description: "Don't restart depdendent components",
|
|
13
|
+
name: 'no-deps',
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static args = {
|
|
17
|
+
component: Args.string({
|
|
18
|
+
name: 'component',
|
|
19
|
+
description: 'The component(s) to restart',
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
static strict = false;
|
|
23
|
+
async run() {
|
|
24
|
+
const { flags, argv } = await this.parse(RestartComand);
|
|
25
|
+
const { monorepo } = getContext();
|
|
26
|
+
let components;
|
|
27
|
+
if (argv.length > 0) {
|
|
28
|
+
components =
|
|
29
|
+
argv.length > 0
|
|
30
|
+
? argv.map((name) => monorepo.component(name))
|
|
31
|
+
: monorepo.components;
|
|
32
|
+
}
|
|
33
|
+
await monorepo.run(new ComposeRestartOperation(), {
|
|
34
|
+
noDeps: flags['no-deps'],
|
|
35
|
+
services: components?.map((c) => c.name),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FlavoredCommand } from '../index.js';
|
|
2
|
+
export default class StopCommand extends FlavoredCommand<typeof StopCommand> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static enableJsonFlag: boolean;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {};
|
|
7
|
+
run(): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Listr } from 'listr2';
|
|
2
|
+
import { FlavoredCommand, getContext } from '../index.js';
|
|
3
|
+
import { ComposeStopOperation } from '../../docker/index.js';
|
|
4
|
+
export default class StopCommand extends FlavoredCommand {
|
|
5
|
+
static description = 'Stop the whole project.';
|
|
6
|
+
static enableJsonFlag = true;
|
|
7
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
|
+
static flags = {};
|
|
9
|
+
async run() {
|
|
10
|
+
const { monorepo } = getContext();
|
|
11
|
+
const runner = new Listr([
|
|
12
|
+
{
|
|
13
|
+
rendererOptions: { persistentOutput: true },
|
|
14
|
+
async task(ctx, task) {
|
|
15
|
+
return monorepo.run(new ComposeStopOperation(task.stdout()), {});
|
|
16
|
+
},
|
|
17
|
+
title: 'Stopping project',
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
await runner.run();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -20,7 +20,7 @@ export default class TasksIndex extends BaseCommand {
|
|
|
20
20
|
return 1;
|
|
21
21
|
}
|
|
22
22
|
// Compare components (if both not null)
|
|
23
|
-
if (Boolean(ac) && Boolean(bc)) {
|
|
23
|
+
if (ac && bc && Boolean(ac) && Boolean(bc)) {
|
|
24
24
|
const cmp = ac.localeCompare(bc);
|
|
25
25
|
if (cmp !== 0) {
|
|
26
26
|
return cmp;
|
|
@@ -3,6 +3,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
3
3
|
import { BaseCommand } from '../../index.js';
|
|
4
4
|
import { ExecutorType, RunTasksOperation } from '../../../monorepo/index.js';
|
|
5
5
|
export default class RunTask extends BaseCommand {
|
|
6
|
+
static aliases = ['run'];
|
|
6
7
|
static args = {
|
|
7
8
|
task: Args.string({
|
|
8
9
|
description: 'List of tasks to run. You can provide either ids or names (eg: component:task or task)',
|
|
@@ -136,6 +136,13 @@
|
|
|
136
136
|
"items": {
|
|
137
137
|
"$ref": "#/definitions/Identifier"
|
|
138
138
|
}
|
|
139
|
+
},
|
|
140
|
+
"vars": {
|
|
141
|
+
"type": "object",
|
|
142
|
+
"description": "Variables to pass onto the task",
|
|
143
|
+
"additionalProperties": {
|
|
144
|
+
"type": "string"
|
|
145
|
+
}
|
|
139
146
|
}
|
|
140
147
|
},
|
|
141
148
|
"additionalProperties": false
|
|
@@ -3,6 +3,7 @@ import * as z from 'zod';
|
|
|
3
3
|
import { AbstractOperation } from '../../../operations/index.js';
|
|
4
4
|
declare const schema: z.ZodObject<{
|
|
5
5
|
command: z.ZodString;
|
|
6
|
+
env: z.ZodOptional<z.ZodObject<{}, z.core.$catchall<z.ZodString>>>;
|
|
6
7
|
service: z.ZodString;
|
|
7
8
|
}, z.core.$strip>;
|
|
8
9
|
export declare class ComposeExecOperation extends AbstractOperation<typeof schema, void> {
|
|
@@ -4,6 +4,11 @@ import { ComposeExecError } from '../../../errors.js';
|
|
|
4
4
|
import { AbstractOperation } from '../../../operations/index.js';
|
|
5
5
|
const schema = z.object({
|
|
6
6
|
command: z.string().describe('The command to execute on the service'),
|
|
7
|
+
env: z
|
|
8
|
+
.object()
|
|
9
|
+
.catchall(z.string())
|
|
10
|
+
.describe('Environment variables to pass to the execution')
|
|
11
|
+
.optional(),
|
|
7
12
|
service: z
|
|
8
13
|
.string()
|
|
9
14
|
.describe('The name of the compose service to exec a shell'),
|
|
@@ -17,7 +22,13 @@ export class ComposeExecOperation extends AbstractOperation {
|
|
|
17
22
|
async _run(input) {
|
|
18
23
|
const { monorepo } = this.context;
|
|
19
24
|
const cmd = 'docker';
|
|
20
|
-
const args = ['compose', 'exec'
|
|
25
|
+
const args = ['compose', 'exec'];
|
|
26
|
+
// Add any env vars
|
|
27
|
+
Object.entries(input.env || {}).forEach(([key, value]) => {
|
|
28
|
+
args.push('-e', `${key.trim()}=${value.trim()}`);
|
|
29
|
+
});
|
|
30
|
+
// add component and script
|
|
31
|
+
args.push(input.service, input.command);
|
|
21
32
|
const child = spawn(cmd, args, {
|
|
22
33
|
stdio: 'pipe',
|
|
23
34
|
shell: true,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import { AbstractOperation } from '../../../operations/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* https://docs.docker.com/reference/cli/docker/compose/restart/
|
|
5
|
+
*/
|
|
6
|
+
declare const schema: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
services: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
8
|
+
noDeps: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
export declare class ComposeRestartOperation extends AbstractOperation<typeof schema, void> {
|
|
11
|
+
constructor();
|
|
12
|
+
protected _run(input: z.input<typeof schema>): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { getContext } from '../../../index.js';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
import { ExecuteLocalCommandOperation, taskManagerFactory } from '../../../monorepo/index.js';
|
|
4
|
+
import { AbstractOperation } from '../../../operations/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* https://docs.docker.com/reference/cli/docker/compose/restart/
|
|
7
|
+
*/
|
|
8
|
+
const schema = z
|
|
9
|
+
.object({
|
|
10
|
+
services: z
|
|
11
|
+
.array(z.string())
|
|
12
|
+
.optional()
|
|
13
|
+
.describe('The list of service to restart'),
|
|
14
|
+
noDeps: z.boolean().optional().describe("Don't restart dependent services"),
|
|
15
|
+
})
|
|
16
|
+
.optional();
|
|
17
|
+
export class ComposeRestartOperation extends AbstractOperation {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(schema);
|
|
20
|
+
}
|
|
21
|
+
async _run(input) {
|
|
22
|
+
const { monorepo } = getContext();
|
|
23
|
+
const manager = taskManagerFactory();
|
|
24
|
+
const command = ['docker', 'compose', 'restart'];
|
|
25
|
+
if (input?.services) {
|
|
26
|
+
command.push(...input.services);
|
|
27
|
+
}
|
|
28
|
+
if (input?.noDeps) {
|
|
29
|
+
command.push('--no-deps');
|
|
30
|
+
}
|
|
31
|
+
manager.add([
|
|
32
|
+
{
|
|
33
|
+
async task(ctx, task) {
|
|
34
|
+
return monorepo.run(new ExecuteLocalCommandOperation(task.stdout()), {
|
|
35
|
+
script: command.join(' '),
|
|
36
|
+
workingDir: monorepo.rootDir,
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
title: input?.services
|
|
40
|
+
? `Restarting ${input.services.join(', ')}`
|
|
41
|
+
: 'Restarting project',
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
await manager.runAll();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Readable, Writable } from 'node:stream';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
import { AbstractOperation } from '../../../operations/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* https://docs.docker.com/reference/cli/docker/compose/stop/
|
|
6
|
+
*/
|
|
7
|
+
declare const schema: z.ZodOptional<z.ZodObject<{}, z.core.$strip>>;
|
|
8
|
+
export declare class ComposeStopOperation extends AbstractOperation<typeof schema, Readable> {
|
|
9
|
+
protected out: Writable;
|
|
10
|
+
constructor(out: Writable);
|
|
11
|
+
protected _run(_input: z.input<typeof schema>): Promise<Readable>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getContext } from '../../../index.js';
|
|
2
|
+
import * as z from 'zod';
|
|
3
|
+
import { ExecuteLocalCommandOperation } from '../../../monorepo/index.js';
|
|
4
|
+
import { AbstractOperation } from '../../../operations/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* https://docs.docker.com/reference/cli/docker/compose/stop/
|
|
7
|
+
*/
|
|
8
|
+
const schema = z.object({}).optional();
|
|
9
|
+
export class ComposeStopOperation extends AbstractOperation {
|
|
10
|
+
out;
|
|
11
|
+
constructor(out) {
|
|
12
|
+
super(schema);
|
|
13
|
+
this.out = out;
|
|
14
|
+
}
|
|
15
|
+
async _run(_input) {
|
|
16
|
+
const { monorepo } = getContext();
|
|
17
|
+
const command = ['docker', 'compose', 'stop'];
|
|
18
|
+
return monorepo.run(new ExecuteLocalCommandOperation(this.out), {
|
|
19
|
+
script: command.join(' '),
|
|
20
|
+
workingDir: monorepo.rootDir,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './ComposeDownOperation.js';
|
|
2
2
|
export * from './ComposeExecOperation.js';
|
|
3
3
|
export * from './ComposeExecShellOperation.js';
|
|
4
|
+
export * from './ComposeRestartOperation.js';
|
|
5
|
+
export * from './ComposeStopOperation.js';
|
|
4
6
|
export * from './ComposeUpOperation.js';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './ComposeDownOperation.js';
|
|
2
2
|
export * from './ComposeExecOperation.js';
|
|
3
3
|
export * from './ComposeExecShellOperation.js';
|
|
4
|
+
export * from './ComposeRestartOperation.js';
|
|
5
|
+
export * from './ComposeStopOperation.js';
|
|
4
6
|
export * from './ComposeUpOperation.js';
|
|
@@ -5,9 +5,6 @@ import { AbstractOperation } from '../../../operations/index.js';
|
|
|
5
5
|
* https://docs.docker.com/reference/api/engine/version/v1.37/#tag/Exec/operation/ContainerExec
|
|
6
6
|
*/
|
|
7
7
|
declare const schema: z.ZodObject<{
|
|
8
|
-
attachStderr: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
9
|
-
attachStdin: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
10
|
-
attachStdout: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
11
8
|
container: z.ZodString;
|
|
12
9
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
13
10
|
script: z.ZodString;
|
|
@@ -4,21 +4,6 @@ import { AbstractOperation } from '../../../operations/index.js';
|
|
|
4
4
|
* https://docs.docker.com/reference/api/engine/version/v1.37/#tag/Exec/operation/ContainerExec
|
|
5
5
|
*/
|
|
6
6
|
const schema = z.object({
|
|
7
|
-
attachStderr: z
|
|
8
|
-
.boolean()
|
|
9
|
-
.default(false)
|
|
10
|
-
.optional()
|
|
11
|
-
.describe('Attach to `stderr` of the exec command.'),
|
|
12
|
-
attachStdin: z
|
|
13
|
-
.boolean()
|
|
14
|
-
.default(false)
|
|
15
|
-
.optional()
|
|
16
|
-
.describe('Attach to `stdin` of the exec command.'),
|
|
17
|
-
attachStdout: z
|
|
18
|
-
.boolean()
|
|
19
|
-
.default(false)
|
|
20
|
-
.optional()
|
|
21
|
-
.describe('Attach to `stdout` of the exec command.'),
|
|
22
7
|
container: z.string().describe('ID or name of the container'),
|
|
23
8
|
env: z
|
|
24
9
|
.record(z.string(), z.string())
|
|
@@ -43,9 +28,8 @@ export class ContainerExecOperation extends AbstractOperation {
|
|
|
43
28
|
return [...arr, `${key}=${value}`];
|
|
44
29
|
}, []);
|
|
45
30
|
const options = {
|
|
46
|
-
AttachStderr:
|
|
47
|
-
|
|
48
|
-
AttachStdout: input.attachStdout,
|
|
31
|
+
AttachStderr: true,
|
|
32
|
+
AttachStdout: true,
|
|
49
33
|
Cmd: ['bash', '-eu', '-o', 'pipefail', '-c', input.script],
|
|
50
34
|
Env: envVars,
|
|
51
35
|
Tty: input.tty,
|
|
@@ -53,7 +37,7 @@ export class ContainerExecOperation extends AbstractOperation {
|
|
|
53
37
|
};
|
|
54
38
|
const exec = await container.exec(options);
|
|
55
39
|
const stream = await exec.start({});
|
|
56
|
-
|
|
40
|
+
exec.modem.demuxStream(stream, this.out || process.stdout, this.out || process.stderr);
|
|
57
41
|
await new Promise((resolve, reject) => {
|
|
58
42
|
const onError = (err) => reject(err);
|
|
59
43
|
const onEnd = async () => {
|
|
@@ -16,7 +16,7 @@ export class MonorepoConfig {
|
|
|
16
16
|
this.flavors = config.flavors || {};
|
|
17
17
|
this.env = config.env || {};
|
|
18
18
|
this.plugins = config.plugins || [];
|
|
19
|
-
this.tasks = toIdentifedHash(config.tasks || {}
|
|
19
|
+
this.tasks = toIdentifedHash(config.tasks || {});
|
|
20
20
|
this.components = config.components || {};
|
|
21
21
|
}
|
|
22
22
|
component(id) {
|
|
@@ -34,7 +34,6 @@ export class BuildResourcesOperation extends AbstractOperation {
|
|
|
34
34
|
const collection = new EMBCollection(monorepo.resources, {
|
|
35
35
|
idField: 'id',
|
|
36
36
|
depField: 'dependencies',
|
|
37
|
-
forbidIdNameCollision: true,
|
|
38
37
|
});
|
|
39
38
|
const ordered = findRunOrder(input.resources || [], collection);
|
|
40
39
|
const tasks = ordered.map((resource) => {
|
|
@@ -13,8 +13,12 @@ export type RunTasksOperationParams = {
|
|
|
13
13
|
export type TaskWithScript = TaskInfo & {
|
|
14
14
|
script: string;
|
|
15
15
|
};
|
|
16
|
+
export type TaskWithScriptAndComponent = TaskInfo & {
|
|
17
|
+
script: string;
|
|
18
|
+
component: string;
|
|
19
|
+
};
|
|
16
20
|
export declare class RunTasksOperation implements IOperation<RunTasksOperationParams, Array<TaskInfo>> {
|
|
17
21
|
run(params: RunTasksOperationParams): Promise<Array<TaskInfo>>;
|
|
18
|
-
protected runDocker(task:
|
|
22
|
+
protected runDocker(task: TaskWithScriptAndComponent, out?: Writable): Promise<void>;
|
|
19
23
|
protected runLocal(task: TaskWithScript, out: Writable): Promise<import("stream").Readable>;
|
|
20
24
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getContext } from '../../../index.js';
|
|
2
2
|
import { PassThrough } from 'node:stream';
|
|
3
|
-
import {
|
|
3
|
+
import { ContainerExecOperation, ListContainersOperation } from '../../../docker/index.js';
|
|
4
4
|
import { EMBCollection, findRunOrder, taskManagerFactory, } from '../../index.js';
|
|
5
5
|
import { ExecuteLocalCommandOperation } from '../index.js';
|
|
6
6
|
export var ExecutorType;
|
|
@@ -58,9 +58,24 @@ export class RunTasksOperation {
|
|
|
58
58
|
}
|
|
59
59
|
async runDocker(task, out) {
|
|
60
60
|
const { monorepo } = getContext();
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
const containers = await monorepo.run(new ListContainersOperation(), {
|
|
62
|
+
filters: {
|
|
63
|
+
label: [
|
|
64
|
+
`emb/project=${monorepo.name}`,
|
|
65
|
+
`emb/component=${task.component}`,
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
if (containers.length === 0) {
|
|
70
|
+
throw new Error(`No container found for component \`${task.component}\``);
|
|
71
|
+
}
|
|
72
|
+
if (containers.length > 1) {
|
|
73
|
+
throw new Error(`More than one container found for component \`${task.component}\``);
|
|
74
|
+
}
|
|
75
|
+
return monorepo.run(new ContainerExecOperation(out), {
|
|
76
|
+
container: containers[0].Id,
|
|
77
|
+
script: task.script,
|
|
78
|
+
env: await monorepo.expand(task.vars || {}),
|
|
64
79
|
});
|
|
65
80
|
}
|
|
66
81
|
async runLocal(task, out) {
|
|
@@ -71,6 +86,7 @@ export class RunTasksOperation {
|
|
|
71
86
|
return monorepo.run(new ExecuteLocalCommandOperation(out), {
|
|
72
87
|
script: task.script,
|
|
73
88
|
workingDir: cwd,
|
|
89
|
+
env: await monorepo.expand(task.vars || {}),
|
|
74
90
|
});
|
|
75
91
|
}
|
|
76
92
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { ComponentFlavorConfig, IResourceConfig, ProjectFlavorConfig, TaskConfig } from '../config/types.js';
|
|
2
|
+
export type MaybeComponentIdentifiable<T> = T & {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
component?: string;
|
|
6
|
+
};
|
|
2
7
|
export type ComponentIdentifiable<T> = T & {
|
|
3
8
|
id: string;
|
|
4
9
|
name: string;
|
|
@@ -17,7 +22,7 @@ export type ComponentFlavorInfo = ComponentIdentifiable<ComponentFlavorConfig>;
|
|
|
17
22
|
export type ComponentFlavors = {
|
|
18
23
|
[k: string]: ComponentFlavorInfo;
|
|
19
24
|
};
|
|
20
|
-
export type TaskInfo =
|
|
25
|
+
export type TaskInfo = MaybeComponentIdentifiable<TaskConfig>;
|
|
21
26
|
export type Tasks = {
|
|
22
27
|
[k: string]: TaskInfo;
|
|
23
28
|
};
|
|
@@ -2,8 +2,6 @@ import { DepList } from './types.js';
|
|
|
2
2
|
export type CollectionConfig<IDK extends PropertyKey, DPK extends PropertyKey> = {
|
|
3
3
|
idField: IDK;
|
|
4
4
|
depField: DPK;
|
|
5
|
-
/** If true, throw when an item's id equals some other item's name (or vice versa). */
|
|
6
|
-
forbidIdNameCollision?: boolean;
|
|
7
5
|
};
|
|
8
6
|
export declare class EMBCollection<T extends Partial<Record<DPK, DepList>> & Record<IDK, string> & {
|
|
9
7
|
name: string;
|
|
@@ -11,7 +9,6 @@ export declare class EMBCollection<T extends Partial<Record<DPK, DepList>> & Rec
|
|
|
11
9
|
private items;
|
|
12
10
|
readonly idField: IDK;
|
|
13
11
|
readonly depField: DPK;
|
|
14
|
-
readonly forbidIdNameCollision: boolean;
|
|
15
12
|
private byId;
|
|
16
13
|
private byName;
|
|
17
14
|
constructor(items: Iterable<T>, cfg: CollectionConfig<IDK, DPK>);
|
|
@@ -3,7 +3,6 @@ export class EMBCollection {
|
|
|
3
3
|
items;
|
|
4
4
|
idField;
|
|
5
5
|
depField;
|
|
6
|
-
forbidIdNameCollision;
|
|
7
6
|
//
|
|
8
7
|
byId;
|
|
9
8
|
byName;
|
|
@@ -11,7 +10,6 @@ export class EMBCollection {
|
|
|
11
10
|
this.items = [];
|
|
12
11
|
this.idField = cfg.idField;
|
|
13
12
|
this.depField = cfg.depField;
|
|
14
|
-
this.forbidIdNameCollision = cfg.forbidIdNameCollision ?? true;
|
|
15
13
|
this.byId = new Map();
|
|
16
14
|
this.byName = new Map();
|
|
17
15
|
// single-pass validation state
|
|
@@ -32,18 +30,6 @@ export class EMBCollection {
|
|
|
32
30
|
this.byId.set(id, t);
|
|
33
31
|
seenIds.add(id);
|
|
34
32
|
}
|
|
35
|
-
// --- Optional validation: forbid id <-> name collisions ---
|
|
36
|
-
if (this.forbidIdNameCollision) {
|
|
37
|
-
if (seenNames.has(id)) {
|
|
38
|
-
const nameOwners = this.byName.get(id) ?? [];
|
|
39
|
-
const ownerIds = nameOwners.map((o) => o[this.idField]).join(', ');
|
|
40
|
-
collisions.push(`value \`${id}\` is an id of \`${name}\` and also a name of item(s) with id(s): [${ownerIds}]`);
|
|
41
|
-
}
|
|
42
|
-
if (seenIds.has(name)) {
|
|
43
|
-
const idOwner = this.byId.get(name);
|
|
44
|
-
collisions.push(`value \`${name}\` is a name of \`${t.name}\` and also an id of \`${idOwner.name}\``);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
33
|
// byName index
|
|
48
34
|
const list = this.byName.get(name);
|
|
49
35
|
if (list) {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { ComponentIdentifiable } from '../../index.js';
|
|
1
|
+
import { ComponentIdentifiable, MaybeComponentIdentifiable } from '../../index.js';
|
|
2
2
|
export * from './EMBCollection.js';
|
|
3
3
|
export * from './graph.js';
|
|
4
4
|
export * from './types.js';
|
|
5
|
-
export declare
|
|
6
|
-
[
|
|
7
|
-
}
|
|
5
|
+
export declare function toIdentifedHash<V, T extends Record<string, V>>(hash: T, parentName: string): {
|
|
6
|
+
[K in keyof T]: ComponentIdentifiable<T[K]>;
|
|
7
|
+
};
|
|
8
|
+
export declare function toIdentifedHash<V, T extends Record<string, V>>(hash: T, parentName?: undefined): {
|
|
9
|
+
[K in keyof T]: MaybeComponentIdentifiable<T[K]>;
|
|
10
|
+
};
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
export * from './EMBCollection.js';
|
|
2
2
|
export * from './graph.js';
|
|
3
3
|
export * from './types.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
// implementation
|
|
5
|
+
export function toIdentifedHash(hash, parentName) {
|
|
6
|
+
const out = {};
|
|
7
|
+
for (const key in hash) {
|
|
8
|
+
if (!Object.hasOwn(hash, key)) {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
11
|
+
const value = hash[key];
|
|
12
|
+
out[key] = {
|
|
7
13
|
...value,
|
|
8
|
-
id: `${parentName}:${key}
|
|
14
|
+
id: parentName ? `${parentName}:${key}` : key,
|
|
9
15
|
name: key,
|
|
10
|
-
component: parentName,
|
|
16
|
+
...(parentName ? { component: parentName } : {}),
|
|
11
17
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -80,6 +80,91 @@
|
|
|
80
80
|
"down.js"
|
|
81
81
|
]
|
|
82
82
|
},
|
|
83
|
+
"restart": {
|
|
84
|
+
"aliases": [],
|
|
85
|
+
"args": {
|
|
86
|
+
"component": {
|
|
87
|
+
"description": "The component(s) to restart",
|
|
88
|
+
"name": "component"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"description": "Restart the whole project.",
|
|
92
|
+
"examples": [
|
|
93
|
+
"<%= config.bin %> <%= command.id %>"
|
|
94
|
+
],
|
|
95
|
+
"flags": {
|
|
96
|
+
"json": {
|
|
97
|
+
"description": "Format output as json.",
|
|
98
|
+
"helpGroup": "GLOBAL",
|
|
99
|
+
"name": "json",
|
|
100
|
+
"allowNo": false,
|
|
101
|
+
"type": "boolean"
|
|
102
|
+
},
|
|
103
|
+
"no-deps": {
|
|
104
|
+
"char": "f",
|
|
105
|
+
"description": "Don't restart depdendent components",
|
|
106
|
+
"name": "no-deps",
|
|
107
|
+
"allowNo": false,
|
|
108
|
+
"type": "boolean"
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"hasDynamicHelp": false,
|
|
112
|
+
"hiddenAliases": [],
|
|
113
|
+
"id": "restart",
|
|
114
|
+
"pluginAlias": "@enspirit/emb",
|
|
115
|
+
"pluginName": "@enspirit/emb",
|
|
116
|
+
"pluginType": "core",
|
|
117
|
+
"strict": false,
|
|
118
|
+
"enableJsonFlag": true,
|
|
119
|
+
"isESM": true,
|
|
120
|
+
"relativePath": [
|
|
121
|
+
"dist",
|
|
122
|
+
"src",
|
|
123
|
+
"cli",
|
|
124
|
+
"commands",
|
|
125
|
+
"restart.js"
|
|
126
|
+
]
|
|
127
|
+
},
|
|
128
|
+
"stop": {
|
|
129
|
+
"aliases": [],
|
|
130
|
+
"args": {},
|
|
131
|
+
"description": "Stop the whole project.",
|
|
132
|
+
"examples": [
|
|
133
|
+
"<%= config.bin %> <%= command.id %>"
|
|
134
|
+
],
|
|
135
|
+
"flags": {
|
|
136
|
+
"json": {
|
|
137
|
+
"description": "Format output as json.",
|
|
138
|
+
"helpGroup": "GLOBAL",
|
|
139
|
+
"name": "json",
|
|
140
|
+
"allowNo": false,
|
|
141
|
+
"type": "boolean"
|
|
142
|
+
},
|
|
143
|
+
"flavor": {
|
|
144
|
+
"description": "Specify the flavor to use.",
|
|
145
|
+
"name": "flavor",
|
|
146
|
+
"required": false,
|
|
147
|
+
"hasDynamicHelp": false,
|
|
148
|
+
"multiple": false,
|
|
149
|
+
"type": "option"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"hasDynamicHelp": false,
|
|
153
|
+
"hiddenAliases": [],
|
|
154
|
+
"id": "stop",
|
|
155
|
+
"pluginAlias": "@enspirit/emb",
|
|
156
|
+
"pluginName": "@enspirit/emb",
|
|
157
|
+
"pluginType": "core",
|
|
158
|
+
"enableJsonFlag": true,
|
|
159
|
+
"isESM": true,
|
|
160
|
+
"relativePath": [
|
|
161
|
+
"dist",
|
|
162
|
+
"src",
|
|
163
|
+
"cli",
|
|
164
|
+
"commands",
|
|
165
|
+
"stop.js"
|
|
166
|
+
]
|
|
167
|
+
},
|
|
83
168
|
"up": {
|
|
84
169
|
"aliases": [],
|
|
85
170
|
"args": {
|
|
@@ -194,7 +279,7 @@
|
|
|
194
279
|
"char": "f",
|
|
195
280
|
"description": "Follow log output",
|
|
196
281
|
"name": "follow",
|
|
197
|
-
"allowNo":
|
|
282
|
+
"allowNo": true,
|
|
198
283
|
"type": "boolean"
|
|
199
284
|
}
|
|
200
285
|
},
|
|
@@ -260,12 +345,10 @@
|
|
|
260
345
|
"shell.js"
|
|
261
346
|
]
|
|
262
347
|
},
|
|
263
|
-
"
|
|
264
|
-
"aliases": [
|
|
265
|
-
"ps"
|
|
266
|
-
],
|
|
348
|
+
"config:print": {
|
|
349
|
+
"aliases": [],
|
|
267
350
|
"args": {},
|
|
268
|
-
"description": "
|
|
351
|
+
"description": "Print the current config.",
|
|
269
352
|
"examples": [
|
|
270
353
|
"<%= config.bin %> <%= command.id %>"
|
|
271
354
|
],
|
|
@@ -277,22 +360,21 @@
|
|
|
277
360
|
"allowNo": false,
|
|
278
361
|
"type": "boolean"
|
|
279
362
|
},
|
|
280
|
-
"
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"name": "all",
|
|
363
|
+
"flavor": {
|
|
364
|
+
"description": "Specify the flavor to use.",
|
|
365
|
+
"name": "flavor",
|
|
284
366
|
"required": false,
|
|
285
|
-
"
|
|
286
|
-
"
|
|
367
|
+
"hasDynamicHelp": false,
|
|
368
|
+
"multiple": false,
|
|
369
|
+
"type": "option"
|
|
287
370
|
}
|
|
288
371
|
},
|
|
289
372
|
"hasDynamicHelp": false,
|
|
290
373
|
"hiddenAliases": [],
|
|
291
|
-
"id": "
|
|
374
|
+
"id": "config:print",
|
|
292
375
|
"pluginAlias": "@enspirit/emb",
|
|
293
376
|
"pluginName": "@enspirit/emb",
|
|
294
377
|
"pluginType": "core",
|
|
295
|
-
"strict": true,
|
|
296
378
|
"enableJsonFlag": true,
|
|
297
379
|
"isESM": true,
|
|
298
380
|
"relativePath": [
|
|
@@ -300,14 +382,16 @@
|
|
|
300
382
|
"src",
|
|
301
383
|
"cli",
|
|
302
384
|
"commands",
|
|
303
|
-
"
|
|
304
|
-
"
|
|
385
|
+
"config",
|
|
386
|
+
"print.js"
|
|
305
387
|
]
|
|
306
388
|
},
|
|
307
|
-
"containers
|
|
308
|
-
"aliases": [
|
|
389
|
+
"containers": {
|
|
390
|
+
"aliases": [
|
|
391
|
+
"ps"
|
|
392
|
+
],
|
|
309
393
|
"args": {},
|
|
310
|
-
"description": "
|
|
394
|
+
"description": "List docker containers.",
|
|
311
395
|
"examples": [
|
|
312
396
|
"<%= config.bin %> <%= command.id %>"
|
|
313
397
|
],
|
|
@@ -318,11 +402,19 @@
|
|
|
318
402
|
"name": "json",
|
|
319
403
|
"allowNo": false,
|
|
320
404
|
"type": "boolean"
|
|
405
|
+
},
|
|
406
|
+
"all": {
|
|
407
|
+
"char": "a",
|
|
408
|
+
"description": "Retun all containers. By default, only running containers are shown",
|
|
409
|
+
"name": "all",
|
|
410
|
+
"required": false,
|
|
411
|
+
"allowNo": false,
|
|
412
|
+
"type": "boolean"
|
|
321
413
|
}
|
|
322
414
|
},
|
|
323
415
|
"hasDynamicHelp": false,
|
|
324
416
|
"hiddenAliases": [],
|
|
325
|
-
"id": "containers
|
|
417
|
+
"id": "containers",
|
|
326
418
|
"pluginAlias": "@enspirit/emb",
|
|
327
419
|
"pluginName": "@enspirit/emb",
|
|
328
420
|
"pluginType": "core",
|
|
@@ -335,13 +427,13 @@
|
|
|
335
427
|
"cli",
|
|
336
428
|
"commands",
|
|
337
429
|
"containers",
|
|
338
|
-
"
|
|
430
|
+
"index.js"
|
|
339
431
|
]
|
|
340
432
|
},
|
|
341
|
-
"
|
|
433
|
+
"containers:prune": {
|
|
342
434
|
"aliases": [],
|
|
343
435
|
"args": {},
|
|
344
|
-
"description": "
|
|
436
|
+
"description": "Prune containers.",
|
|
345
437
|
"examples": [
|
|
346
438
|
"<%= config.bin %> <%= command.id %>"
|
|
347
439
|
],
|
|
@@ -352,22 +444,15 @@
|
|
|
352
444
|
"name": "json",
|
|
353
445
|
"allowNo": false,
|
|
354
446
|
"type": "boolean"
|
|
355
|
-
},
|
|
356
|
-
"flavor": {
|
|
357
|
-
"description": "Specify the flavor to use.",
|
|
358
|
-
"name": "flavor",
|
|
359
|
-
"required": false,
|
|
360
|
-
"hasDynamicHelp": false,
|
|
361
|
-
"multiple": false,
|
|
362
|
-
"type": "option"
|
|
363
447
|
}
|
|
364
448
|
},
|
|
365
449
|
"hasDynamicHelp": false,
|
|
366
450
|
"hiddenAliases": [],
|
|
367
|
-
"id": "
|
|
451
|
+
"id": "containers:prune",
|
|
368
452
|
"pluginAlias": "@enspirit/emb",
|
|
369
453
|
"pluginName": "@enspirit/emb",
|
|
370
454
|
"pluginType": "core",
|
|
455
|
+
"strict": true,
|
|
371
456
|
"enableJsonFlag": true,
|
|
372
457
|
"isESM": true,
|
|
373
458
|
"relativePath": [
|
|
@@ -375,8 +460,8 @@
|
|
|
375
460
|
"src",
|
|
376
461
|
"cli",
|
|
377
462
|
"commands",
|
|
378
|
-
"
|
|
379
|
-
"
|
|
463
|
+
"containers",
|
|
464
|
+
"prune.js"
|
|
380
465
|
]
|
|
381
466
|
},
|
|
382
467
|
"images:delete": {
|
|
@@ -651,7 +736,9 @@
|
|
|
651
736
|
]
|
|
652
737
|
},
|
|
653
738
|
"tasks:run": {
|
|
654
|
-
"aliases": [
|
|
739
|
+
"aliases": [
|
|
740
|
+
"run"
|
|
741
|
+
],
|
|
655
742
|
"args": {
|
|
656
743
|
"task": {
|
|
657
744
|
"description": "List of tasks to run. You can provide either ids or names (eg: component:task or task)",
|
|
@@ -710,5 +797,5 @@
|
|
|
710
797
|
]
|
|
711
798
|
}
|
|
712
799
|
},
|
|
713
|
-
"version": "0.5.
|
|
800
|
+
"version": "0.5.3"
|
|
714
801
|
}
|