build-strap 4.0.0-dev.46 → 4.0.0-dev.54

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 (107) hide show
  1. package/README.md +3 -34
  2. package/package.json +23 -19
  3. package/src/ant.d.ts +19 -0
  4. package/src/ant.js +12 -36
  5. package/src/cert.d.ts +12 -0
  6. package/src/cert.js +87 -148
  7. package/src/clean.d.ts +4 -0
  8. package/src/clean.js +5 -13
  9. package/src/copy.d.ts +7 -0
  10. package/src/copy.js +48 -74
  11. package/src/cp.d.ts +17 -0
  12. package/src/cp.js +81 -165
  13. package/src/docker.container.d.ts +73 -0
  14. package/src/docker.container.js +208 -350
  15. package/src/docker.d.ts +68 -0
  16. package/src/docker.js +163 -339
  17. package/src/docker.network.d.ts +42 -0
  18. package/src/docker.network.js +67 -141
  19. package/src/docker.volume.d.ts +26 -0
  20. package/src/docker.volume.js +50 -124
  21. package/src/dockerCleanup.d.ts +38 -0
  22. package/src/dockerCleanup.js +62 -136
  23. package/src/dockerCompose.d.ts +154 -0
  24. package/src/dockerCompose.js +390 -716
  25. package/src/fs.d.ts +5 -0
  26. package/src/fs.js +33 -91
  27. package/src/git.d.ts +9 -0
  28. package/src/git.js +19 -29
  29. package/src/index.d.ts +20 -0
  30. package/src/index.js +20 -26
  31. package/src/maps.d.ts +33 -0
  32. package/src/maps.js +12 -82
  33. package/src/npm.d.ts +48 -0
  34. package/src/npm.js +128 -131
  35. package/src/pkg.d.ts +38 -0
  36. package/src/pkg.js +27 -74
  37. package/src/publish.d.ts +27 -0
  38. package/src/publish.js +51 -138
  39. package/src/run.d.ts +13 -0
  40. package/src/run.js +39 -84
  41. package/src/tgz.d.ts +13 -0
  42. package/src/tgz.js +54 -88
  43. package/src/version.d.ts +34 -0
  44. package/src/version.js +85 -126
  45. package/src/yarn.d.ts +44 -0
  46. package/src/yarn.js +147 -115
  47. package/ant.js +0 -43
  48. package/ant.js.flow +0 -42
  49. package/artifactory.js +0 -617
  50. package/artifactory.js.flow +0 -616
  51. package/cert.conf +0 -20
  52. package/cert.js +0 -153
  53. package/cert.js.flow +0 -152
  54. package/clean.js +0 -20
  55. package/clean.js.flow +0 -19
  56. package/copy.js +0 -80
  57. package/copy.js.flow +0 -79
  58. package/cp.js +0 -173
  59. package/cp.js.flow +0 -172
  60. package/docker.container.js +0 -390
  61. package/docker.container.js.flow +0 -389
  62. package/docker.js +0 -365
  63. package/docker.js.flow +0 -364
  64. package/docker.network.js +0 -160
  65. package/docker.network.js.flow +0 -159
  66. package/docker.volume.js +0 -136
  67. package/docker.volume.js.flow +0 -136
  68. package/dockerCleanup.js +0 -152
  69. package/dockerCleanup.js.flow +0 -151
  70. package/dockerCompose.js +0 -766
  71. package/dockerCompose.js.flow +0 -765
  72. package/flow.js +0 -21
  73. package/flow.js.flow +0 -20
  74. package/fs.js +0 -95
  75. package/fs.js.flow +0 -96
  76. package/git.js +0 -35
  77. package/git.js.flow +0 -34
  78. package/hg.js +0 -35
  79. package/hg.js.flow +0 -34
  80. package/index.js +0 -27
  81. package/index.js.flow +0 -26
  82. package/inline-resources.js +0 -158
  83. package/inline-resources.js.flow +0 -157
  84. package/maps.js +0 -112
  85. package/maps.js.flow +0 -111
  86. package/npm.js +0 -145
  87. package/npm.js.flow +0 -144
  88. package/pkg.js +0 -81
  89. package/pkg.js.flow +0 -80
  90. package/publish.js +0 -145
  91. package/publish.js.flow +0 -144
  92. package/run.js +0 -90
  93. package/run.js.flow +0 -89
  94. package/src/artifactory.js +0 -616
  95. package/src/cert.conf +0 -20
  96. package/src/flow.js +0 -20
  97. package/src/hg.js +0 -34
  98. package/src/inline-resources.js +0 -157
  99. package/src/test.js +0 -55
  100. package/test.js +0 -56
  101. package/test.js.flow +0 -55
  102. package/tgz.js +0 -102
  103. package/tgz.js.flow +0 -101
  104. package/version.js +0 -143
  105. package/version.js.flow +0 -142
  106. package/yarn.js +0 -124
  107. package/yarn.js.flow +0 -123
@@ -1,765 +1,439 @@
1
- // @flow
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _DockerComposeService_name, _DockerComposeService_svcDef, _DockerComposeService_dockerCompose, _DockerComposeService_tracker, _DockerComposeService_parsedPorts, _DockerComposeService_parsedNetworks, _DockerComposeService_parsedVolumes, _DockerComposeService_baseRunArgs;
2
13
  import fs from 'fs-extra';
14
+ import getPort from 'get-port';
3
15
  import yaml from 'js-yaml';
4
16
  import path from 'path';
5
- import getPort from 'get-port';
6
- import { keys, entries, mapValuesAsync, type MapObj } from './maps';
7
-
8
- import { buildLog } from './run';
9
- import { dockerPull } from './docker';
10
- import {
11
- dockerContainerFind,
12
- dockerContainerRunDaemon,
13
- type DockerContainer,
14
- } from './docker.container';
15
- import {
16
- dockerNetworkDelete,
17
- dockerNetworkCreate,
18
- type DockerNetworkCreateOptions,
19
- type DockerNetwork,
20
- } from './docker.network';
21
- import {
22
- dockerVolumeCreate,
23
- dockerVolumeRm,
24
- type DockerVolume,
25
- } from './docker.volume';
26
-
27
- export type DockerComposeResourceTracker = {
28
- services: Map<string, DockerComposeService>,
29
- networks: Map<string, DockerNetwork>,
30
- containers: Map<string, DockerContainer>,
31
- volumes: Map<string, DockerVolume>,
32
- cleaning: ?Promise<void>,
33
- };
34
-
35
- export const dockerComposeCreateResourceTracker = (): DockerComposeResourceTracker => ({
36
- networks: new Map(),
37
- services: new Map(),
38
- containers: new Map(),
39
- volumes: new Map(),
40
- cleaning: null,
17
+ import { dockerContainerFind, dockerContainerRunDaemon, } from './docker.container.js';
18
+ import { dockerPull } from './docker.js';
19
+ import { dockerNetworkCreate, dockerNetworkDelete, } from './docker.network.js';
20
+ import { dockerVolumeCreate, dockerVolumeRm, } from './docker.volume.js';
21
+ import { mapValuesAsync } from './maps.js';
22
+ import { buildLog } from './run.js';
23
+ export const dockerComposeCreateResourceTracker = () => ({
24
+ cleaning: null,
25
+ containers: new Map(),
26
+ networks: new Map(),
27
+ services: new Map(),
28
+ volumes: new Map(),
41
29
  });
42
-
43
30
  const defaultTracker = dockerComposeCreateResourceTracker();
44
-
45
- type DockerComposeEnvDef = string[] | { [string]: string };
46
-
47
- type DockerComposeULimitDef = number | { soft: number, hard: number };
48
-
49
- type DockerComposeULimitsDef = {
50
- [string]: DockerComposeULimitDef,
51
- };
52
-
53
- type DockerComposeServiceDef = {
54
- container_name?: string,
55
- image?: string,
56
- ports?: string[],
57
- volumes?: string[],
58
- command?: string[],
59
- networks?: string[],
60
- environment?: DockerComposeEnvDef,
61
- links?: string[],
62
- ulimits?: DockerComposeULimitsDef,
63
- };
64
-
65
- type DockerComposeVolumeDef = {
66
- name?: string,
67
- };
68
-
69
- type DockerComposeNetworkDef = {
70
- ...DockerNetworkCreateOptions,
71
- name?: string,
72
- };
73
-
74
- type DockerCompose = {
75
- version: string,
76
- services?: {
77
- [string]: DockerComposeServiceDef,
78
- },
79
- volumes?: {
80
- [string]: DockerComposeVolumeDef,
81
- },
82
- networks?: {
83
- [string]: DockerComposeNetworkDef,
84
- },
85
- };
86
-
87
31
  /**
88
32
  * Parse a docker-compose.yml file into a pojo representation
89
33
  * @param {string} filePath Path to the docker-compose.yml file
90
34
  */
91
- export const dockerComposeParse = async (
92
- filePath?: string = './docker-compose.yml',
93
- ): Promise<DockerCompose> => (yaml.load(await fs.readFile(filePath)): any);
94
-
95
- let dc: ?DockerCompose = null;
96
-
35
+ export const dockerComposeParse = async (filePath = './docker-compose.yml') => yaml.load(await fs.readFile(filePath, 'utf8'));
36
+ let dc = null;
97
37
  /**
98
38
  * Get the main docker-compose.yml from the root of the repo
99
39
  * @param {boolean} force Force reload from file
100
40
  */
101
- export const dockerComposeGetMain = async (
102
- force?: boolean = false,
103
- ): Promise<DockerCompose> => {
104
- if (force || !dc) {
105
- dc = await dockerComposeParse();
106
- }
107
- return dc;
41
+ export const dockerComposeGetMain = async (force = false) => {
42
+ if (force || !dc) {
43
+ dc = await dockerComposeParse();
44
+ }
45
+ return dc;
108
46
  };
109
-
110
47
  // Function that handles passed dockerCompose as either a file path or `DockerCompose` object.
111
48
  // If not passed, defaults to the main docker-compose.yml from the root of the repo
112
- const dockerComposeResolve = async (
113
- dockerCompose?: ?(string | DockerCompose),
114
- force?: boolean,
115
- ): Promise<DockerCompose> =>
116
- typeof dockerCompose === 'string'
49
+ const dockerComposeResolve = async (dockerCompose, force) => typeof dockerCompose === 'string'
117
50
  ? dockerComposeParse(dockerCompose)
118
51
  : dockerCompose || dockerComposeGetMain(force);
119
-
120
52
  // Determines an unnamed resource's name from the dirname combined with the key
121
- const prefixName = (name: string) => `${path.basename(__dirname)}_${name}`;
122
-
123
- const getServiceDef = async (
124
- name: string,
125
- force?: boolean,
126
- dockerCompose?: ?(string | DockerCompose),
127
- ): Promise<?DockerComposeServiceDef> =>
128
- (await dockerComposeResolve(dockerCompose, force)).services?.[name] || null;
129
-
130
- type PortMap = {
131
- local: ?number,
132
- localDefault: number,
133
- docker: number,
134
- };
135
-
136
- type UrlMap = {
137
- local: ?string,
138
- docker: ?string,
53
+ const prefixName = (name) => `${path.basename(__dirname)}_${name}`;
54
+ const getServiceDef = async (name, force, dockerCompose) => (await dockerComposeResolve(dockerCompose, force)).services?.[name] || null;
55
+ const parsePorts = async (portsCfg = [], avoidConflicts = true, mapLocal = true, host = '0.0.0.0') => {
56
+ const ports = [];
57
+ const runArgs = await portsCfg.reduce(async (args, portStr) => {
58
+ const [lp, dp] = portStr.split(':');
59
+ const localDefault = parseInt(lp, 10);
60
+ const docker = parseInt(dp, 10);
61
+ const local = mapLocal
62
+ ? avoidConflicts
63
+ ? await getPort({ host, port: localDefault })
64
+ : localDefault
65
+ : null;
66
+ ports.push({ docker, local, localDefault });
67
+ return local ? [...(await args), '-p', `${local}:${docker}`] : args;
68
+ }, Promise.resolve([]));
69
+ return { ports, runArgs };
139
70
  };
140
-
141
- type ParsedPortInfo = {
142
- runArgs: string[],
143
- ports: PortMap[],
144
- };
145
-
146
- const parsePorts = async (
147
- portsCfg?: string[] = [],
148
- avoidConflicts?: boolean = true,
149
- mapLocal?: boolean = true,
150
- host?: string = '0.0.0.0',
151
- ): Promise<ParsedPortInfo> => {
152
- const ports: PortMap[] = [];
153
- const runArgs = await portsCfg.reduce(async (args, portStr) => {
154
- const [lp, dp] = portStr.split(':');
155
- const localDefault = parseInt(lp, 10);
156
- const docker = parseInt(dp, 10);
157
- const local = mapLocal
158
- ? avoidConflicts
159
- ? await getPort({ port: localDefault, host })
160
- : localDefault
161
- : null;
162
- ports.push({ local, localDefault, docker });
163
- return local ? [...(await args), '-p', `${local}:${docker}`] : args;
164
- }, []);
165
- return { runArgs, ports };
166
- };
167
-
168
- const parseEnv = (env?: DockerComposeEnvDef = []): string[] =>
169
- Array.isArray(env)
71
+ const parseEnv = (env = []) => Array.isArray(env)
170
72
  ? env.flatMap((e) => ['-e', e])
171
- : entries(env).flatMap(([k, v]) => ['-e', `${k}=${v}`]);
172
-
173
- const parseULimits = (ul?: DockerComposeULimitsDef = {}): string[] =>
174
- entries(ul).flatMap(([k, v]) => [
73
+ : Object.entries(env).flatMap(([k, v]) => ['-e', `${k}=${v}`]);
74
+ const parseULimits = (ul = {}) => Object.entries(ul).flatMap(([k, v]) => [
175
75
  '--ulimit',
176
- `${k}=${
177
- typeof v === 'number' ? v : `${v.soft}${v.hard ? `:${v.hard}` : ''}`
178
- }`,
179
- ]);
180
-
181
- type ParsedVolumeInfo = {
182
- runArgs: string[],
183
- volumes: string[],
184
- };
185
-
186
- const parseVolumes = async (
187
- volCfg?: string[] = [],
188
- nameSuffix?: string = '',
189
- dockerCompose?: ?(string | DockerCompose),
190
- ): Promise<ParsedVolumeInfo> => {
191
- const { volumes: volMap } = await dockerComposeResolve(dockerCompose);
192
- const volumes = [];
193
- const runArgs: string[] = volCfg
194
- .map((v) => {
195
- const [src, ...rest] = v.split(':');
196
- const name = volMap?.[src]
197
- ? `${volMap[src].name || prefixName(src)}${nameSuffix}`
198
- : null;
199
- if (name) {
200
- volumes.push(name);
201
- }
202
- const realSrc = name || path.resolve(src);
203
- return [realSrc, ...rest].join(':');
76
+ `${k}=${typeof v === 'number' ? v : `${v.soft}${v.hard ? `:${v.hard}` : ''}`}`,
77
+ ]);
78
+ const parseVolumes = async (volCfg = [], nameSuffix = '', dockerCompose = null) => {
79
+ const { volumes: volMap } = await dockerComposeResolve(dockerCompose);
80
+ const volumes = [];
81
+ const runArgs = volCfg
82
+ .map((v) => {
83
+ const [src, ...rest] = v.split(':');
84
+ const name = volMap?.[src]
85
+ ? `${volMap[src].name || prefixName(src)}${nameSuffix}`
86
+ : null;
87
+ if (name) {
88
+ volumes.push(name);
89
+ }
90
+ const realSrc = name || path.resolve(src);
91
+ return [realSrc, ...rest].join(':');
204
92
  })
205
- .flatMap((v) => ['-v', v]);
206
- return { runArgs, volumes };
207
- };
208
-
209
- type ParsedNetworkInfo = {
210
- runArgs: string[],
211
- networks: string[],
93
+ .flatMap((v) => ['-v', v]);
94
+ return { runArgs, volumes };
212
95
  };
213
-
214
- const parseNetworks = async (
215
- netCfg?: string[] = [],
216
- dockerCompose?: ?(string | DockerCompose),
217
- ): Promise<ParsedNetworkInfo> => {
218
- const { networks: netMap } = await dockerComposeResolve(dockerCompose);
219
- const networks = netCfg.map((n) => netMap?.[n].name || prefixName(n));
220
- return {
221
- networks,
222
- runArgs: (networks.flatMap((n) => ['--network', n]): string[]),
223
- };
96
+ const parseNetworks = async (netCfg = [], dockerCompose = null) => {
97
+ const { networks: netMap } = await dockerComposeResolve(dockerCompose);
98
+ const networks = netCfg.map((n) => netMap?.[n].name || prefixName(n));
99
+ return {
100
+ networks,
101
+ runArgs: networks.flatMap((n) => ['--network', n]),
102
+ };
224
103
  };
225
-
226
- export const dockerComposeCreateNetworks = async (
227
- names?: ?(string[]),
228
- dockerCompose?: ?(string | DockerCompose),
229
- tracker?: DockerComposeResourceTracker = defaultTracker,
230
- ) => {
231
- const { networks = {} } = await dockerComposeResolve(dockerCompose);
232
- await Promise.all(
233
- entries(networks).map(async ([key, val]) => {
234
- const name = val?.name || prefixName(key);
235
- if (!names || names.includes(name)) {
236
- const network = await dockerNetworkCreate(name, (val || {}: any));
237
- if (network) {
238
- tracker.networks.set(name, network);
104
+ export const dockerComposeCreateNetworks = async (names, dockerCompose, tracker = defaultTracker) => {
105
+ const { networks = {} } = await dockerComposeResolve(dockerCompose);
106
+ await Promise.all(Object.entries(networks).map(async ([key, val]) => {
107
+ const name = val?.name || prefixName(key);
108
+ if (names?.includes(name)) {
109
+ const network = await dockerNetworkCreate(name, val);
110
+ if (network) {
111
+ tracker.networks.set(name, network);
112
+ }
239
113
  }
240
- }
241
- }),
242
- );
114
+ }));
243
115
  };
244
-
245
- export const dockerComposeCreateVolumes = async (
246
- names?: string[],
247
- dockerCompose?: ?(string | DockerCompose),
248
- tracker?: DockerComposeResourceTracker = defaultTracker,
249
- ) => {
250
- const { volumes = {} } = await dockerComposeResolve(dockerCompose);
251
- await Promise.all(
252
- entries(volumes).map(async ([key, val]) => {
253
- const name = val?.name || prefixName(key);
254
- if (!names || names.includes(name)) {
255
- const volume = await dockerVolumeCreate(name, (val || {}: any));
256
- if (volume) {
257
- tracker.volumes.set(name, volume);
116
+ export const dockerComposeCreateVolumes = async (names, dockerCompose, tracker = defaultTracker) => {
117
+ const { volumes = {} } = await dockerComposeResolve(dockerCompose);
118
+ await Promise.all(Object.entries(volumes).map(async ([key, val]) => {
119
+ const name = val?.name || prefixName(key);
120
+ if (!names || names.includes(name)) {
121
+ const volume = await dockerVolumeCreate(name, val);
122
+ if (volume) {
123
+ tracker.volumes.set(name, volume);
124
+ }
258
125
  }
259
- }
260
- }),
261
- );
262
- };
263
-
264
- type HealthCheckFn = (UpResult) => Promise<void>;
265
-
266
- type UpOptions = {
267
- healthCheck?: HealthCheckFn,
268
- avoidConflicts?: boolean,
269
- mapVolumes?: boolean,
270
- mapPorts?: boolean,
271
- cmd?: string[],
272
- tracker?: DockerComposeResourceTracker,
273
- };
274
-
275
- type ServiceNameInfo = {
276
- name: string,
277
- aliases: string[],
278
- suffix: string,
126
+ }));
279
127
  };
280
-
281
- type UpResult = {|
282
- service: DockerComposeService,
283
- container: DockerContainer,
284
- containerName: string,
285
- aliases: string[],
286
- ports: PortMap[],
287
- urls: UrlMap[],
288
- volumes: string[],
289
- |};
290
-
291
128
  export class DockerComposeService {
292
- #name: string;
293
- #svcDef: DockerComposeServiceDef;
294
- #dockerCompose: ?(DockerCompose | string);
295
- #tracker: DockerComposeResourceTracker = dockerComposeCreateResourceTracker();
296
-
297
- // lazily computed
298
- #parsedPorts: ?ParsedPortInfo = null;
299
- #parsedNetworks: ?ParsedNetworkInfo = null;
300
- #parsedVolumes: ?ParsedVolumeInfo = null;
301
- #baseRunArgs: ?(string[]) = null;
302
-
303
- constructor(
304
- name: string,
305
- serviceDef: DockerComposeServiceDef,
306
- dockerCompose?: ?(DockerCompose | string),
307
- ) {
308
- this.#name = name;
309
- this.#svcDef = serviceDef;
310
- this.#dockerCompose = dockerCompose || null;
311
- }
312
-
313
- get name(): string {
314
- return this.#name;
315
- }
316
-
317
- get serviceDef(): DockerComposeServiceDef {
318
- return this.#svcDef;
319
- }
320
-
321
- get image(): ?string {
322
- return this.#svcDef.image || null;
323
- }
324
-
325
- get defaultContainerName(): string {
326
- return this.#svcDef.container_name || this.#name;
327
- }
328
-
329
- get cmd(): string[] {
330
- return this.#svcDef.command || [];
331
- }
332
-
333
- get envArgs(): string[] {
334
- return parseEnv(this.#svcDef.environment);
335
- }
336
-
337
- /**
338
- * Find (available) container name and alias(es)
339
- * @param {boolean} avoidConflicts if `true`, find a container name that is unused
340
- * @param {number} max maximum number of names to try
341
- */
342
- async getNames(
343
- avoidConflicts?: boolean = false,
344
- max?: number = 100,
345
- ): Promise<ServiceNameInfo> {
346
- /* eslint-disable no-await-in-loop */
347
- for (let i = 0; i < max; i += 1) {
348
- const suffix = i ? `-${i}` : '';
349
- const testName = `${this.defaultContainerName}${suffix}`;
350
- const container = await dockerContainerFind(testName, { all: true });
351
- if (!avoidConflicts || !container) {
352
- return {
353
- name: testName,
354
- aliases: [`${this.name}${suffix}`],
355
- suffix,
356
- };
357
- }
129
+ constructor(name, serviceDef, dockerCompose) {
130
+ _DockerComposeService_name.set(this, void 0);
131
+ _DockerComposeService_svcDef.set(this, void 0);
132
+ _DockerComposeService_dockerCompose.set(this, void 0);
133
+ _DockerComposeService_tracker.set(this, dockerComposeCreateResourceTracker());
134
+ // lazily computed
135
+ _DockerComposeService_parsedPorts.set(this, null);
136
+ _DockerComposeService_parsedNetworks.set(this, null);
137
+ _DockerComposeService_parsedVolumes.set(this, null);
138
+ _DockerComposeService_baseRunArgs.set(this, null);
139
+ __classPrivateFieldSet(this, _DockerComposeService_name, name, "f");
140
+ __classPrivateFieldSet(this, _DockerComposeService_svcDef, serviceDef, "f");
141
+ __classPrivateFieldSet(this, _DockerComposeService_dockerCompose, dockerCompose || null, "f");
358
142
  }
359
- /* eslint-enable no-await-in-loop */
360
- throw new Error(
361
- `Failed to find available container name for ${this.defaultContainerName}`,
362
- );
363
- }
364
-
365
- // Get (available) port mappings
366
- async getPorts(
367
- avoidConflicts?: boolean = false,
368
- mapLocal?: boolean = true,
369
- ): Promise<ParsedPortInfo> {
370
- return parsePorts(this.#svcDef.ports, avoidConflicts, mapLocal);
371
- }
372
-
373
- async getDefaultPortInfo(): Promise<ParsedPortInfo> {
374
- if (!this.#parsedPorts) {
375
- this.#parsedPorts = await this.getPorts();
143
+ get name() {
144
+ return __classPrivateFieldGet(this, _DockerComposeService_name, "f");
376
145
  }
377
- return this.#parsedPorts;
378
- }
379
-
380
- async getDefaultPorts(): Promise<PortMap[]> {
381
- const { ports } = await this.getDefaultPortInfo();
382
- return ports;
383
- }
384
-
385
- async getDefaultPortArgs(): Promise<string[]> {
386
- const { runArgs } = await this.getDefaultPortInfo();
387
- return runArgs;
388
- }
389
-
390
- async getDefaultUrls(): Promise<UrlMap[]> {
391
- return this.constructor.getUrls(
392
- await this.getDefaultPorts(),
393
- this.defaultContainerName,
394
- );
395
- }
396
-
397
- async getDefaultNetworkInfo(): Promise<ParsedNetworkInfo> {
398
- if (!this.#parsedNetworks) {
399
- this.#parsedNetworks = await parseNetworks(this.#svcDef.networks);
146
+ get serviceDef() {
147
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f");
400
148
  }
401
- return this.#parsedNetworks;
402
- }
403
-
404
- async getDefaultNetworks(): Promise<string[]> {
405
- const { networks } = await this.getDefaultNetworkInfo();
406
- return networks;
407
- }
408
-
409
- async getDefaultNetworkArgs(): Promise<string[]> {
410
- const { runArgs } = await this.getDefaultNetworkInfo();
411
- return runArgs;
412
- }
413
-
414
- async getDefaultVolumeInfo(): Promise<ParsedVolumeInfo> {
415
- if (!this.#parsedVolumes) {
416
- this.#parsedVolumes = await parseVolumes(this.#svcDef.networks);
149
+ get image() {
150
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").image || null;
417
151
  }
418
- return this.#parsedVolumes;
419
- }
420
-
421
- async getDefaultVolumes(): Promise<string[]> {
422
- const { volumes } = await this.getDefaultVolumeInfo();
423
- return volumes;
424
- }
425
-
426
- async getDefaultVolumeArgs(): Promise<string[]> {
427
- const { runArgs } = await this.getDefaultVolumeInfo();
428
- return runArgs;
429
- }
430
-
431
- async pull() {
432
- if (!this.image) {
433
- throw new Error(`Cannot pull '${this.name}', no image configured.`);
152
+ get defaultContainerName() {
153
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").container_name || __classPrivateFieldGet(this, _DockerComposeService_name, "f");
434
154
  }
435
- await dockerPull({ image: this.image });
436
- }
437
-
438
- async getBaseRunArgs(): Promise<string[]> {
439
- if (!this.#baseRunArgs) {
440
- const envArgs = parseEnv(this.#svcDef.environment);
441
- const ulArgs = parseULimits(this.#svcDef.ulimits);
442
- const netArgs = await this.getDefaultNetworkArgs();
443
-
444
- this.#baseRunArgs = ['--rm', ...envArgs, ...netArgs, ...ulArgs];
155
+ get cmd() {
156
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").command || [];
445
157
  }
446
- return this.#baseRunArgs;
447
- }
448
-
449
- async assembleRunArgs(
450
- containerName?: string = this.defaultContainerName,
451
- aliases?: string[] = [this.name],
452
- additionalArgs?: string[],
453
- ): Promise<string[]> {
454
- const additional = additionalArgs || [
455
- ...(await this.getDefaultPortArgs()),
456
- ...(await this.getDefaultVolumeArgs()),
457
- ];
458
- return [
459
- ...(await this.getBaseRunArgs()),
460
- ...(containerName ? ['--name', containerName] : []),
461
- ...aliases.flatMap((a) => (a ? ['--network-alias', a] : [])),
462
- ...additional,
463
- ];
464
- }
465
-
466
- async getRunArgs(
467
- avoidConflicts?: boolean = false,
468
- mapLocalPorts?: boolean = true,
469
- ): Promise<string[]> {
470
- const { name: cName, aliases, suffix } = await this.getNames(
471
- avoidConflicts,
472
- );
473
- const { runArgs: pArgs } = await this.getPorts(
474
- avoidConflicts,
475
- mapLocalPorts,
476
- );
477
- const { runArgs: vArgs } = await parseVolumes(this.#svcDef.volumes, suffix);
478
- return this.assembleRunArgs(cName, aliases, [...pArgs, ...vArgs]);
479
- }
480
-
481
- async up({
482
- healthCheck,
483
- avoidConflicts = false,
484
- mapVolumes = true,
485
- mapPorts = true,
486
- cmd = this.cmd,
487
- tracker = defaultTracker,
488
- }: UpOptions = {}): Promise<UpResult> {
489
- const { image } = this;
490
- if (!image) {
491
- throw new Error(
492
- `Cannot bring up service '${this.name}', no image defined.`,
493
- );
158
+ get envArgs() {
159
+ return parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
494
160
  }
495
- if (this.#tracker.containers.size) {
496
- buildLog(
497
- `Warning: up called on service '${this.name}' with already running container`,
498
- );
161
+ /**
162
+ * Find (available) container name and alias(es)
163
+ * @param {boolean} avoidConflicts if `true`, find a container name that is unused
164
+ * @param {number} max maximum number of names to try
165
+ */
166
+ async getNames(avoidConflicts = false, max = 100) {
167
+ /* eslint-disable no-await-in-loop */
168
+ for (let i = 0; i < max; i += 1) {
169
+ const suffix = i ? `-${i}` : '';
170
+ const testName = `${this.defaultContainerName}${suffix}`;
171
+ const container = await dockerContainerFind(testName, { all: true });
172
+ if (!avoidConflicts || !container) {
173
+ return {
174
+ aliases: [`${this.name}${suffix}`],
175
+ name: testName,
176
+ suffix,
177
+ };
178
+ }
179
+ }
180
+ /* eslint-enable no-await-in-loop */
181
+ throw new Error(`Failed to find available container name for ${this.defaultContainerName}`);
499
182
  }
500
- const { name: containerName, aliases, suffix } = await this.getNames(
501
- avoidConflicts,
502
- );
503
- const { runArgs: pArgs, ports } = await this.getPorts(
504
- avoidConflicts,
505
- mapPorts,
506
- );
507
- const { runArgs: vArgs, volumes } = mapVolumes
508
- ? await parseVolumes(this.#svcDef.volumes, suffix)
509
- : { runArgs: [], volumes: [] };
510
-
511
- let container = await dockerContainerFind(containerName, { all: true });
512
- if (container && !(await container.isRunning())) {
513
- await container.start();
183
+ // Get (available) port mappings
184
+ async getPorts(avoidConflicts = false, mapLocal = true) {
185
+ return parsePorts(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ports, avoidConflicts, mapLocal);
514
186
  }
515
- if (!container) {
516
- await this.pull();
517
- await dockerComposeCreateNetworks(
518
- await this.getDefaultNetworks(),
519
- this.#dockerCompose,
520
- this.#tracker,
521
- );
522
- await dockerComposeCreateVolumes(
523
- volumes,
524
- this.#dockerCompose,
525
- this.#tracker,
526
- );
527
- const runArgs = await this.assembleRunArgs(containerName, aliases, [
528
- ...pArgs,
529
- ...vArgs,
530
- ]);
531
- container = await dockerContainerRunDaemon({
532
- image,
533
- runArgs,
534
- cmd,
535
- });
536
- } else {
537
- buildLog(`Reusing existing container for '${this.name}' service.`);
187
+ async getDefaultPortInfo() {
188
+ if (!__classPrivateFieldGet(this, _DockerComposeService_parsedPorts, "f")) {
189
+ __classPrivateFieldSet(this, _DockerComposeService_parsedPorts, await this.getPorts(), "f");
190
+ }
191
+ return __classPrivateFieldGet(this, _DockerComposeService_parsedPorts, "f");
538
192
  }
539
- // This service tracks the things it created
540
- this.#tracker.containers.set(containerName, container);
541
- // The passed tracker needs to track this service
542
- tracker.services.set(this.name, this);
543
-
544
- const idAlias = container.id.slice(0, 12);
545
- aliases.push(idAlias);
546
- const urls = this.constructor.getUrls(ports, idAlias);
547
-
548
- const info: UpResult = {
549
- service: this,
550
- container,
551
- containerName,
552
- aliases,
553
- ports,
554
- volumes,
555
- urls,
556
- };
557
- await healthCheck?.(info);
558
- return info;
559
- }
560
-
561
- async down({
562
- includeDefaults = false,
563
- includeVolumes = false,
564
- includeNetworks = false,
565
- }: {
566
- includeDefaults?: boolean,
567
- includeVolumes?: boolean,
568
- includeNetworks?: boolean,
569
- } = {}) {
570
- buildLog(`Bringing down <${this.name}> service...`);
571
- await dockerComposeTeardown({
572
- tracker: this.#tracker,
573
- includeVolumes,
574
- includeNetworks,
575
- });
576
- if (includeDefaults) {
577
- const container = await dockerContainerFind(this.defaultContainerName);
578
- if (container) {
579
- await container.teardown(true);
580
- }
193
+ async getDefaultPorts() {
194
+ const { ports } = await this.getDefaultPortInfo();
195
+ return ports;
581
196
  }
582
- }
583
-
584
- static async parse(
585
- name: string,
586
- force?: boolean = true,
587
- dockerCompose?: ?(DockerCompose | string),
588
- ): Promise<?DockerComposeService> {
589
- const svcDef = await getServiceDef(name, force, dockerCompose);
590
- return svcDef ? new this(name, svcDef, dockerCompose) : null;
591
- }
592
-
593
- static getUrls(ports: PortMap[], alias: string): UrlMap[] {
594
- return ports.map(({ local, docker }) => ({
595
- local: local ? `http://localhost:${local}` : null,
596
- docker: docker ? `http://${alias}:${docker}` : null,
597
- }));
598
- }
599
- }
600
-
601
- export async function dockerComposeGetAllServices(
602
- dockerCompose?: ?(string | DockerCompose),
603
- ): Promise<MapObj<string, DockerComposeService>> {
604
- const { services } = await dockerComposeResolve(dockerCompose);
605
- return mapValuesAsync(services, (s, name) =>
606
- DockerComposeService.parse(name),
607
- );
608
- }
609
-
610
- export async function dockerComposeTeardown({
611
- includeDefaults = false,
612
- includeVolumes = false,
613
- includeNetworks = false,
614
- dockerCompose,
615
- tracker = defaultTracker,
616
- }: {
617
- includeDefaults?: boolean,
618
- includeVolumes?: boolean,
619
- includeNetworks?: boolean,
620
- dockerCompose?: ?(string | DockerCompose),
621
- tracker?: DockerComposeResourceTracker,
622
- } = {}): Promise<void> {
623
- if (!tracker.cleaning) {
624
- // eslint-disable-next-line no-param-reassign
625
- tracker.cleaning = (async () => {
626
- if (tracker.services.size) {
627
- buildLog('Bringing down started docker services...');
628
- const promises = Promise.all(
629
- Array.from(tracker.services.values()).map(async (s) =>
630
- s.down({ includeVolumes, includeNetworks }),
631
- ),
632
- );
633
- tracker.services.clear();
634
- await promises;
635
- }
636
- if (includeDefaults) {
637
- const { services } = await dockerComposeResolve(dockerCompose);
638
- const svcNames = keys(services);
639
- if (svcNames.length) {
640
- buildLog('Bringing down default docker services...');
641
- await Promise.all(
642
- svcNames.map(async (s) =>
643
- (await DockerComposeService.parse(s))?.down({
644
- includeDefaults,
645
- includeVolumes,
646
- includeNetworks,
647
- }),
648
- ),
649
- );
197
+ async getDefaultPortArgs() {
198
+ const { runArgs } = await this.getDefaultPortInfo();
199
+ return runArgs;
200
+ }
201
+ async getDefaultUrls() {
202
+ return DockerComposeService.getUrls(await this.getDefaultPorts(), this.defaultContainerName);
203
+ }
204
+ async getDefaultNetworkInfo() {
205
+ if (!__classPrivateFieldGet(this, _DockerComposeService_parsedNetworks, "f")) {
206
+ __classPrivateFieldSet(this, _DockerComposeService_parsedNetworks, await parseNetworks(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").networks), "f");
650
207
  }
651
- }
652
-
653
- if (tracker.containers.size) {
654
- buildLog('Stopping created docker containers...');
655
- const promises = Promise.all(
656
- Array.from(tracker.containers.values()).map(async (c) =>
657
- c.teardown(true),
658
- ),
659
- );
660
- tracker.containers.clear();
661
- await promises;
662
- }
663
-
664
- if (includeVolumes) {
665
- if (tracker.volumes.size) {
666
- buildLog('Removing created docker volumes...');
667
- const promises = Promise.all(
668
- Array.from(tracker.volumes.values()).map(async (v) => v.rm()),
669
- );
670
- tracker.volumes.clear();
671
- await promises;
208
+ return __classPrivateFieldGet(this, _DockerComposeService_parsedNetworks, "f");
209
+ }
210
+ async getDefaultNetworks() {
211
+ const { networks } = await this.getDefaultNetworkInfo();
212
+ return networks;
213
+ }
214
+ async getDefaultNetworkArgs() {
215
+ const { runArgs } = await this.getDefaultNetworkInfo();
216
+ return runArgs;
217
+ }
218
+ async getDefaultVolumeInfo() {
219
+ if (!__classPrivateFieldGet(this, _DockerComposeService_parsedVolumes, "f")) {
220
+ __classPrivateFieldSet(this, _DockerComposeService_parsedVolumes, await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").networks), "f");
672
221
  }
673
- if (includeDefaults) {
674
- buildLog('Removing default docker volumes...');
675
- const { volumes } = await dockerComposeResolve(dockerCompose);
676
- await Promise.all(
677
- entries(volumes).map(async ([key, val]) => {
678
- const name = val?.name || prefixName(key);
679
- await dockerVolumeRm(name, true);
680
- }),
681
- );
222
+ return __classPrivateFieldGet(this, _DockerComposeService_parsedVolumes, "f");
223
+ }
224
+ async getDefaultVolumes() {
225
+ const { volumes } = await this.getDefaultVolumeInfo();
226
+ return volumes;
227
+ }
228
+ async getDefaultVolumeArgs() {
229
+ const { runArgs } = await this.getDefaultVolumeInfo();
230
+ return runArgs;
231
+ }
232
+ async pull() {
233
+ if (!this.image) {
234
+ throw new Error(`Cannot pull '${this.name}', no image configured.`);
235
+ }
236
+ await dockerPull({ image: this.image });
237
+ }
238
+ async getBaseRunArgs() {
239
+ if (!__classPrivateFieldGet(this, _DockerComposeService_baseRunArgs, "f")) {
240
+ const envArgs = parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
241
+ const ulArgs = parseULimits(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ulimits);
242
+ const netArgs = await this.getDefaultNetworkArgs();
243
+ __classPrivateFieldSet(this, _DockerComposeService_baseRunArgs, ['--rm', ...envArgs, ...netArgs, ...ulArgs], "f");
244
+ }
245
+ return __classPrivateFieldGet(this, _DockerComposeService_baseRunArgs, "f");
246
+ }
247
+ async assembleRunArgs(containerName = this.defaultContainerName, aliases = [this.name], additionalArgs = null) {
248
+ const additional = additionalArgs || [
249
+ ...(await this.getDefaultPortArgs()),
250
+ ...(await this.getDefaultVolumeArgs()),
251
+ ];
252
+ return [
253
+ ...(await this.getBaseRunArgs()),
254
+ ...(containerName ? ['--name', containerName] : []),
255
+ ...aliases.flatMap((a) => (a ? ['--network-alias', a] : [])),
256
+ ...additional,
257
+ ];
258
+ }
259
+ async getRunArgs(avoidConflicts = false, mapLocalPorts = true) {
260
+ const { aliases, name: cName, suffix, } = await this.getNames(avoidConflicts);
261
+ const { runArgs: pArgs } = await this.getPorts(avoidConflicts, mapLocalPorts);
262
+ const { runArgs: vArgs } = await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").volumes, suffix);
263
+ return this.assembleRunArgs(cName, aliases, [...pArgs, ...vArgs]);
264
+ }
265
+ async up({ healthCheck, avoidConflicts = false, mapVolumes = true, mapPorts = true, cmd = this.cmd, tracker = defaultTracker, } = {}) {
266
+ const { image } = this;
267
+ if (!image) {
268
+ throw new Error(`Cannot bring up service '${this.name}', no image defined.`);
682
269
  }
683
- }
684
-
685
- if (includeNetworks) {
686
- if (tracker.networks.size) {
687
- buildLog('Removing created docker networks...');
688
- const promises = Promise.all(
689
- Array.from(tracker.networks.values()).map(async (n) => n.rm()),
690
- );
691
- tracker.networks.clear();
692
- await promises;
270
+ if (__classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.size) {
271
+ buildLog(`Warning: up called on service '${this.name}' with already running container`);
693
272
  }
273
+ const { aliases, name: containerName, suffix, } = await this.getNames(avoidConflicts);
274
+ const { ports, runArgs: pArgs } = await this.getPorts(avoidConflicts, mapPorts);
275
+ const { runArgs: vArgs, volumes } = mapVolumes
276
+ ? await parseVolumes(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").volumes, suffix)
277
+ : { runArgs: [], volumes: [] };
278
+ let container = await dockerContainerFind(containerName, { all: true });
279
+ if (container && !(await container.isRunning())) {
280
+ await container.start();
281
+ }
282
+ if (!container) {
283
+ await this.pull();
284
+ await dockerComposeCreateNetworks(await this.getDefaultNetworks(), __classPrivateFieldGet(this, _DockerComposeService_dockerCompose, "f"), __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"));
285
+ await dockerComposeCreateVolumes(volumes, __classPrivateFieldGet(this, _DockerComposeService_dockerCompose, "f"), __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"));
286
+ const runArgs = await this.assembleRunArgs(containerName, aliases, [
287
+ ...pArgs,
288
+ ...vArgs,
289
+ ]);
290
+ container = await dockerContainerRunDaemon({
291
+ cmd,
292
+ image,
293
+ runArgs,
294
+ });
295
+ }
296
+ else {
297
+ buildLog(`Reusing existing container for '${this.name}' service.`);
298
+ }
299
+ // This service tracks the things it created
300
+ __classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.set(containerName, container);
301
+ // The passed tracker needs to track this service
302
+ tracker.services.set(this.name, this);
303
+ const idAlias = container.id.slice(0, 12);
304
+ aliases.push(idAlias);
305
+ const urls = DockerComposeService.getUrls(ports, idAlias);
306
+ const info = {
307
+ aliases,
308
+ container,
309
+ containerName,
310
+ ports,
311
+ service: this,
312
+ urls,
313
+ volumes,
314
+ };
315
+ await healthCheck?.(info);
316
+ return info;
317
+ }
318
+ async down({ includeDefaults = false, includeNetworks = false, includeVolumes = false, } = {}) {
319
+ buildLog(`Bringing down <${this.name}> service...`);
320
+ await dockerComposeTeardown({
321
+ includeNetworks,
322
+ includeVolumes,
323
+ tracker: __classPrivateFieldGet(this, _DockerComposeService_tracker, "f"),
324
+ });
694
325
  if (includeDefaults) {
695
- buildLog('Removing default docker networks...');
696
- const { networks } = await dockerComposeResolve(dockerCompose);
697
- await Promise.all(
698
- entries(networks).map(async ([key, val]) => {
699
- const name = val?.name || prefixName(key);
700
- try {
701
- await dockerNetworkDelete(name);
702
- } catch (err) {
703
- buildLog(`Error deleting network '${name}': ${err.message}`);
704
- }
705
- }),
706
- );
326
+ const container = await dockerContainerFind(this.defaultContainerName);
327
+ if (container) {
328
+ await container.teardown(true);
329
+ }
707
330
  }
708
- }
709
- // eslint-disable-next-line no-param-reassign
710
- tracker.cleaning = null;
711
- })();
712
- }
713
- return tracker.cleaning;
331
+ }
332
+ static async parse(name, force = true, dockerCompose = null) {
333
+ const svcDef = await getServiceDef(name, force, dockerCompose);
334
+ return svcDef ? new this(name, svcDef, dockerCompose) : null;
335
+ }
336
+ static getUrls(ports, alias) {
337
+ return ports.map(({ docker, local }) => ({
338
+ docker: docker ? `http://${alias}:${docker}` : null,
339
+ local: local ? `http://localhost:${local}` : null,
340
+ }));
341
+ }
342
+ }
343
+ _DockerComposeService_name = new WeakMap(), _DockerComposeService_svcDef = new WeakMap(), _DockerComposeService_dockerCompose = new WeakMap(), _DockerComposeService_tracker = new WeakMap(), _DockerComposeService_parsedPorts = new WeakMap(), _DockerComposeService_parsedNetworks = new WeakMap(), _DockerComposeService_parsedVolumes = new WeakMap(), _DockerComposeService_baseRunArgs = new WeakMap();
344
+ export async function dockerComposeGetAllServices(dockerCompose) {
345
+ const { services } = await dockerComposeResolve(dockerCompose);
346
+ return mapValuesAsync(services, (s, name) => DockerComposeService.parse(name));
347
+ }
348
+ export async function dockerComposeTeardown({ includeDefaults = false, includeVolumes = false, includeNetworks = false, dockerCompose, tracker = defaultTracker, } = {}) {
349
+ if (!tracker.cleaning) {
350
+ // eslint-disable-next-line no-param-reassign
351
+ tracker.cleaning = (async () => {
352
+ if (tracker.services.size) {
353
+ buildLog('Bringing down started docker services...');
354
+ const promises = Promise.all(Array.from(tracker.services.values()).map(async (s) => s.down({ includeNetworks, includeVolumes })));
355
+ tracker.services.clear();
356
+ await promises;
357
+ }
358
+ if (includeDefaults) {
359
+ const { services } = await dockerComposeResolve(dockerCompose);
360
+ const svcNames = Object.keys(services ?? {});
361
+ if (svcNames.length) {
362
+ buildLog('Bringing down default docker services...');
363
+ await Promise.all(svcNames.map(async (s) => (await DockerComposeService.parse(s))?.down({
364
+ includeDefaults,
365
+ includeNetworks,
366
+ includeVolumes,
367
+ })));
368
+ }
369
+ }
370
+ if (tracker.containers.size) {
371
+ buildLog('Stopping created docker containers...');
372
+ const promises = Promise.all(Array.from(tracker.containers.values()).map(async (c) => c.teardown(true)));
373
+ tracker.containers.clear();
374
+ await promises;
375
+ }
376
+ if (includeVolumes) {
377
+ if (tracker.volumes.size) {
378
+ buildLog('Removing created docker volumes...');
379
+ const promises = Promise.all(Array.from(tracker.volumes.values()).map(async (v) => v.rm()));
380
+ tracker.volumes.clear();
381
+ await promises;
382
+ }
383
+ if (includeDefaults) {
384
+ buildLog('Removing default docker volumes...');
385
+ const { volumes } = await dockerComposeResolve(dockerCompose);
386
+ await Promise.all(Object.entries(volumes ?? {}).map(async ([key, val]) => {
387
+ const name = val?.name || prefixName(key);
388
+ await dockerVolumeRm(name, true);
389
+ }));
390
+ }
391
+ }
392
+ if (includeNetworks) {
393
+ if (tracker.networks.size) {
394
+ buildLog('Removing created docker networks...');
395
+ const promises = Promise.all(Array.from(tracker.networks.values()).map(async (n) => n.rm()));
396
+ tracker.networks.clear();
397
+ await promises;
398
+ }
399
+ if (includeDefaults) {
400
+ buildLog('Removing default docker networks...');
401
+ const { networks } = await dockerComposeResolve(dockerCompose);
402
+ await Promise.all(Object.entries(networks ?? {}).map(async ([key, val]) => {
403
+ const name = val?.name || prefixName(key);
404
+ try {
405
+ await dockerNetworkDelete(name);
406
+ }
407
+ catch (err) {
408
+ buildLog(`Error deleting network '${name}': ${err.message}`);
409
+ }
410
+ }));
411
+ }
412
+ }
413
+ // eslint-disable-next-line no-param-reassign
414
+ tracker.cleaning = null;
415
+ })();
416
+ }
417
+ return tracker.cleaning;
714
418
  }
715
-
716
- export type DockerContainerInfo = {|
717
- ...UpResult,
718
- id: string,
719
- image: string,
720
- name?: ?string,
721
-
722
- // for convenience, the first port mapping info
723
- port?: ?number,
724
- dockerPort?: ?number,
725
- url?: ?string,
726
- dockerUrl?: ?string,
727
- |};
728
-
729
- export async function dockerComposeRunService(
730
- key: string,
731
- upOptions?: UpOptions = {},
732
- dockerCompose?: ?(string | DockerCompose),
733
- ): Promise<DockerContainerInfo> {
734
- const service: ?DockerComposeService = await DockerComposeService.parse(
735
- key,
736
- false,
737
- dockerCompose,
738
- );
739
- if (!service) {
740
- throw new Error(`Failed to find service '${key}'`);
741
- }
742
- buildLog(`Starting <${service.name}> service...`);
743
- const upResult: UpResult = await service.up(upOptions);
744
- const {
745
- container,
746
- urls,
747
- urls: [{ local: url, docker: dockerUrl }],
748
- ports: [{ local: port, docker: dockerPort }],
749
- } = upResult;
750
- const { id, name, image } = container;
751
- urls.forEach(
752
- ({ local }) =>
753
- local && buildLog(`<${service.name}> accessible at ${local}`),
754
- );
755
- return {
756
- ...upResult,
757
- id,
758
- image,
759
- name,
760
- port,
761
- dockerPort,
762
- url,
763
- dockerUrl,
764
- };
419
+ export async function dockerComposeRunService(key, upOptions = {}, dockerCompose = null) {
420
+ const service = await DockerComposeService.parse(key, false, dockerCompose);
421
+ if (!service) {
422
+ throw new Error(`Failed to find service '${key}'`);
423
+ }
424
+ buildLog(`Starting <${service.name}> service...`);
425
+ const upResult = await service.up(upOptions);
426
+ const { container, urls, urls: [{ docker: dockerUrl, local: url }], ports: [{ docker: dockerPort, local: port }], } = upResult;
427
+ const { id, image, name } = container;
428
+ urls.forEach(({ local }) => local && buildLog(`<${service.name}> accessible at ${local}`));
429
+ return {
430
+ ...upResult,
431
+ dockerPort,
432
+ dockerUrl,
433
+ id,
434
+ image,
435
+ name,
436
+ port,
437
+ url,
438
+ };
765
439
  }