@enspirit/emb 0.0.1 → 0.0.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.
Files changed (164) hide show
  1. package/README.md +190 -164
  2. package/bin/run.js +8 -2
  3. package/dist/src/cli/abstract/FlavouredCommand.d.ts +12 -0
  4. package/dist/src/cli/abstract/FlavouredCommand.js +40 -0
  5. package/dist/src/cli/abstract/index.d.ts +1 -0
  6. package/dist/src/cli/abstract/index.js +1 -0
  7. package/dist/src/cli/commands/clean.d.ts +15 -0
  8. package/dist/src/cli/commands/clean.js +29 -0
  9. package/dist/src/cli/commands/components/build.d.ts +11 -0
  10. package/dist/src/cli/commands/components/build.js +24 -0
  11. package/dist/src/cli/commands/components/index.d.ts +14 -0
  12. package/dist/src/cli/commands/components/index.js +44 -0
  13. package/dist/src/cli/commands/config/print.d.ts +13 -0
  14. package/dist/src/cli/commands/config/print.js +16 -0
  15. package/dist/src/cli/commands/containers/index.d.ts +12 -0
  16. package/dist/src/cli/commands/containers/index.js +66 -0
  17. package/dist/src/cli/commands/containers/prune.d.ts +8 -0
  18. package/dist/src/cli/commands/containers/prune.js +23 -0
  19. package/dist/src/cli/commands/down.d.ts +8 -0
  20. package/dist/src/cli/commands/down.js +42 -0
  21. package/dist/src/cli/commands/images/delete.d.ts +10 -0
  22. package/dist/src/cli/commands/images/delete.js +44 -0
  23. package/dist/src/cli/commands/images/index.d.ts +17 -0
  24. package/dist/src/cli/commands/images/index.js +59 -0
  25. package/dist/src/cli/commands/images/prune.d.ts +11 -0
  26. package/dist/src/cli/commands/images/prune.js +35 -0
  27. package/dist/src/cli/commands/run/index.d.ts +10 -0
  28. package/dist/src/cli/commands/run/index.js +49 -0
  29. package/dist/src/cli/commands/tasks/index.d.ts +9 -0
  30. package/dist/src/cli/commands/tasks/index.js +23 -0
  31. package/dist/src/cli/commands/tasks/run.d.ts +16 -0
  32. package/dist/src/cli/commands/tasks/run.js +113 -0
  33. package/dist/src/cli/commands/up.d.ts +10 -0
  34. package/dist/src/cli/commands/up.js +49 -0
  35. package/dist/src/cli/constants.d.ts +2 -0
  36. package/dist/src/cli/constants.js +6 -0
  37. package/dist/src/cli/hooks/init.d.ts +3 -0
  38. package/dist/src/cli/hooks/init.js +27 -0
  39. package/dist/src/cli/index.d.ts +3 -0
  40. package/dist/src/cli/index.js +3 -0
  41. package/dist/src/config/convert.d.ts +5 -0
  42. package/dist/src/config/convert.js +48 -0
  43. package/dist/src/config/index.d.ts +6 -0
  44. package/dist/src/config/index.js +25 -0
  45. package/dist/src/config/schema.d.ts +102 -0
  46. package/dist/src/config/schema.js +7 -0
  47. package/dist/src/config/schema.json +209 -0
  48. package/dist/src/config/types.d.ts +43 -0
  49. package/dist/src/config/types.js +1 -0
  50. package/dist/src/config/validation.d.ts +1 -0
  51. package/dist/src/config/validation.js +27 -0
  52. package/dist/src/context.d.ts +3 -0
  53. package/dist/src/context.js +7 -0
  54. package/dist/src/docker/compose/index.d.ts +7 -0
  55. package/dist/src/docker/compose/index.js +13 -0
  56. package/dist/src/docker/containers/getContainer.d.ts +2 -0
  57. package/dist/src/docker/containers/getContainer.js +5 -0
  58. package/dist/src/docker/containers/index.d.ts +1 -0
  59. package/dist/src/docker/containers/index.js +1 -0
  60. package/dist/src/docker/images/buildImage.d.ts +19 -0
  61. package/dist/src/docker/images/buildImage.js +64 -0
  62. package/dist/src/docker/images/deleteImage.d.ts +5 -0
  63. package/dist/src/docker/images/deleteImage.js +6 -0
  64. package/dist/src/docker/images/index.d.ts +4 -0
  65. package/dist/src/docker/images/index.js +4 -0
  66. package/dist/src/docker/images/listImages.d.ts +2 -0
  67. package/dist/src/docker/images/listImages.js +8 -0
  68. package/dist/src/docker/images/pruneImages.d.ts +6 -0
  69. package/dist/src/docker/images/pruneImages.js +8 -0
  70. package/dist/src/docker/index.d.ts +7 -0
  71. package/dist/src/docker/index.js +7 -0
  72. package/dist/src/docker/operations/containers/ListContainersOperation.d.ts +18 -0
  73. package/dist/src/docker/operations/containers/ListContainersOperation.js +44 -0
  74. package/dist/src/docker/operations/containers/PruneContainersOperation.d.ts +16 -0
  75. package/dist/src/docker/operations/containers/PruneContainersOperation.js +33 -0
  76. package/dist/src/docker/operations/containers/index.d.ts +2 -0
  77. package/dist/src/docker/operations/containers/index.js +2 -0
  78. package/dist/src/docker/operations/images/BuildImageOperation.d.ts +20 -0
  79. package/dist/src/docker/operations/images/BuildImageOperation.js +69 -0
  80. package/dist/src/docker/operations/images/ListImagesOperation.d.ts +17 -0
  81. package/dist/src/docker/operations/images/ListImagesOperation.js +38 -0
  82. package/dist/src/docker/operations/images/PruneImagesOperation.d.ts +16 -0
  83. package/dist/src/docker/operations/images/PruneImagesOperation.js +33 -0
  84. package/dist/src/docker/operations/images/index.d.ts +3 -0
  85. package/dist/src/docker/operations/images/index.js +3 -0
  86. package/dist/src/docker/operations/index.d.ts +2 -0
  87. package/dist/src/docker/operations/index.js +2 -0
  88. package/dist/src/docker/protobuf/control.proto +48 -0
  89. package/dist/src/docker/protobuf/index.d.ts +5 -0
  90. package/dist/src/docker/protobuf/index.js +29 -0
  91. package/dist/src/docker/types.d.ts +14 -0
  92. package/dist/src/docker/types.js +1 -0
  93. package/dist/src/docker/utils.d.ts +7 -0
  94. package/dist/src/docker/utils.js +10 -0
  95. package/dist/src/executors/docker.d.ts +6 -0
  96. package/dist/src/executors/docker.js +14 -0
  97. package/dist/src/executors/index.d.ts +6 -0
  98. package/dist/src/executors/index.js +7 -0
  99. package/dist/src/executors/shell.d.ts +2 -0
  100. package/dist/src/executors/shell.js +14 -0
  101. package/dist/src/executors/types.d.ts +8 -0
  102. package/dist/src/executors/types.js +1 -0
  103. package/dist/src/index.d.ts +3 -0
  104. package/dist/src/index.js +3 -0
  105. package/dist/src/monorepo/component.d.ts +24 -0
  106. package/dist/src/monorepo/component.js +77 -0
  107. package/dist/src/monorepo/config.d.ts +16 -0
  108. package/dist/src/monorepo/config.js +66 -0
  109. package/dist/src/monorepo/index.d.ts +7 -0
  110. package/dist/src/monorepo/index.js +7 -0
  111. package/dist/src/monorepo/monorepo.d.ts +29 -0
  112. package/dist/src/monorepo/monorepo.js +106 -0
  113. package/dist/src/monorepo/operations/components/BuildComponentsOperation.d.ts +11 -0
  114. package/dist/src/monorepo/operations/components/BuildComponentsOperation.js +144 -0
  115. package/dist/src/monorepo/operations/components/index.d.ts +1 -0
  116. package/dist/src/monorepo/operations/components/index.js +1 -0
  117. package/dist/src/monorepo/operations/index.d.ts +1 -0
  118. package/dist/src/monorepo/operations/index.js +1 -0
  119. package/dist/src/monorepo/plugins/ComponentsDiscover.d.ts +6 -0
  120. package/dist/src/monorepo/plugins/ComponentsDiscover.js +30 -0
  121. package/dist/src/monorepo/plugins/DotEnvPlugin.d.ts +5 -0
  122. package/dist/src/monorepo/plugins/DotEnvPlugin.js +11 -0
  123. package/dist/src/monorepo/plugins/index.d.ts +7 -0
  124. package/dist/src/monorepo/plugins/index.js +20 -0
  125. package/dist/src/monorepo/plugins/plugin.d.ts +15 -0
  126. package/dist/src/monorepo/plugins/plugin.js +12 -0
  127. package/dist/src/monorepo/project.d.ts +6 -0
  128. package/dist/src/monorepo/project.js +8 -0
  129. package/dist/src/monorepo/store/index.d.ts +20 -0
  130. package/dist/src/monorepo/store/index.js +65 -0
  131. package/dist/src/monorepo/types.d.ts +7 -0
  132. package/dist/src/monorepo/types.js +1 -0
  133. package/dist/src/monorepo/utils/findBuildOrder.d.ts +2 -0
  134. package/dist/src/monorepo/utils/findBuildOrder.js +41 -0
  135. package/dist/src/monorepo/utils/index.d.ts +1 -0
  136. package/dist/src/monorepo/utils/index.js +1 -0
  137. package/dist/src/operations/abstract/AbstractOperation.d.ts +10 -0
  138. package/dist/src/operations/abstract/AbstractOperation.js +13 -0
  139. package/dist/src/operations/abstract/index.d.ts +1 -0
  140. package/dist/src/operations/abstract/index.js +1 -0
  141. package/dist/src/operations/index.d.ts +2 -0
  142. package/dist/src/operations/index.js +2 -0
  143. package/dist/src/operations/types.d.ts +3 -0
  144. package/dist/src/operations/types.js +1 -0
  145. package/dist/src/prerequisites/FilePrerequisitePlugin.d.ts +7 -0
  146. package/dist/src/prerequisites/FilePrerequisitePlugin.js +41 -0
  147. package/dist/src/prerequisites/GitPrerequisitePlugin.d.ts +5 -0
  148. package/dist/src/prerequisites/GitPrerequisitePlugin.js +17 -0
  149. package/dist/src/prerequisites/index.d.ts +3 -0
  150. package/dist/src/prerequisites/index.js +3 -0
  151. package/dist/src/prerequisites/types.d.ts +46 -0
  152. package/dist/src/prerequisites/types.js +24 -0
  153. package/dist/src/types.d.ts +13 -0
  154. package/dist/src/types.js +1 -0
  155. package/dist/src/utils/TemplateExpander.d.ts +21 -0
  156. package/dist/src/utils/TemplateExpander.js +53 -0
  157. package/dist/src/utils/deepMergeArray.d.ts +1 -0
  158. package/dist/src/utils/deepMergeArray.js +19 -0
  159. package/dist/src/utils/index.d.ts +3 -0
  160. package/dist/src/utils/index.js +3 -0
  161. package/dist/src/utils/time.d.ts +2 -0
  162. package/dist/src/utils/time.js +19 -0
  163. package/oclif.manifest.json +572 -2
  164. package/package.json +10 -9
@@ -0,0 +1,24 @@
1
+ import { Args } from '@oclif/core';
2
+ import { FlavoredCommand, getContext } from '../../index.js';
3
+ import { BuildComponentsOperation } from '../../../monorepo/operations/index.js';
4
+ export default class BuildCommand extends FlavoredCommand {
5
+ static args = {
6
+ component: Args.string({
7
+ description: 'List of components to build',
8
+ required: false,
9
+ }),
10
+ };
11
+ static description = 'Build the components of the monorepo';
12
+ static examples = [
13
+ `<%= config.bin %> <%= command.id %> build --flavor development`,
14
+ ];
15
+ static flags = {};
16
+ static strict = false;
17
+ async run() {
18
+ const { argv } = await this.parse(BuildCommand);
19
+ const { monorepo } = getContext();
20
+ await monorepo.run(new BuildComponentsOperation(), {
21
+ components: argv.length > 0 ? argv : undefined,
22
+ });
23
+ }
24
+ }
@@ -0,0 +1,14 @@
1
+ import { FlavoredCommand } from '../../index.js';
2
+ export type ComponentInfo = {
3
+ container?: string;
4
+ imageName: string;
5
+ name: string;
6
+ tag: string;
7
+ };
8
+ export default class ComponentsIndex extends FlavoredCommand<typeof ComponentsIndex> {
9
+ static description: string;
10
+ static enableJsonFlag: boolean;
11
+ static examples: string[];
12
+ static flags: {};
13
+ run(): Promise<Array<ComponentInfo>>;
14
+ }
@@ -0,0 +1,44 @@
1
+ import { printTable } from '@oclif/table';
2
+ import { FlavoredCommand, getContext, TABLE_DEFAULTS } from '../../index.js';
3
+ import { ListContainersOperation, shortId } from '../../../docker/index.js';
4
+ export default class ComponentsIndex extends FlavoredCommand {
5
+ static description = 'List components.';
6
+ static enableJsonFlag = true;
7
+ static examples = ['<%= config.bin %> <%= command.id %>'];
8
+ static flags = {};
9
+ async run() {
10
+ const { flags } = await this.parse(ComponentsIndex);
11
+ const { monorepo } = await getContext();
12
+ // Get all running containers for this project
13
+ // and then try to do a mapping. It's probably better than
14
+ // doing N queries to list with specific filters
15
+ const runningContainers = await monorepo.run(new ListContainersOperation(), {
16
+ filters: {
17
+ label: [`emb/project=${monorepo.name}`],
18
+ },
19
+ });
20
+ const components = await Promise.all(monorepo.components.map(async (cmp) => {
21
+ const buildInfos = await cmp.toDockerBuild();
22
+ const container = runningContainers.find((cont) => {
23
+ return cont.Image === `${buildInfos.name}:${buildInfos.tag}`;
24
+ });
25
+ return {
26
+ container: container?.Id ? shortId(container?.Id) : '',
27
+ imageName: buildInfos.name,
28
+ name: cmp.name,
29
+ tag: buildInfos.tag,
30
+ };
31
+ }));
32
+ if (!flags.json) {
33
+ printTable({
34
+ ...TABLE_DEFAULTS,
35
+ columns: ['name', 'imageName', 'tag', 'container'],
36
+ data: components,
37
+ sort: {
38
+ name: 'asc',
39
+ },
40
+ });
41
+ }
42
+ return components;
43
+ }
44
+ }
@@ -0,0 +1,13 @@
1
+ import { FlavoredCommand } from '../../index.js';
2
+ import { IMonorepoConfig } from '../../../config/index.js';
3
+ export type TaskInfo = {
4
+ component?: string;
5
+ description?: string;
6
+ name: string;
7
+ };
8
+ export default class ConfigPrint extends FlavoredCommand<typeof ConfigPrint> {
9
+ static description: string;
10
+ static enableJsonFlag: boolean;
11
+ static examples: string[];
12
+ run(): Promise<IMonorepoConfig>;
13
+ }
@@ -0,0 +1,16 @@
1
+ import YAML from 'yaml';
2
+ import { FlavoredCommand, getContext } from '../../index.js';
3
+ export default class ConfigPrint extends FlavoredCommand {
4
+ static description = 'Print the current config.';
5
+ static enableJsonFlag = true;
6
+ static examples = ['<%= config.bin %> <%= command.id %>'];
7
+ async run() {
8
+ const { flags } = await this.parse(ConfigPrint);
9
+ const context = await getContext();
10
+ const { monorepo } = context;
11
+ if (!flags.json) {
12
+ console.log(YAML.stringify(monorepo.config));
13
+ }
14
+ return monorepo.config;
15
+ }
16
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ import { ContainerInfo } from 'dockerode';
3
+ export default class ContainersIndex extends Command {
4
+ static aliases: string[];
5
+ static description: string;
6
+ static enableJsonFlag: boolean;
7
+ static examples: string[];
8
+ static flags: {
9
+ all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<Array<ContainerInfo>>;
12
+ }
@@ -0,0 +1,66 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Command, Flags } from '@oclif/core';
3
+ import { printTable } from '@oclif/table';
4
+ import { TABLE_DEFAULTS } from '../../index.js';
5
+ import { ListContainersOperation, shortId } from '../../../docker/index.js';
6
+ import { timeAgo } from '../../../utils/index.js';
7
+ export default class ContainersIndex extends Command {
8
+ static aliases = ['ps'];
9
+ static description = 'List docker containers.';
10
+ static enableJsonFlag = true;
11
+ static examples = ['<%= config.bin %> <%= command.id %>'];
12
+ static flags = {
13
+ all: Flags.boolean({
14
+ char: 'a',
15
+ default: false,
16
+ description: 'Retun all containers. By default, only running containers are shown',
17
+ name: 'all',
18
+ required: false,
19
+ }),
20
+ };
21
+ async run() {
22
+ const { flags } = await this.parse(ContainersIndex);
23
+ const context = await getContext();
24
+ const { monorepo } = context;
25
+ const containers = await monorepo.run(new ListContainersOperation(), {
26
+ all: flags.all,
27
+ filters: {
28
+ label: [`emb/project=${monorepo.name}`],
29
+ },
30
+ });
31
+ if (!flags.json) {
32
+ const data = containers.map((c) => {
33
+ return {
34
+ command: c.Command,
35
+ created: timeAgo(new Date(c.Created * 1000)),
36
+ id: shortId(c.Id),
37
+ image: c.Image,
38
+ name: c.Names[0] || c.Id,
39
+ ports: c.Ports.map((p) => {
40
+ const parts = [];
41
+ if (p.IP) {
42
+ parts.push(p.IP, ':', p.PublicPort, '->');
43
+ }
44
+ parts.push(p.PrivatePort, '/', p.Type);
45
+ return parts.join('');
46
+ }).join(', '),
47
+ status: c.Status,
48
+ };
49
+ });
50
+ printTable({
51
+ ...TABLE_DEFAULTS,
52
+ columns: [
53
+ 'id',
54
+ 'image',
55
+ 'command',
56
+ 'created',
57
+ 'status',
58
+ 'ports',
59
+ 'name',
60
+ ],
61
+ data,
62
+ });
63
+ }
64
+ return containers;
65
+ }
66
+ }
@@ -0,0 +1,8 @@
1
+ import { Command } from '@oclif/core';
2
+ import { PruneContainersInfo } from 'dockerode';
3
+ export default class ContainersPrune extends Command {
4
+ static description: string;
5
+ static enableJsonFlag: boolean;
6
+ static examples: string[];
7
+ run(): Promise<PruneContainersInfo>;
8
+ }
@@ -0,0 +1,23 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Command } from '@oclif/core';
3
+ import { PruneContainersOperation } from '../../../docker/index.js';
4
+ export default class ContainersPrune extends Command {
5
+ static description = 'Prune containers.';
6
+ static enableJsonFlag = true;
7
+ static examples = ['<%= config.bin %> <%= command.id %>'];
8
+ async run() {
9
+ const { monorepo } = await getContext();
10
+ const info = await monorepo.run(new PruneContainersOperation(), {
11
+ filters: {
12
+ label: [`emb/project=${monorepo.name}`],
13
+ },
14
+ });
15
+ info.ContainersDeleted?.forEach((d) => {
16
+ if (d) {
17
+ this.log('Deleted', d);
18
+ }
19
+ });
20
+ this.log('Space reclaimed', info.SpaceReclaimed);
21
+ return info;
22
+ }
23
+ }
@@ -0,0 +1,8 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DownCommand extends Command {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ static flags: {};
7
+ run(): Promise<void>;
8
+ }
@@ -0,0 +1,42 @@
1
+ import { getContext } from '../../index.js';
2
+ import { Command } from '@oclif/core';
3
+ import { Listr } from 'listr2';
4
+ import { down } from '../../docker/index.js';
5
+ export default class DownCommand extends Command {
6
+ static description = 'Stop the whole project.';
7
+ static enableJsonFlag = true;
8
+ static examples = ['<%= config.bin %> <%= command.id %>'];
9
+ static flags = {};
10
+ async run() {
11
+ const { monorepo } = getContext();
12
+ const runner = new Listr([
13
+ {
14
+ rendererOptions: { persistentOutput: true },
15
+ async task(ctx, task) {
16
+ const process = await down({ cwd: monorepo.rootDir });
17
+ const handleOutput = (chunk) => {
18
+ const line = chunk.toString();
19
+ task.output = line.trimEnd(); // This updates the live output in Listr
20
+ };
21
+ process.stdout?.on('data', handleOutput);
22
+ process.stderr?.on('data', handleOutput);
23
+ return new Promise((resolve, reject) => {
24
+ process.on('exit', (code) => {
25
+ if (code === 0) {
26
+ resolve(null);
27
+ }
28
+ else {
29
+ reject(new Error(`Command failed with code ${code}`));
30
+ }
31
+ });
32
+ process.on('error', (err) => {
33
+ reject(err);
34
+ });
35
+ });
36
+ },
37
+ title: 'Stopping project',
38
+ },
39
+ ]);
40
+ await runner.run();
41
+ }
42
+ }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ImagesDelete extends Command {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ static flags: {
7
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,44 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Command, Flags } from '@oclif/core';
3
+ import { Listr } from 'listr2';
4
+ import { deleteImage, listImages } from '../../../docker/index.js';
5
+ export default class ImagesDelete extends Command {
6
+ static description = 'Delete project images.';
7
+ static enableJsonFlag = true;
8
+ static examples = ['<%= config.bin %> <%= command.id %>'];
9
+ static flags = {
10
+ force: Flags.boolean({
11
+ char: 'f',
12
+ default: false,
13
+ description: 'Remove the image even if it is being used by stopped containers or has other tags',
14
+ name: 'force',
15
+ required: false,
16
+ }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(ImagesDelete);
20
+ const context = await getContext();
21
+ const images = await listImages({
22
+ filters: {
23
+ label: [`emb/project=${context.monorepo.name}`],
24
+ },
25
+ });
26
+ // De-duplicate this (also in images/index.ts)
27
+ // TODO: move to repo/config abstraction
28
+ const imageNames = images.reduce((imgs, img) => {
29
+ const tags = (img.RepoTags || [])?.filter((tag) => tag.indexOf(context.monorepo.name) === 0);
30
+ return [...imgs, ...tags];
31
+ }, []);
32
+ const runner = new Listr(imageNames.map((img) => {
33
+ return {
34
+ async task() {
35
+ await deleteImage(img, {
36
+ force: flags.force,
37
+ });
38
+ },
39
+ title: `Delete ${img}`,
40
+ };
41
+ }));
42
+ await runner.run();
43
+ }
44
+ }
@@ -0,0 +1,17 @@
1
+ import { Command } from '@oclif/core';
2
+ export type ImageInfo = {
3
+ created: Date;
4
+ imageId: string;
5
+ name: string;
6
+ size: number;
7
+ tag: string;
8
+ };
9
+ export default class ImagesIndex extends Command {
10
+ static description: string;
11
+ static enableJsonFlag: boolean;
12
+ static examples: string[];
13
+ static flags: {
14
+ all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<Array<ImageInfo>>;
17
+ }
@@ -0,0 +1,59 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Command, Flags } from '@oclif/core';
3
+ import { printTable } from '@oclif/table';
4
+ import { TABLE_DEFAULTS } from '../../index.js';
5
+ import { listImages, shortId } from '../../../docker/index.js';
6
+ import { timeAgo } from '../../../utils/index.js';
7
+ export default class ImagesIndex extends Command {
8
+ static description = 'List docker images.';
9
+ static enableJsonFlag = true;
10
+ static examples = ['<%= config.bin %> <%= command.id %>'];
11
+ static flags = {
12
+ all: Flags.boolean({
13
+ char: 'a',
14
+ default: false,
15
+ description: 'Show all images. Only images from a final layer (no children) are shown by default.',
16
+ name: 'all',
17
+ required: false,
18
+ }),
19
+ };
20
+ async run() {
21
+ const { flags } = await this.parse(ImagesIndex);
22
+ const context = await getContext();
23
+ const images = await listImages({
24
+ all: flags.all,
25
+ filters: {
26
+ label: [`emb/project=${context.monorepo.name}`],
27
+ },
28
+ });
29
+ const flatten = images.reduce((imgs, img) => {
30
+ const matches = (img.RepoTags || [])
31
+ ?.filter((tag) => tag.indexOf(context.monorepo.name) === 0)
32
+ .map((m) => {
33
+ const [name, tag] = m.split(':');
34
+ return {
35
+ created: new Date(img.Created * 1000),
36
+ imageId: shortId(img.Id),
37
+ name,
38
+ size: img.Size,
39
+ tag,
40
+ };
41
+ });
42
+ return [...imgs, ...matches];
43
+ }, []);
44
+ if (!flags.json) {
45
+ printTable({
46
+ ...TABLE_DEFAULTS,
47
+ columns: ['name', 'tag', 'imageId', 'created', 'size'],
48
+ data: flatten.map((f) => {
49
+ return {
50
+ ...f,
51
+ created: timeAgo(f.created),
52
+ size: Math.floor(f.size / (1000 * 1000)) + 'MB',
53
+ };
54
+ }),
55
+ });
56
+ }
57
+ return flatten;
58
+ }
59
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ import { PruneImagesInfo } from 'dockerode';
3
+ export default class ImagesPrune extends Command {
4
+ static description: string;
5
+ static enableJsonFlag: boolean;
6
+ static examples: string[];
7
+ static flags: {
8
+ all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<PruneImagesInfo>;
11
+ }
@@ -0,0 +1,35 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Command, Flags } from '@oclif/core';
3
+ import { pruneImages } from '../../../docker/index.js';
4
+ export default class ImagesPrune extends Command {
5
+ static description = 'Prune project images.';
6
+ static enableJsonFlag = true;
7
+ static examples = ['<%= config.bin %> <%= command.id %>'];
8
+ static flags = {
9
+ all: Flags.boolean({
10
+ char: 'a',
11
+ default: false,
12
+ description: 'Prune all images. When set to true all images will be pruned, not only dangling ones',
13
+ name: 'all',
14
+ required: false,
15
+ }),
16
+ };
17
+ async run() {
18
+ const { flags } = await this.parse(ImagesPrune);
19
+ const context = await getContext();
20
+ const info = await pruneImages({
21
+ dangling: !flags.all,
22
+ label: [`emb/project=${context.monorepo.name}`],
23
+ });
24
+ info.ImagesDeleted?.forEach((d) => {
25
+ if (d.Deleted) {
26
+ this.log('Deleted', d.Deleted);
27
+ }
28
+ if (d.Untagged) {
29
+ this.log('Untagged', d.Untagged);
30
+ }
31
+ });
32
+ this.log('Space reclaimed', info.SpaceReclaimed);
33
+ return info;
34
+ }
35
+ }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class RunComponentScript extends Command {
3
+ static args: {
4
+ component: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ script: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static strict: boolean;
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,49 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Args, Command } from '@oclif/core';
3
+ import { Listr } from 'listr2';
4
+ import { spawn } from 'node:child_process';
5
+ import fs from 'node:fs/promises';
6
+ export default class RunComponentScript extends Command {
7
+ static args = {
8
+ component: Args.string({
9
+ description: 'Component name',
10
+ required: true,
11
+ }),
12
+ script: Args.string({ description: 'NPM script to run', required: true }),
13
+ };
14
+ static description = "Run an npm script from a component's package.json";
15
+ static strict = true;
16
+ async run() {
17
+ const { args } = await this.parse(RunComponentScript);
18
+ const { monorepo } = getContext();
19
+ const component = monorepo.component(args.component);
20
+ const pkgPath = component.join('package.json');
21
+ const tasks = new Listr([
22
+ {
23
+ rendererOptions: {
24
+ persistentOutput: true,
25
+ },
26
+ async task(_ctx, _task) {
27
+ try {
28
+ const pkgRaw = await fs.readFile(pkgPath, 'utf8');
29
+ const pkg = JSON.parse(pkgRaw);
30
+ if (!pkg.scripts?.[args.script]) {
31
+ throw new Error(`Script "${args.script}" not found in ${component.name}/package.json`);
32
+ }
33
+ return spawn('npm', ['run', args.script], {
34
+ cwd: component.rootdir,
35
+ }).stdout;
36
+ }
37
+ catch (error) {
38
+ const error_ = error instanceof Error
39
+ ? new TypeError(`Failed to run ${component.name}:${args.script}\n${error.message}`)
40
+ : new Error(`Failed to run ${component.name}:${args.script}\n${error}`);
41
+ throw error_;
42
+ }
43
+ },
44
+ title: `Running npm script '${args.script}' on ${args.component}`,
45
+ },
46
+ ], { concurrent: false });
47
+ await tasks.run();
48
+ }
49
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ import { TaskInfo } from '../../../monorepo/index.js';
3
+ export default class TasksIndex extends Command {
4
+ static description: string;
5
+ static enableJsonFlag: boolean;
6
+ static examples: string[];
7
+ static flags: {};
8
+ run(): Promise<Array<TaskInfo>>;
9
+ }
@@ -0,0 +1,23 @@
1
+ import { getContext } from '../../../index.js';
2
+ import { Command } from '@oclif/core';
3
+ import { printTable } from '@oclif/table';
4
+ import { TABLE_DEFAULTS } from '../../index.js';
5
+ export default class TasksIndex extends Command {
6
+ static description = 'List tasks.';
7
+ static enableJsonFlag = true;
8
+ static examples = ['<%= config.bin %> <%= command.id %>'];
9
+ static flags = {};
10
+ async run() {
11
+ const { flags } = await this.parse(TasksIndex);
12
+ const context = await getContext();
13
+ const { monorepo } = context;
14
+ const { tasks } = monorepo;
15
+ if (!flags.json)
16
+ printTable({
17
+ ...TABLE_DEFAULTS,
18
+ columns: ['id', 'component', 'name', 'description'],
19
+ data: tasks,
20
+ });
21
+ return tasks;
22
+ }
23
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class RunTask extends Command {
3
+ static args: {
4
+ task: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static enableJsonFlag: boolean;
8
+ static examples: string[];
9
+ static flags: {
10
+ executor: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ static strict: boolean;
13
+ run(): Promise<void>;
14
+ private dockerExec;
15
+ private shellExec;
16
+ }