@enspirit/emb 0.5.2 → 0.6.0

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 (56) hide show
  1. package/README.md +87 -3
  2. package/dist/src/cli/abstract/BaseCommand.js +3 -1
  3. package/dist/src/cli/commands/components/logs.js +7 -19
  4. package/dist/src/cli/commands/images/push.d.ts +11 -0
  5. package/dist/src/cli/commands/images/push.js +29 -0
  6. package/dist/src/cli/commands/resources/index.js +9 -1
  7. package/dist/src/cli/commands/restart.d.ts +14 -0
  8. package/dist/src/cli/commands/restart.js +38 -0
  9. package/dist/src/cli/commands/stop.js +2 -2
  10. package/dist/src/cli/commands/tasks/index.js +1 -1
  11. package/dist/src/cli/commands/tasks/run.d.ts +1 -0
  12. package/dist/src/cli/commands/tasks/run.js +1 -0
  13. package/dist/src/config/schema.d.ts +6 -0
  14. package/dist/src/config/schema.json +7 -0
  15. package/dist/src/docker/compose/client.d.ts +24 -0
  16. package/dist/src/docker/compose/client.js +55 -0
  17. package/dist/src/docker/compose/index.d.ts +1 -0
  18. package/dist/src/docker/compose/index.js +1 -0
  19. package/dist/src/docker/compose/operations/ComposeExecOperation.d.ts +1 -0
  20. package/dist/src/docker/compose/operations/ComposeExecOperation.js +12 -1
  21. package/dist/src/docker/compose/operations/ComposeRestartOperation.d.ts +14 -0
  22. package/dist/src/docker/compose/operations/ComposeRestartOperation.js +46 -0
  23. package/dist/src/docker/compose/operations/index.d.ts +1 -0
  24. package/dist/src/docker/compose/operations/index.js +1 -0
  25. package/dist/src/docker/index.d.ts +0 -1
  26. package/dist/src/docker/index.js +0 -1
  27. package/dist/src/docker/operations/containers/ContainerExecOperation.d.ts +0 -3
  28. package/dist/src/docker/operations/containers/ContainerExecOperation.js +3 -19
  29. package/dist/src/docker/operations/images/PushImagesOperation.d.ts +9 -3
  30. package/dist/src/docker/operations/images/PushImagesOperation.js +104 -6
  31. package/dist/src/docker/resources/DockerImageResource.js +9 -6
  32. package/dist/src/monorepo/component.d.ts +1 -0
  33. package/dist/src/monorepo/component.js +3 -0
  34. package/dist/src/monorepo/config.js +1 -1
  35. package/dist/src/monorepo/monorepo.js +1 -8
  36. package/dist/src/monorepo/operations/resources/BuildResourcesOperation.js +0 -1
  37. package/dist/src/monorepo/operations/shell/ExecuteLocalCommandOperation.js +1 -0
  38. package/dist/src/monorepo/operations/tasks/RunTasksOperation.d.ts +5 -1
  39. package/dist/src/monorepo/operations/tasks/RunTasksOperation.js +8 -5
  40. package/dist/src/monorepo/resources/FileResourceBuilder.d.ts +1 -0
  41. package/dist/src/monorepo/resources/FileResourceBuilder.js +4 -1
  42. package/dist/src/monorepo/resources/ResourceFactory.js +1 -1
  43. package/dist/src/monorepo/resources/abstract/AbstractResourceBuilder.d.ts +1 -0
  44. package/dist/src/monorepo/resources/types.d.ts +6 -0
  45. package/dist/src/monorepo/types.d.ts +6 -1
  46. package/dist/src/monorepo/utils/EMBCollection.d.ts +0 -3
  47. package/dist/src/monorepo/utils/EMBCollection.js +0 -14
  48. package/dist/src/monorepo/utils/index.d.ts +7 -4
  49. package/dist/src/monorepo/utils/index.js +14 -8
  50. package/dist/src/types.d.ts +2 -0
  51. package/oclif.manifest.json +139 -36
  52. package/package.json +1 -1
  53. package/dist/src/docker/containers/getContainer.d.ts +0 -2
  54. package/dist/src/docker/containers/getContainer.js +0 -5
  55. package/dist/src/docker/containers/index.d.ts +0 -1
  56. package/dist/src/docker/containers/index.js +0 -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.2 darwin-x64 node-v22.18.0
17
+ @enspirit/emb/0.6.0 darwin-x64 node-v22.18.0
18
18
  $ emb --help [COMMAND]
19
19
  USAGE
20
20
  $ emb COMMAND
@@ -36,10 +36,13 @@ USAGE
36
36
  * [`emb images`](#emb-images)
37
37
  * [`emb images delete`](#emb-images-delete)
38
38
  * [`emb images prune`](#emb-images-prune)
39
+ * [`emb images push`](#emb-images-push)
39
40
  * [`emb logs COMPONENT`](#emb-logs-component)
40
41
  * [`emb ps`](#emb-ps)
41
42
  * [`emb resources`](#emb-resources)
42
43
  * [`emb resources build [COMPONENT]`](#emb-resources-build-component)
44
+ * [`emb restart [COMPONENT]`](#emb-restart-component)
45
+ * [`emb run TASK`](#emb-run-task)
43
46
  * [`emb shell COMPONENT`](#emb-shell-component)
44
47
  * [`emb stop`](#emb-stop)
45
48
  * [`emb tasks`](#emb-tasks)
@@ -132,7 +135,7 @@ ARGUMENTS
132
135
  COMPONENT The component you want to see the logs of
133
136
 
134
137
  FLAGS
135
- -f, --follow Follow log output
138
+ -f, --[no-]follow Follow log output
136
139
 
137
140
  DESCRIPTION
138
141
  Get components logs.
@@ -336,6 +339,31 @@ EXAMPLES
336
339
  $ emb images prune
337
340
  ```
338
341
 
342
+ ## `emb images push`
343
+
344
+ Push docker images.
345
+
346
+ ```
347
+ USAGE
348
+ $ emb images push [--json] [--flavor <value>] [--registry <value>] [--retag <value>]
349
+
350
+ FLAGS
351
+ --flavor=<value> Specify the flavor to use.
352
+ --registry=<value> Override the registry to push to
353
+ --retag=<value> Override the original tag to push to a new tag
354
+
355
+ GLOBAL FLAGS
356
+ --json Format output as json.
357
+
358
+ DESCRIPTION
359
+ Push docker images.
360
+
361
+ EXAMPLES
362
+ $ emb images push
363
+
364
+ $ emb images push --registry my.registry.io --retag newtag
365
+ ```
366
+
339
367
  ## `emb logs COMPONENT`
340
368
 
341
369
  Get components logs.
@@ -348,7 +376,7 @@ ARGUMENTS
348
376
  COMPONENT The component you want to see the logs of
349
377
 
350
378
  FLAGS
351
- -f, --follow Follow log output
379
+ -f, --[no-]follow Follow log output
352
380
 
353
381
  DESCRIPTION
354
382
  Get components logs.
@@ -431,6 +459,59 @@ EXAMPLES
431
459
  $ emb resources build build --flavor development
432
460
  ```
433
461
 
462
+ ## `emb restart [COMPONENT]`
463
+
464
+ Restart the whole project.
465
+
466
+ ```
467
+ USAGE
468
+ $ emb restart [COMPONENT...] [--json] [-f]
469
+
470
+ ARGUMENTS
471
+ COMPONENT... The component(s) to restart
472
+
473
+ FLAGS
474
+ -f, --no-deps Don't restart depdendent components
475
+
476
+ GLOBAL FLAGS
477
+ --json Format output as json.
478
+
479
+ DESCRIPTION
480
+ Restart the whole project.
481
+
482
+ EXAMPLES
483
+ $ emb restart
484
+ ```
485
+
486
+ ## `emb run TASK`
487
+
488
+ Run tasks.
489
+
490
+ ```
491
+ USAGE
492
+ $ emb run TASK... [--json] [-x container|local] [-a]
493
+
494
+ ARGUMENTS
495
+ TASK... List of tasks to run. You can provide either ids or names (eg: component:task or task)
496
+
497
+ FLAGS
498
+ -a, --all-matching Run all tasks matching (when multiple matches)
499
+ -x, --executor=<option> Where to run the task. (experimental!)
500
+ <options: container|local>
501
+
502
+ GLOBAL FLAGS
503
+ --json Format output as json.
504
+
505
+ DESCRIPTION
506
+ Run tasks.
507
+
508
+ ALIASES
509
+ $ emb run
510
+
511
+ EXAMPLES
512
+ $ emb run
513
+ ```
514
+
434
515
  ## `emb shell COMPONENT`
435
516
 
436
517
  Get a shell on a running component.
@@ -516,6 +597,9 @@ GLOBAL FLAGS
516
597
  DESCRIPTION
517
598
  Run tasks.
518
599
 
600
+ ALIASES
601
+ $ emb run
602
+
519
603
  EXAMPLES
520
604
  $ emb tasks run
521
605
  ```
@@ -1,4 +1,4 @@
1
- import { getContext, setContext } from '../../index.js';
1
+ import { DockerComposeClient, getContext, setContext } from '../../index.js';
2
2
  import { Command, Performance } from '@oclif/core';
3
3
  import Dockerode from 'dockerode';
4
4
  import { loadConfig } from '../../config/index.js';
@@ -21,9 +21,11 @@ export class BaseCommand extends Command {
21
21
  const monorepo = await withMarker('emb:monorepo', 'init', () => {
22
22
  return new Monorepo(config, rootDir).init();
23
23
  });
24
+ const compose = new DockerComposeClient(monorepo);
24
25
  this.context = setContext({
25
26
  docker: new Dockerode(),
26
27
  monorepo,
28
+ compose,
27
29
  });
28
30
  }
29
31
  catch (error) {
@@ -1,6 +1,5 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import { BaseCommand, getContext } from '../../index.js';
3
- import { ListContainersOperation } from '../../../docker/index.js';
4
3
  export default class ComponentsLogs extends BaseCommand {
5
4
  static aliases = ['logs'];
6
5
  static description = 'Get components logs.';
@@ -10,8 +9,9 @@ export default class ComponentsLogs extends BaseCommand {
10
9
  follow: Flags.boolean({
11
10
  name: 'follow',
12
11
  char: 'f',
12
+ allowNo: true,
13
13
  description: 'Follow log output',
14
- default: false,
14
+ default: true,
15
15
  }),
16
16
  };
17
17
  static args = {
@@ -23,31 +23,19 @@ export default class ComponentsLogs extends BaseCommand {
23
23
  };
24
24
  async run() {
25
25
  const { flags, args } = await this.parse(ComponentsLogs);
26
- const { monorepo, docker } = await getContext();
26
+ const { monorepo, docker, compose } = await getContext();
27
27
  const component = monorepo.component(args.component);
28
- const containers = await monorepo.run(new ListContainersOperation(), {
29
- filters: {
30
- label: [
31
- `emb/project=${monorepo.name}`,
32
- `emb/component=${component.name}`,
33
- `emb/flavor=${monorepo.currentFlavor}`,
34
- ],
35
- },
28
+ const containerId = await compose.getContainer(component.name, {
29
+ mustBeRunning: false,
36
30
  });
37
- if (containers.length === 0) {
38
- return this.error(`No container found for component \`${component.name}\``);
39
- }
40
- if (containers.length > 1) {
41
- return this.error(`More than one container found for component \`${component.name}\``);
42
- }
43
- const container = await docker.getContainer(containers[0].Id);
31
+ const container = await docker.getContainer(containerId);
44
32
  if (flags.follow) {
45
33
  const stream = await container.logs({
46
34
  follow: true,
47
35
  stderr: true,
48
36
  stdout: true,
49
37
  });
50
- stream.pipe(process.stdout);
38
+ docker.modem.demuxStream(stream, process.stdout, process.stderr);
51
39
  }
52
40
  else {
53
41
  const res = await container.logs({
@@ -0,0 +1,11 @@
1
+ import { FlavoredCommand } from '../../index.js';
2
+ export default class ImagesPush extends FlavoredCommand<typeof ImagesPush> {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ static flags: {
7
+ registry: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ retag: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,29 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { FlavoredCommand } from '../../index.js';
3
+ import { PushImagesOperation } from '../../../docker/operations/images/PushImagesOperation.js';
4
+ export default class ImagesPush extends FlavoredCommand {
5
+ static description = 'Push docker images.';
6
+ static enableJsonFlag = true;
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --registry my.registry.io --retag newtag',
10
+ ];
11
+ static flags = {
12
+ registry: Flags.string({
13
+ name: 'registry',
14
+ description: 'Override the registry to push to',
15
+ }),
16
+ retag: Flags.string({
17
+ name: 'retag',
18
+ description: 'Override the original tag to push to a new tag',
19
+ }),
20
+ };
21
+ async run() {
22
+ const { flags } = await this.parse(ImagesPush);
23
+ const { monorepo } = this.context;
24
+ await monorepo.run(new PushImagesOperation(process.stdout), {
25
+ registry: flags.registry,
26
+ retag: flags.retag,
27
+ });
28
+ }
29
+ }
@@ -1,5 +1,6 @@
1
1
  import { printTable } from '@oclif/table';
2
2
  import { FlavoredCommand, getContext, TABLE_DEFAULTS } from '../../index.js';
3
+ import { ResourceFactory } from '../../../monorepo/resources/ResourceFactory.js';
3
4
  export default class ResourcesIndex extends FlavoredCommand {
4
5
  static description = 'List resources.';
5
6
  static enableJsonFlag = true;
@@ -9,14 +10,21 @@ export default class ResourcesIndex extends FlavoredCommand {
9
10
  const { flags } = await this.parse(ResourcesIndex);
10
11
  const { monorepo } = await getContext();
11
12
  const resources = await Promise.all(monorepo.resources.map(async (config) => {
13
+ const component = monorepo.component(config.component);
14
+ const builder = ResourceFactory.factor(config.type, {
15
+ config,
16
+ monorepo,
17
+ component,
18
+ });
12
19
  return {
13
20
  ...config,
21
+ reference: await builder.getReference(),
14
22
  };
15
23
  }));
16
24
  if (!flags.json) {
17
25
  printTable({
18
26
  ...TABLE_DEFAULTS,
19
- columns: ['name', 'type', 'id'],
27
+ columns: ['name', 'type', 'reference', 'id'],
20
28
  data: resources,
21
29
  sort: {
22
30
  name: 'asc',
@@ -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
+ }
@@ -1,6 +1,6 @@
1
1
  import { Listr } from 'listr2';
2
2
  import { FlavoredCommand, getContext } from '../index.js';
3
- import { ComposeDownOperation } from '../../docker/index.js';
3
+ import { ComposeStopOperation } from '../../docker/index.js';
4
4
  export default class StopCommand extends FlavoredCommand {
5
5
  static description = 'Stop the whole project.';
6
6
  static enableJsonFlag = true;
@@ -12,7 +12,7 @@ export default class StopCommand extends FlavoredCommand {
12
12
  {
13
13
  rendererOptions: { persistentOutput: true },
14
14
  async task(ctx, task) {
15
- return monorepo.run(new ComposeDownOperation(task.stdout()), {});
15
+ return monorepo.run(new ComposeStopOperation(task.stdout()), {});
16
16
  },
17
17
  title: 'Stopping project',
18
18
  },
@@ -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;
@@ -1,5 +1,6 @@
1
1
  import { BaseCommand } from '../../index.js';
2
2
  export default class RunTask extends BaseCommand {
3
+ static aliases: string[];
3
4
  static args: {
4
5
  task: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
6
  };
@@ -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)',
@@ -12,6 +12,12 @@ export type TaskConfig = TaskConfig1 & {
12
12
  [k: string]: unknown;
13
13
  };
14
14
  pre?: Identifier[];
15
+ /**
16
+ * Variables to pass onto the task
17
+ */
18
+ vars?: {
19
+ [k: string]: string;
20
+ };
15
21
  };
16
22
  export type TaskConfig1 = {
17
23
  [k: string]: unknown;
@@ -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
@@ -0,0 +1,24 @@
1
+ import { Monorepo } from '../../index.js';
2
+ export type ComposeContainer = {
3
+ Name: string;
4
+ ID: string;
5
+ State: 'exited' | 'running';
6
+ };
7
+ export type ComposeService = {
8
+ name: string;
9
+ containers: Array<ComposeContainer>;
10
+ };
11
+ export type ComposeServices = Map<string, ComposeService>;
12
+ export type GetContainerOptions = {
13
+ mustBeRunning: boolean;
14
+ mustBeUnique: boolean;
15
+ };
16
+ export declare const DefaultGetContainerOptions: GetContainerOptions;
17
+ export declare class DockerComposeClient {
18
+ protected monorepo: Monorepo;
19
+ protected containers?: ComposeServices;
20
+ constructor(monorepo: Monorepo);
21
+ init(): Promise<void>;
22
+ getContainer(serviceName: string, options?: Partial<GetContainerOptions>): Promise<string>;
23
+ private loadContainers;
24
+ }
@@ -0,0 +1,55 @@
1
+ import { execa } from 'execa';
2
+ export const DefaultGetContainerOptions = {
3
+ mustBeRunning: true,
4
+ mustBeUnique: true,
5
+ };
6
+ export class DockerComposeClient {
7
+ monorepo;
8
+ containers;
9
+ constructor(monorepo) {
10
+ this.monorepo = monorepo;
11
+ }
12
+ async init() {
13
+ await this.loadContainers();
14
+ }
15
+ async getContainer(serviceName, options = DefaultGetContainerOptions) {
16
+ const getOptions = { ...DefaultGetContainerOptions, ...options };
17
+ await this.loadContainers();
18
+ const service = this.containers?.get(serviceName);
19
+ if (!service) {
20
+ throw new Error(`No compose service found with name ${serviceName}`);
21
+ }
22
+ const containers = getOptions.mustBeRunning
23
+ ? service.containers.filter((c) => c.State === 'running')
24
+ : service.containers;
25
+ if (containers.length === 0) {
26
+ throw new Error(`No container found for service ${serviceName}`);
27
+ }
28
+ if (containers.length > 1 && getOptions.mustBeUnique) {
29
+ throw new Error(`Multiple containers found`);
30
+ }
31
+ return containers[0].ID;
32
+ }
33
+ async loadContainers(force = false) {
34
+ if (this.containers && !force) {
35
+ return;
36
+ }
37
+ const { stdout } = await execa({
38
+ cwd: this.monorepo.rootDir,
39
+ }) `docker compose ps -a --format json`;
40
+ this.containers = stdout
41
+ .split('\n')
42
+ .map((l) => JSON.parse(l))
43
+ .reduce((services, entry) => {
44
+ if (!services.has(entry.Service)) {
45
+ services.set(entry.Service, {
46
+ name: entry.Service,
47
+ containers: [],
48
+ });
49
+ }
50
+ const svc = services.get(entry.Service);
51
+ svc?.containers.push(entry);
52
+ return services;
53
+ }, new Map());
54
+ }
55
+ }
@@ -1 +1,2 @@
1
+ export * from './client.js';
1
2
  export * from './operations/index.js';
@@ -1 +1,2 @@
1
+ export * from './client.js';
1
2
  export * from './operations/index.js';
@@ -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', input.service, input.command];
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
+ }
@@ -1,5 +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';
4
5
  export * from './ComposeStopOperation.js';
5
6
  export * from './ComposeUpOperation.js';
@@ -1,5 +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';
4
5
  export * from './ComposeStopOperation.js';
5
6
  export * from './ComposeUpOperation.js';
@@ -1,6 +1,5 @@
1
1
  import './resources/index.js';
2
2
  export * from './compose/index.js';
3
- export * from './containers/index.js';
4
3
  export * from './images/index.js';
5
4
  export * from './operations/index.js';
6
5
  export * from './protobuf/index.js';
@@ -1,6 +1,5 @@
1
1
  import './resources/index.js';
2
2
  export * from './compose/index.js';
3
- export * from './containers/index.js';
4
3
  export * from './images/index.js';
5
4
  export * from './operations/index.js';
6
5
  export * from './protobuf/index.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;