build-strap 3.0.0-dev.42 → 4.0.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 (130) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -34
  3. package/dist/src/ant.d.ts +19 -0
  4. package/dist/src/ant.js +18 -0
  5. package/dist/src/cert.d.ts +12 -0
  6. package/dist/src/cert.js +91 -0
  7. package/dist/src/clean.d.ts +4 -0
  8. package/dist/src/clean.js +11 -0
  9. package/dist/src/copy.d.ts +7 -0
  10. package/dist/src/copy.js +53 -0
  11. package/dist/src/cp.d.ts +17 -0
  12. package/dist/src/cp.js +88 -0
  13. package/dist/src/docker.container.d.ts +73 -0
  14. package/dist/src/docker.container.js +247 -0
  15. package/dist/src/docker.d.ts +68 -0
  16. package/dist/src/docker.js +188 -0
  17. package/dist/src/docker.network.d.ts +42 -0
  18. package/dist/src/docker.network.js +85 -0
  19. package/dist/src/docker.volume.d.ts +26 -0
  20. package/dist/src/docker.volume.js +62 -0
  21. package/dist/src/dockerCleanup.d.ts +38 -0
  22. package/dist/src/dockerCleanup.js +77 -0
  23. package/dist/src/dockerCompose.d.ts +154 -0
  24. package/dist/src/dockerCompose.js +439 -0
  25. package/dist/src/fs.d.ts +5 -0
  26. package/dist/src/fs.js +38 -0
  27. package/dist/src/git.d.ts +9 -0
  28. package/dist/src/git.js +24 -0
  29. package/dist/src/index.d.ts +20 -0
  30. package/dist/src/index.js +20 -0
  31. package/dist/src/maps.d.ts +33 -0
  32. package/dist/src/maps.js +41 -0
  33. package/dist/src/npm.d.ts +35 -0
  34. package/dist/src/npm.js +104 -0
  35. package/dist/src/pkg.d.ts +33 -0
  36. package/dist/src/pkg.js +33 -0
  37. package/dist/src/publish.d.ts +27 -0
  38. package/dist/src/publish.js +57 -0
  39. package/dist/src/run.d.ts +13 -0
  40. package/dist/src/run.js +44 -0
  41. package/dist/src/tgz.d.ts +13 -0
  42. package/dist/src/tgz.js +67 -0
  43. package/dist/src/version.d.ts +34 -0
  44. package/dist/src/version.js +101 -0
  45. package/dist/src/yarn.d.ts +26 -0
  46. package/dist/src/yarn.js +75 -0
  47. package/package.json +74 -20
  48. package/ant.js +0 -43
  49. package/ant.js.flow +0 -42
  50. package/artifactory.js +0 -617
  51. package/artifactory.js.flow +0 -616
  52. package/cert.conf +0 -20
  53. package/cert.js +0 -153
  54. package/cert.js.flow +0 -152
  55. package/clean.js +0 -20
  56. package/clean.js.flow +0 -19
  57. package/copy.js +0 -80
  58. package/copy.js.flow +0 -79
  59. package/cp.js +0 -173
  60. package/cp.js.flow +0 -172
  61. package/docker.container.js +0 -390
  62. package/docker.container.js.flow +0 -389
  63. package/docker.js +0 -368
  64. package/docker.js.flow +0 -367
  65. package/docker.network.js +0 -160
  66. package/docker.network.js.flow +0 -159
  67. package/docker.volume.js +0 -136
  68. package/docker.volume.js.flow +0 -136
  69. package/dockerCleanup.js +0 -152
  70. package/dockerCleanup.js.flow +0 -151
  71. package/dockerCompose.js +0 -766
  72. package/dockerCompose.js.flow +0 -765
  73. package/flow.js +0 -21
  74. package/flow.js.flow +0 -20
  75. package/fs.js +0 -95
  76. package/fs.js.flow +0 -96
  77. package/git.js +0 -35
  78. package/git.js.flow +0 -34
  79. package/hg.js +0 -35
  80. package/hg.js.flow +0 -34
  81. package/index.js +0 -27
  82. package/index.js.flow +0 -26
  83. package/inline-resources.js +0 -158
  84. package/inline-resources.js.flow +0 -157
  85. package/maps.js +0 -112
  86. package/maps.js.flow +0 -111
  87. package/npm.js +0 -145
  88. package/npm.js.flow +0 -144
  89. package/pkg.js +0 -81
  90. package/pkg.js.flow +0 -80
  91. package/publish.js +0 -145
  92. package/publish.js.flow +0 -144
  93. package/run.js +0 -90
  94. package/run.js.flow +0 -89
  95. package/src/ant.js +0 -42
  96. package/src/artifactory.js +0 -616
  97. package/src/cert.conf +0 -20
  98. package/src/cert.js +0 -152
  99. package/src/clean.js +0 -19
  100. package/src/copy.js +0 -79
  101. package/src/cp.js +0 -172
  102. package/src/docker.container.js +0 -389
  103. package/src/docker.js +0 -367
  104. package/src/docker.network.js +0 -159
  105. package/src/docker.volume.js +0 -136
  106. package/src/dockerCleanup.js +0 -151
  107. package/src/dockerCompose.js +0 -765
  108. package/src/flow.js +0 -20
  109. package/src/fs.js +0 -96
  110. package/src/git.js +0 -34
  111. package/src/hg.js +0 -34
  112. package/src/index.js +0 -26
  113. package/src/inline-resources.js +0 -157
  114. package/src/maps.js +0 -111
  115. package/src/npm.js +0 -144
  116. package/src/pkg.js +0 -80
  117. package/src/publish.js +0 -144
  118. package/src/run.js +0 -89
  119. package/src/test.js +0 -55
  120. package/src/tgz.js +0 -101
  121. package/src/version.js +0 -141
  122. package/src/yarn.js +0 -123
  123. package/test.js +0 -56
  124. package/test.js.flow +0 -55
  125. package/tgz.js +0 -102
  126. package/tgz.js.flow +0 -101
  127. package/version.js +0 -142
  128. package/version.js.flow +0 -141
  129. package/yarn.js +0 -124
  130. package/yarn.js.flow +0 -123
@@ -0,0 +1,439 @@
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;
13
+ import fs from 'fs-extra';
14
+ import getPort from 'get-port';
15
+ import yaml from 'js-yaml';
16
+ import path from 'path';
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(),
29
+ });
30
+ const defaultTracker = dockerComposeCreateResourceTracker();
31
+ /**
32
+ * Parse a docker-compose.yml file into a pojo representation
33
+ * @param {string} filePath Path to the docker-compose.yml file
34
+ */
35
+ export const dockerComposeParse = async (filePath = './docker-compose.yml') => yaml.load(await fs.readFile(filePath, 'utf8'));
36
+ let dc = null;
37
+ /**
38
+ * Get the main docker-compose.yml from the root of the repo
39
+ * @param {boolean} force Force reload from file
40
+ */
41
+ export const dockerComposeGetMain = async (force = false) => {
42
+ if (force || !dc) {
43
+ dc = await dockerComposeParse();
44
+ }
45
+ return dc;
46
+ };
47
+ // Function that handles passed dockerCompose as either a file path or `DockerCompose` object.
48
+ // If not passed, defaults to the main docker-compose.yml from the root of the repo
49
+ const dockerComposeResolve = async (dockerCompose, force) => typeof dockerCompose === 'string'
50
+ ? dockerComposeParse(dockerCompose)
51
+ : dockerCompose || dockerComposeGetMain(force);
52
+ // Determines an unnamed resource's name from the dirname combined with the key
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 };
70
+ };
71
+ const parseEnv = (env = []) => Array.isArray(env)
72
+ ? env.flatMap((e) => ['-e', e])
73
+ : Object.entries(env).flatMap(([k, v]) => ['-e', `${k}=${v}`]);
74
+ const parseULimits = (ul = {}) => Object.entries(ul).flatMap(([k, v]) => [
75
+ '--ulimit',
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(':');
92
+ })
93
+ .flatMap((v) => ['-v', v]);
94
+ return { runArgs, volumes };
95
+ };
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
+ };
103
+ };
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
+ }
113
+ }
114
+ }));
115
+ };
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
+ }
125
+ }
126
+ }));
127
+ };
128
+ export class DockerComposeService {
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");
142
+ }
143
+ get name() {
144
+ return __classPrivateFieldGet(this, _DockerComposeService_name, "f");
145
+ }
146
+ get serviceDef() {
147
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f");
148
+ }
149
+ get image() {
150
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").image || null;
151
+ }
152
+ get defaultContainerName() {
153
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").container_name || __classPrivateFieldGet(this, _DockerComposeService_name, "f");
154
+ }
155
+ get cmd() {
156
+ return __classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").command || [];
157
+ }
158
+ get envArgs() {
159
+ return parseEnv(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").environment);
160
+ }
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}`);
182
+ }
183
+ // Get (available) port mappings
184
+ async getPorts(avoidConflicts = false, mapLocal = true) {
185
+ return parsePorts(__classPrivateFieldGet(this, _DockerComposeService_svcDef, "f").ports, avoidConflicts, mapLocal);
186
+ }
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");
192
+ }
193
+ async getDefaultPorts() {
194
+ const { ports } = await this.getDefaultPortInfo();
195
+ return ports;
196
+ }
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");
207
+ }
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");
221
+ }
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.`);
269
+ }
270
+ if (__classPrivateFieldGet(this, _DockerComposeService_tracker, "f").containers.size) {
271
+ buildLog(`Warning: up called on service '${this.name}' with already running container`);
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
+ });
325
+ if (includeDefaults) {
326
+ const container = await dockerContainerFind(this.defaultContainerName);
327
+ if (container) {
328
+ await container.teardown(true);
329
+ }
330
+ }
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;
418
+ }
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
+ };
439
+ }
@@ -0,0 +1,5 @@
1
+ import glob from 'glob';
2
+ export declare const readDir: (pattern: string, options?: glob.IOptions | undefined) => Promise<string[]>;
3
+ export declare const moveDir: (source: string, target: string) => Promise<void>;
4
+ export declare const copyDir: (source: string, target: string, fileGlob?: string, globOptions?: null | glob.IOptions, renameFn?: (name: string) => string) => Promise<void>;
5
+ export declare const cleanDir: (pattern: string, globOptions?: false | glob.IOptions | undefined) => Promise<void>;
package/dist/src/fs.js ADDED
@@ -0,0 +1,38 @@
1
+ import fs from 'fs-extra';
2
+ import glob from 'glob';
3
+ import path from 'path';
4
+ import rimraf from 'rimraf';
5
+ export const readDir = async (pattern, options) => new Promise((resolve, reject) => {
6
+ glob(pattern, options || {}, (err, result) => err ? reject(err) : resolve(result));
7
+ });
8
+ export const moveDir = async (source, target) => {
9
+ const dirs = await readDir('**/*.*', {
10
+ cwd: source,
11
+ dot: true,
12
+ nosort: true,
13
+ });
14
+ await Promise.all(dirs.map(async (dir) => {
15
+ const from = path.resolve(source, dir);
16
+ const to = path.resolve(target, dir);
17
+ await fs.ensureDir(path.dirname(to));
18
+ await fs.rename(from, to);
19
+ }));
20
+ };
21
+ export const copyDir = async (source, target, fileGlob = '**/*.*', globOptions = null, renameFn = (n) => n) => {
22
+ const paths = await readDir(fileGlob, {
23
+ cwd: source,
24
+ dot: true,
25
+ nodir: true,
26
+ nosort: true,
27
+ ...globOptions,
28
+ });
29
+ await Promise.all(paths.map(async (p) => {
30
+ const from = path.resolve(source, p);
31
+ const to = path.resolve(target, renameFn(p));
32
+ await fs.ensureDir(path.dirname(to));
33
+ await fs.copyFile(from, to);
34
+ }));
35
+ };
36
+ export const cleanDir = async (pattern, globOptions) => new Promise((resolve, reject) => {
37
+ rimraf(pattern, { glob: globOptions }, (err) => err ? reject(err) : resolve());
38
+ });
@@ -0,0 +1,9 @@
1
+ export declare function git(args: string[]): Promise<string>;
2
+ export declare function gitBranch(): Promise<string>;
3
+ export declare function gitRevId(): Promise<string>;
4
+ declare type GitInfo = {
5
+ branch: string;
6
+ revision: string;
7
+ };
8
+ export declare function gitInfo(noCache?: boolean): Promise<GitInfo>;
9
+ export {};
@@ -0,0 +1,24 @@
1
+ import { exec } from './cp.js';
2
+ export async function git(args) {
3
+ return (await exec(`git ${args.join(' ')}`)).stdout.toString();
4
+ }
5
+ export async function gitBranch() {
6
+ return (await git(['symbolic-ref', '--short', 'HEAD']))
7
+ .replace(/[_+/]/g, '-')
8
+ .trim();
9
+ }
10
+ export async function gitRevId() {
11
+ return (await git(['rev-parse', '--short=12', 'HEAD']))
12
+ .replace(/[+]/g, '')
13
+ .trim();
14
+ }
15
+ let info = null;
16
+ export async function gitInfo(noCache = false) {
17
+ if (!info || noCache) {
18
+ info = {
19
+ branch: await gitBranch(),
20
+ revision: await gitRevId(),
21
+ };
22
+ }
23
+ return info;
24
+ }
@@ -0,0 +1,20 @@
1
+ export * from './ant.js';
2
+ export * from './cert.js';
3
+ export * from './clean.js';
4
+ export * from './copy.js';
5
+ export * from './cp.js';
6
+ export * from './docker.js';
7
+ export * from './docker.container.js';
8
+ export * from './docker.network.js';
9
+ export * from './docker.volume.js';
10
+ export * from './dockerCleanup.js';
11
+ export * from './dockerCompose.js';
12
+ export * from './fs.js';
13
+ export * from './git.js';
14
+ export * from './npm.js';
15
+ export * from './pkg.js';
16
+ export * from './publish.js';
17
+ export * from './run.js';
18
+ export * from './tgz.js';
19
+ export * from './version.js';
20
+ export * from './yarn.js';
@@ -0,0 +1,20 @@
1
+ export * from './ant.js';
2
+ export * from './cert.js';
3
+ export * from './clean.js';
4
+ export * from './copy.js';
5
+ export * from './cp.js';
6
+ export * from './docker.js';
7
+ export * from './docker.container.js';
8
+ export * from './docker.network.js';
9
+ export * from './docker.volume.js';
10
+ export * from './dockerCleanup.js';
11
+ export * from './dockerCompose.js';
12
+ export * from './fs.js';
13
+ export * from './git.js';
14
+ export * from './npm.js';
15
+ export * from './pkg.js';
16
+ export * from './publish.js';
17
+ export * from './run.js';
18
+ export * from './tgz.js';
19
+ export * from './version.js';
20
+ export * from './yarn.js';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Given a `ObjMap`, iterate over each entry and run it through the given `map` function.
3
+ * @param {ObjMap} obj the input object
4
+ * @param {Function} map the mapping operation
5
+ * @returns {ObjMap} a new object
6
+ */
7
+ export declare const mapValues: <K extends string, V, R>(obj: Record<K, V> | null | undefined, map: (value: V, key: K, map: Record<K, V>) => R) => Record<K, R>;
8
+ /**
9
+ * Given a `ObjMap`, iterate over each entry and run it through the given async `map` function.
10
+ * The promise returned by the `map` is awaited, such that the resulting `ObjMap` values are
11
+ * the result of the resolved promise.
12
+ * @param {ObjMap} obj the input object
13
+ * @param {Function} map the async mapping operation
14
+ * @returns {Promise} a promise for a new object
15
+ */
16
+ export declare const mapValuesAsync: <K extends string, V, R>(obj: Record<K, V> | null | undefined, map: (value: V, key: K, objMap: Record<K, V>) => Promise<R>) => Promise<Record<K, R>>;
17
+ /**
18
+ * Given a `ObjMap`, iterate over each entry and run it through the given `filter` function.
19
+ * Any entry for which the `filter` returns `false` is removed from the resulting `ObjMap`.
20
+ * All other entries are left as-is. The resulting output is a subset of the input.
21
+ * If no `filter` is specified, default to filtering out nullish values.
22
+ * @param {ObjMap} obj the input object
23
+ * @param {Function} filter the filter operation
24
+ * @returns {ObjMap} a new object, a subset of the input
25
+ */
26
+ export declare const filterKeys: <V, K extends string = string>(obj: Record<K, V> | null | undefined, filter?: (value: V, key: K, objMap: Record<K, V>) => boolean) => Partial<Record<K, V>>;
27
+ /**
28
+ * Given an object, removes any top level keys with a nullish value.
29
+ * The type system should preserve the incoming object type, with all such keys typed as `empty`.
30
+ * @param {Object} obj the input object
31
+ * @returns {Object} a new object, a subset of the input
32
+ */
33
+ export declare const filterNullish: <T>(obj: Record<string, T>) => Record<string, Exclude<T, null | undefined>>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Given a `ObjMap`, iterate over each entry and run it through the given `map` function.
3
+ * @param {ObjMap} obj the input object
4
+ * @param {Function} map the mapping operation
5
+ * @returns {ObjMap} a new object
6
+ */
7
+ export const mapValues = (obj, map) => Object.entries(obj ?? {}).reduce((acc, [k, v]) => Object.assign(acc, {
8
+ [k]: map(v, k, (obj ?? {})),
9
+ }), {});
10
+ /**
11
+ * Given a `ObjMap`, iterate over each entry and run it through the given async `map` function.
12
+ * The promise returned by the `map` is awaited, such that the resulting `ObjMap` values are
13
+ * the result of the resolved promise.
14
+ * @param {ObjMap} obj the input object
15
+ * @param {Function} map the async mapping operation
16
+ * @returns {Promise} a promise for a new object
17
+ */
18
+ export const mapValuesAsync = async (obj, map) => Object.entries(obj ?? {}).reduce(async (acc, [k, v]) => Object.assign(await acc, {
19
+ [k]: await map(v, k, (obj ?? {})),
20
+ }), Promise.resolve({}));
21
+ /**
22
+ * Given a `ObjMap`, iterate over each entry and run it through the given `filter` function.
23
+ * Any entry for which the `filter` returns `false` is removed from the resulting `ObjMap`.
24
+ * All other entries are left as-is. The resulting output is a subset of the input.
25
+ * If no `filter` is specified, default to filtering out nullish values.
26
+ * @param {ObjMap} obj the input object
27
+ * @param {Function} filter the filter operation
28
+ * @returns {ObjMap} a new object, a subset of the input
29
+ */
30
+ export const filterKeys = (obj, filter = (v) => v != null) => Object.entries(obj ?? {}).reduce((acc, [k, v]) => filter(v, k, (obj ?? {}))
31
+ ? Object.assign(acc, {
32
+ [k]: v,
33
+ })
34
+ : acc, {});
35
+ /**
36
+ * Given an object, removes any top level keys with a nullish value.
37
+ * The type system should preserve the incoming object type, with all such keys typed as `empty`.
38
+ * @param {Object} obj the input object
39
+ * @returns {Object} a new object, a subset of the input
40
+ */
41
+ export const filterNullish = (obj) => filterKeys(obj);
@@ -0,0 +1,35 @@
1
+ export declare type NpmCreds = {
2
+ email?: string;
3
+ password?: string;
4
+ username?: string;
5
+ };
6
+ export declare type NpmConfig = {
7
+ access?: 'public' | 'restricted';
8
+ dryRun?: boolean;
9
+ name?: string;
10
+ publish?: boolean;
11
+ registry?: string;
12
+ };
13
+ export declare function getNpmConfig(): NpmConfig;
14
+ export declare function npmExec(args: string[], npmPath?: string): Promise<string>;
15
+ export declare function npmGetVersions(packageName: string, npmPath?: string): Promise<string[]>;
16
+ export interface NpmPublishOptions {
17
+ npmAuthToken?: string;
18
+ npmConfig?: NpmConfig;
19
+ npmCreds?: NpmCreds;
20
+ npmPath?: string;
21
+ publishPath?: string;
22
+ skipExisting?: boolean;
23
+ tag?: string;
24
+ workDir?: string;
25
+ writeNpmrc?: boolean;
26
+ }
27
+ export declare function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath, skipExisting, tag, workDir: passedWorkDir, writeNpmrc, }?: NpmPublishOptions): Promise<boolean>;
28
+ interface NpmPackOptions {
29
+ destination?: string;
30
+ npmConfig?: NpmConfig;
31
+ npmPath?: string;
32
+ workDir?: string;
33
+ }
34
+ export declare function npmPack({ destination, npmConfig, npmPath, workDir, }: NpmPackOptions): Promise<string>;
35
+ export {};