build-strap 3.0.0 → 4.0.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +3 -34
- package/ant.d.ts +19 -0
- package/ant.js +12 -37
- package/cert.d.ts +12 -0
- package/cert.js +89 -151
- package/clean.d.ts +4 -0
- package/clean.js +7 -16
- package/copy.d.ts +7 -0
- package/copy.js +49 -76
- package/cp.d.ts +17 -0
- package/cp.js +85 -170
- package/docker.container.d.ts +73 -0
- package/docker.container.js +219 -362
- package/docker.d.ts +68 -0
- package/docker.js +167 -347
- package/docker.network.d.ts +42 -0
- package/docker.network.js +69 -144
- package/docker.volume.d.ts +26 -0
- package/docker.volume.js +52 -126
- package/dockerCleanup.d.ts +38 -0
- package/dockerCleanup.js +66 -141
- package/dockerCompose.d.ts +154 -0
- package/dockerCompose.js +400 -727
- package/fs.d.ts +5 -0
- package/fs.js +38 -95
- package/git.d.ts +9 -0
- package/git.js +19 -30
- package/index.d.ts +20 -0
- package/index.js +20 -27
- package/maps.d.ts +33 -0
- package/maps.js +16 -87
- package/npm.d.ts +48 -0
- package/npm.js +133 -135
- package/package.json +23 -19
- package/pkg.d.ts +39 -0
- package/pkg.js +26 -74
- package/publish.d.ts +27 -0
- package/publish.js +52 -140
- package/run.d.ts +13 -0
- package/run.js +39 -85
- package/tgz.d.ts +13 -0
- package/tgz.js +61 -96
- package/version.d.ts +34 -0
- package/version.js +86 -127
- package/yarn.d.ts +44 -0
- package/yarn.js +150 -119
- package/ant.js.flow +0 -42
- package/artifactory.js +0 -617
- package/artifactory.js.flow +0 -616
- package/cert.conf +0 -20
- package/cert.js.flow +0 -152
- package/clean.js.flow +0 -19
- package/copy.js.flow +0 -79
- package/cp.js.flow +0 -172
- package/docker.container.js.flow +0 -389
- package/docker.js.flow +0 -367
- package/docker.network.js.flow +0 -159
- package/docker.volume.js.flow +0 -136
- package/dockerCleanup.js.flow +0 -151
- package/dockerCompose.js.flow +0 -765
- package/flow.js +0 -21
- package/flow.js.flow +0 -20
- package/fs.js.flow +0 -96
- package/git.js.flow +0 -34
- package/hg.js +0 -35
- package/hg.js.flow +0 -34
- package/index.js.flow +0 -26
- package/inline-resources.js +0 -158
- package/inline-resources.js.flow +0 -157
- package/maps.js.flow +0 -111
- package/npm.js.flow +0 -144
- package/pkg.js.flow +0 -80
- package/publish.js.flow +0 -144
- package/run.js.flow +0 -89
- package/src/ant.js +0 -42
- package/src/artifactory.js +0 -616
- package/src/cert.conf +0 -20
- package/src/cert.js +0 -152
- package/src/clean.js +0 -19
- package/src/copy.js +0 -79
- package/src/cp.js +0 -172
- package/src/docker.container.js +0 -389
- package/src/docker.js +0 -367
- package/src/docker.network.js +0 -159
- package/src/docker.volume.js +0 -136
- package/src/dockerCleanup.js +0 -151
- package/src/dockerCompose.js +0 -765
- package/src/flow.js +0 -20
- package/src/fs.js +0 -96
- package/src/git.js +0 -34
- package/src/hg.js +0 -34
- package/src/index.js +0 -26
- package/src/inline-resources.js +0 -157
- package/src/maps.js +0 -111
- package/src/npm.js +0 -144
- package/src/pkg.js +0 -80
- package/src/publish.js +0 -144
- package/src/run.js +0 -89
- package/src/test.js +0 -55
- package/src/tgz.js +0 -101
- package/src/version.js +0 -141
- package/src/yarn.js +0 -123
- package/test.js +0 -56
- package/test.js.flow +0 -55
- package/tgz.js.flow +0 -101
- package/version.js.flow +0 -141
- package/yarn.js.flow +0 -123
package/docker.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface DockerConfig {
|
|
2
|
+
name?: string;
|
|
3
|
+
registry?: string;
|
|
4
|
+
repository?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getDockerConfig(): DockerConfig;
|
|
7
|
+
export declare const parseDockerDate: (date: string) => Date;
|
|
8
|
+
export declare function dockerBuild(tags?: string[], buildArgs?: string[], target?: string | null, extraArgs?: string[], repo?: string, dockerFile?: string, workDir?: string): Promise<string>;
|
|
9
|
+
export declare function dockerTag(imageId: string, tags?: string[], repo?: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Apply the standard convention for tagging the docker image for the project,
|
|
12
|
+
* based on the source control branch being built.
|
|
13
|
+
* For releases, applies `latest`, `M.m.p`, `M.m`, `M`
|
|
14
|
+
* For release candidates, applies `latest-rc`
|
|
15
|
+
* For feature branches, applies `latest-feature`
|
|
16
|
+
* For development branch, applies `latest-dev`
|
|
17
|
+
* All other branches, no tag is applies
|
|
18
|
+
* @param {string} imageId id of the docker image to which to apply the tags
|
|
19
|
+
* @param {string} repo optional override of the docker repo url to use (derived from package.json by default)
|
|
20
|
+
*/
|
|
21
|
+
export declare function dockerTagVersion(imageId: string, repo?: string): Promise<void>;
|
|
22
|
+
export interface DockerImage {
|
|
23
|
+
created: Date;
|
|
24
|
+
digest: string;
|
|
25
|
+
id: string;
|
|
26
|
+
repository: string;
|
|
27
|
+
size: number;
|
|
28
|
+
tag: string;
|
|
29
|
+
}
|
|
30
|
+
export declare type DockerImageFilter = (i: DockerImage) => boolean;
|
|
31
|
+
export declare function dockerImages(repo?: null | string, filter?: null | DockerImageFilter): Promise<DockerImage[]>;
|
|
32
|
+
export declare function getDockerId(tag?: string, repo?: null | string): Promise<string>;
|
|
33
|
+
export declare function getUntaggedDockerIds(repo?: string, filter?: null | DockerImageFilter): Promise<string[]>;
|
|
34
|
+
export declare function getDockerTags(id?: null | string, repo?: null | string, fullName?: boolean, filter?: null | DockerImageFilter): Promise<string[]>;
|
|
35
|
+
export declare function getDockerDigest(imageId: string, repo?: string): Promise<string>;
|
|
36
|
+
interface DockerLoginOptions {
|
|
37
|
+
password?: string;
|
|
38
|
+
registry?: string;
|
|
39
|
+
user?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function dockerLogin({ password, registry, user, }?: DockerLoginOptions): Promise<void>;
|
|
42
|
+
export declare function dockerPush(tags?: string[], repo?: string): Promise<void>;
|
|
43
|
+
export interface DockerPullOptions {
|
|
44
|
+
image: string;
|
|
45
|
+
offline?: boolean;
|
|
46
|
+
testUrl?: string | null;
|
|
47
|
+
}
|
|
48
|
+
export declare function dockerPull({ image, offline, testUrl, }: DockerPullOptions): Promise<void>;
|
|
49
|
+
export declare function dockerRmi(images?: string[], ignoreErrors?: boolean): Promise<void>;
|
|
50
|
+
export declare function getDockerRepo(): string;
|
|
51
|
+
export interface PullAndRunContainerOptions extends DockerPullOptions {
|
|
52
|
+
alias?: string | null;
|
|
53
|
+
cmd?: string[];
|
|
54
|
+
network?: string | null;
|
|
55
|
+
runArgs?: string[];
|
|
56
|
+
}
|
|
57
|
+
export declare function dockerPullAndRunContainer(options: PullAndRunContainerOptions): Promise<string>;
|
|
58
|
+
export interface CopyFilePathConfig {
|
|
59
|
+
from: string;
|
|
60
|
+
to: string;
|
|
61
|
+
}
|
|
62
|
+
export interface CopyFilesFromDockerImageConfig {
|
|
63
|
+
filePaths: CopyFilePathConfig[];
|
|
64
|
+
ignoreErrors?: boolean;
|
|
65
|
+
imageId: string;
|
|
66
|
+
}
|
|
67
|
+
export declare function copyFilesFromDockerImage({ filePaths, ignoreErrors, imageId, }: CopyFilesFromDockerImageConfig): Promise<any>;
|
|
68
|
+
export {};
|
package/docker.js
CHANGED
|
@@ -1,66 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
import bytes from 'bytes';
|
|
2
|
+
import isReachable from 'is-reachable';
|
|
3
|
+
import moment from 'moment';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { spawn } from './cp.js';
|
|
6
|
+
import { dockerContainerKill, dockerContainerRunDaemon, } from './docker.container.js';
|
|
7
|
+
import { dockerNetworkConnect } from './docker.network.js';
|
|
8
|
+
import { getCfg, getPkgName, getPkgScope } from './pkg.js';
|
|
9
|
+
import { buildLog } from './run.js';
|
|
10
|
+
import { getDevBranch, getVersion } from './version.js';
|
|
11
|
+
export function getDockerConfig() {
|
|
12
|
+
return getCfg().docker || {};
|
|
13
|
+
}
|
|
14
|
+
export const parseDockerDate = (date) => moment(date, 'YYYY-MM-DD HH:mm:ss ZZ').toDate();
|
|
15
|
+
export async function dockerBuild(tags = ['latest'], buildArgs = [], target = null, extraArgs = [], repo = getDockerRepo(), dockerFile = './Dockerfile', workDir = '.') {
|
|
16
|
+
const args = [
|
|
17
|
+
'build',
|
|
18
|
+
...['-f', path.resolve(dockerFile)],
|
|
19
|
+
...(target ? ['--target', target] : []),
|
|
20
|
+
...tags.reduce((ar, t) => [...ar, '-t', `${repo}:${t}`], []),
|
|
21
|
+
...buildArgs.reduce((ar, a) => [...ar, '--build-arg', a], []),
|
|
22
|
+
...(extraArgs || []),
|
|
23
|
+
path.resolve(workDir),
|
|
24
|
+
];
|
|
25
|
+
return (await spawn('docker', args, { stdio: 'inherit' })).output;
|
|
26
|
+
}
|
|
27
|
+
export async function dockerTag(imageId, tags = ['latest'], repo = getDockerRepo()) {
|
|
28
|
+
await Promise.all(tags.map(async (t) => {
|
|
29
|
+
await spawn('docker', ['tag', imageId, `${repo}:${t}`]);
|
|
30
|
+
buildLog(`Tagged image ${imageId} as ${repo}:${t}`);
|
|
31
|
+
}));
|
|
24
32
|
}
|
|
25
|
-
|
|
26
|
-
const parseDockerDate = (date) =>
|
|
27
|
-
(0, _moment.default)(date, 'YYYY-MM-DD HH:mm:ss ZZ').toDate();exports.parseDockerDate = parseDockerDate;
|
|
28
|
-
|
|
29
|
-
async function dockerBuild(
|
|
30
|
-
tags = ['latest'],
|
|
31
|
-
buildArgs = [],
|
|
32
|
-
target = null,
|
|
33
|
-
extraArgs = [],
|
|
34
|
-
repo = getDockerRepo(),
|
|
35
|
-
dockerFile = './Dockerfile',
|
|
36
|
-
workDir = '.')
|
|
37
|
-
{
|
|
38
|
-
const args = [
|
|
39
|
-
'build',
|
|
40
|
-
...['-f', _path.default.resolve(dockerFile)],
|
|
41
|
-
...(target ? ['--target', target] : []),
|
|
42
|
-
...tags.reduce((ar, t) => [...ar, '-t', `${repo}:${t}`], []),
|
|
43
|
-
...buildArgs.reduce((ar, a) => [...ar, '--build-arg', a], []),
|
|
44
|
-
...(extraArgs || []),
|
|
45
|
-
_path.default.resolve(workDir)];
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return (0, _cp.spawn)('docker', args, { stdio: 'inherit' });
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function dockerTag(
|
|
52
|
-
imageId,
|
|
53
|
-
tags = ['latest'],
|
|
54
|
-
repo = getDockerRepo())
|
|
55
|
-
{
|
|
56
|
-
await Promise.all(
|
|
57
|
-
tags.map(async (t) => {
|
|
58
|
-
await (0, _cp.spawn)('docker', ['tag', imageId, `${repo}:${t}`]);
|
|
59
|
-
(0, _run.buildLog)(`Tagged image ${imageId} as ${repo}:${t}`);
|
|
60
|
-
}));
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
33
|
/**
|
|
65
34
|
* Apply the standard convention for tagging the docker image for the project,
|
|
66
35
|
* based on the source control branch being built.
|
|
@@ -72,297 +41,148 @@ repo = getDockerRepo())
|
|
|
72
41
|
* @param {string} imageId id of the docker image to which to apply the tags
|
|
73
42
|
* @param {string} repo optional override of the docker repo url to use (derived from package.json by default)
|
|
74
43
|
*/
|
|
75
|
-
async function dockerTagVersion(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
{
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
} else if (branch.match(/^(release|patch)-/)) {
|
|
90
|
-
await dockerTag(imageId, ['latest-rc'], repo);
|
|
91
|
-
} else if (branch.match(/^feature-/)) {
|
|
92
|
-
await dockerTag(imageId, ['latest-feature'], repo);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
async function dockerImages(
|
|
108
|
-
repo = getDockerRepo(),
|
|
109
|
-
filter = null)
|
|
110
|
-
{
|
|
111
|
-
return (
|
|
112
|
-
await (0, _cp.spawn)(
|
|
113
|
-
'docker',
|
|
114
|
-
['images', '--format', `{{json .}}`, ...(repo ? [repo] : [])],
|
|
115
|
-
{ captureOutput: true })).
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
split('\n').
|
|
119
|
-
filter((line) => !!line.trim()).
|
|
120
|
-
map((l) => {
|
|
121
|
-
const {
|
|
122
|
-
Repository: repository,
|
|
123
|
-
Tag: tag,
|
|
124
|
-
ID: id,
|
|
125
|
-
Digest: digest,
|
|
126
|
-
CreatedAt,
|
|
127
|
-
Size } =
|
|
128
|
-
JSON.parse(l.trim());
|
|
129
|
-
return {
|
|
130
|
-
repository,
|
|
131
|
-
tag,
|
|
132
|
-
id,
|
|
133
|
-
digest,
|
|
134
|
-
created: parseDockerDate(CreatedAt),
|
|
135
|
-
size: _bytes.default.parse(Size) };
|
|
136
|
-
|
|
137
|
-
}).
|
|
138
|
-
filter(
|
|
139
|
-
(m) =>
|
|
140
|
-
(m && m.id) != null && (
|
|
141
|
-
typeof filter === 'function' ? filter(m) : true));
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async function getDockerId(
|
|
146
|
-
tag = 'latest',
|
|
147
|
-
repo)
|
|
148
|
-
{
|
|
149
|
-
return (await dockerImages(repo, (m) => m.tag === tag)).map((m) => m.id)[0];
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function getUntaggedDockerIds(
|
|
153
|
-
repo,
|
|
154
|
-
filter = null)
|
|
155
|
-
{
|
|
156
|
-
return (
|
|
157
|
-
await dockerImages(
|
|
158
|
-
repo,
|
|
159
|
-
(m) =>
|
|
160
|
-
m.tag === '<none>' && (typeof filter === 'function' ? filter(m) : true))).
|
|
161
|
-
|
|
162
|
-
map((m) => m.id);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async function getDockerTags(
|
|
166
|
-
id,
|
|
167
|
-
repo,
|
|
168
|
-
fullName = false,
|
|
169
|
-
filter = null)
|
|
170
|
-
{
|
|
171
|
-
return (
|
|
172
|
-
await dockerImages(
|
|
173
|
-
repo,
|
|
174
|
-
(m) =>
|
|
175
|
-
(!id || m.id === id) && (
|
|
176
|
-
typeof filter === 'function' ? filter(m) : true))).
|
|
177
|
-
|
|
178
|
-
map((m) => fullName ? `${m.repository}:${m.tag}` : m.tag);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async function getDockerDigest(
|
|
182
|
-
imageId,
|
|
183
|
-
repo)
|
|
184
|
-
{
|
|
185
|
-
return (await dockerImages(repo, (m) => m.id === imageId)).map(
|
|
186
|
-
(m) => m.digest)[
|
|
187
|
-
0];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async function dockerLogin(
|
|
191
|
-
user,
|
|
192
|
-
password,
|
|
193
|
-
registry)
|
|
194
|
-
{
|
|
195
|
-
const reg = registry || getDockerConfig().registry;
|
|
196
|
-
await (0, _cp.spawn)(
|
|
197
|
-
'docker',
|
|
198
|
-
[
|
|
199
|
-
'login',
|
|
200
|
-
'-u',
|
|
201
|
-
user || process.env.ARTIFACTORY_USER || '',
|
|
202
|
-
'-p',
|
|
203
|
-
password || process.env.ARTIFACTORY_PASSWORD || '',
|
|
204
|
-
...(reg ? [reg] : [])],
|
|
205
|
-
|
|
206
|
-
{ stdio: 'inherit' });
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
async function dockerPush(
|
|
211
|
-
tags = ['latest'],
|
|
212
|
-
repo = getDockerRepo())
|
|
213
|
-
{
|
|
214
|
-
// do this sequentially, so you don't push the same image simultaneously
|
|
215
|
-
await tags.reduce(async (prev, tag) => {
|
|
216
|
-
await prev;
|
|
217
|
-
await (0, _cp.spawn)('docker', ['push', `${repo}:${tag}`], { stdio: 'inherit' });
|
|
218
|
-
}, Promise.resolve());
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
async function dockerPull({
|
|
228
|
-
image,
|
|
229
|
-
offline = process.argv.includes('--offline'),
|
|
230
|
-
testUrl })
|
|
231
|
-
{
|
|
232
|
-
if (
|
|
233
|
-
offline ||
|
|
234
|
-
!(await (0, _isReachable.default)(testUrl || 'https://hub.docker.com')))
|
|
235
|
-
{
|
|
236
|
-
if (offline === false) {
|
|
237
|
-
throw new Error('Offline, cannot docker pull');
|
|
44
|
+
export async function dockerTagVersion(imageId, repo = getDockerRepo()) {
|
|
45
|
+
const { branch, isRelease, major, minor, patch } = await getVersion();
|
|
46
|
+
// determine what tags to apply
|
|
47
|
+
if (isRelease) {
|
|
48
|
+
await dockerTag(imageId, ['latest', `${major}`, `${major}.${minor}`, `${major}.${minor}.${patch}`], repo);
|
|
49
|
+
}
|
|
50
|
+
else if (branch === (await getDevBranch())) {
|
|
51
|
+
await dockerTag(imageId, ['latest-dev'], repo);
|
|
52
|
+
}
|
|
53
|
+
else if (branch.match(/^(release|patch)-/)) {
|
|
54
|
+
await dockerTag(imageId, ['latest-rc'], repo);
|
|
55
|
+
}
|
|
56
|
+
else if (branch.match(/^feature-/)) {
|
|
57
|
+
await dockerTag(imageId, ['latest-feature'], repo);
|
|
238
58
|
}
|
|
239
|
-
(0, _run.buildLog)('It looks like you are offline, skipping docker pull');
|
|
240
|
-
} else {
|
|
241
|
-
// throws on failure
|
|
242
|
-
await (0, _cp.spawn)('docker', ['pull', image], { stdio: 'inherit' });
|
|
243
|
-
}
|
|
244
59
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
{
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
60
|
+
export async function dockerImages(repo = getDockerRepo(), filter = null) {
|
|
61
|
+
return (await spawn('docker', ['images', '--format', `{{json .}}`, ...(repo ? [repo] : [])], { captureOutput: true })).output
|
|
62
|
+
.split('\n')
|
|
63
|
+
.filter((line) => !!line.trim())
|
|
64
|
+
.map((l) => {
|
|
65
|
+
const { CreatedAt, Digest: digest, ID: id, Repository: repository, Size, Tag: tag, } = JSON.parse(l.trim());
|
|
66
|
+
return {
|
|
67
|
+
created: parseDockerDate(CreatedAt),
|
|
68
|
+
digest,
|
|
69
|
+
id,
|
|
70
|
+
repository,
|
|
71
|
+
size: bytes.parse(Size),
|
|
72
|
+
tag,
|
|
73
|
+
};
|
|
74
|
+
})
|
|
75
|
+
.filter((m) => (m && m.id) != null &&
|
|
76
|
+
(typeof filter === 'function' ? filter(m) : true));
|
|
77
|
+
}
|
|
78
|
+
export async function getDockerId(tag = 'latest', repo = null) {
|
|
79
|
+
return (await dockerImages(repo, (m) => m.tag === tag)).map((m) => m.id)[0];
|
|
80
|
+
}
|
|
81
|
+
export async function getUntaggedDockerIds(repo, filter = null) {
|
|
82
|
+
return (await dockerImages(repo, (m) => m.tag === '<none>' && (typeof filter === 'function' ? filter(m) : true))).map((m) => m.id);
|
|
83
|
+
}
|
|
84
|
+
export async function getDockerTags(id, repo, fullName = false, filter = null) {
|
|
85
|
+
return (await dockerImages(repo, (m) => (!id || m.id === id) &&
|
|
86
|
+
(typeof filter === 'function' ? filter(m) : true))).map((m) => (fullName ? `${m.repository}:${m.tag}` : m.tag));
|
|
87
|
+
}
|
|
88
|
+
export async function getDockerDigest(imageId, repo) {
|
|
89
|
+
return (await dockerImages(repo, (m) => m.id === imageId)).map((m) => m.digest)[0];
|
|
90
|
+
}
|
|
91
|
+
export async function dockerLogin({ password = process.env.DOCKER_PASSWORD, registry = process.env.DOCKER_REGISTRY, user = process.env.DOCKER_PASSWORD, } = {}) {
|
|
92
|
+
const reg = registry || getDockerConfig().registry;
|
|
93
|
+
await spawn('docker', ['login', '-u', user || '', '-p', password || '', ...(reg ? [reg] : [])], { stdio: 'inherit' });
|
|
94
|
+
}
|
|
95
|
+
export async function dockerPush(tags = ['latest'], repo = getDockerRepo()) {
|
|
96
|
+
// do this sequentially, so you don't push the same image simultaneously
|
|
97
|
+
await tags.reduce(async (prev, tag) => {
|
|
98
|
+
await prev;
|
|
99
|
+
await spawn('docker', ['push', `${repo}:${tag}`], { stdio: 'inherit' });
|
|
100
|
+
}, Promise.resolve());
|
|
101
|
+
}
|
|
102
|
+
export async function dockerPull({ image, offline = process.argv.includes('--offline'), testUrl, }) {
|
|
103
|
+
if (offline || !(await isReachable(testUrl || 'https://hub.docker.com'))) {
|
|
104
|
+
if (offline === false) {
|
|
105
|
+
throw new Error('Offline, cannot docker pull');
|
|
106
|
+
}
|
|
107
|
+
buildLog('It looks like you are offline, skipping docker pull');
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
// throws on failure
|
|
111
|
+
await spawn('docker', ['pull', image], { stdio: 'inherit' });
|
|
112
|
+
}
|
|
263
113
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
114
|
+
export async function dockerRmi(images = [], ignoreErrors = true) {
|
|
115
|
+
// must do these sequentially, or they will interfere with each other
|
|
116
|
+
await images.reduce(async (prev, image) => {
|
|
117
|
+
await prev;
|
|
118
|
+
await spawn('docker', ['rmi', image], { stdio: 'inherit' }).catch((err) => {
|
|
119
|
+
if (ignoreErrors) {
|
|
120
|
+
buildLog(`Warning (ignored Error): Failed to rm image(s): ${err.message}`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}, Promise.resolve());
|
|
127
|
+
}
|
|
128
|
+
export function getDockerRepo() {
|
|
129
|
+
const { name: dkrName, registry, repository: dkrRepo } = getDockerConfig();
|
|
130
|
+
const repository = dkrRepo || getPkgScope();
|
|
131
|
+
const name = dkrName || getPkgName(false);
|
|
132
|
+
if (!repository || !name) {
|
|
133
|
+
throw new Error('Docker configuration is missing or incomplete in package.json');
|
|
134
|
+
}
|
|
135
|
+
return `${registry ? `${registry}/` : ''}${repository}/${name}`;
|
|
275
136
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const {
|
|
290
|
-
runArgs = [],
|
|
291
|
-
cmd = [],
|
|
292
|
-
network,
|
|
293
|
-
alias,
|
|
294
|
-
offline = process.argv.includes('--offline'),
|
|
295
|
-
testUrl } =
|
|
296
|
-
options;
|
|
297
|
-
|
|
298
|
-
try {
|
|
299
|
-
await dockerPull({ image, offline, testUrl });
|
|
300
|
-
} catch (err) {
|
|
301
|
-
(0, _run.buildLog)(`docker pull failed (${err.message}), attempting to continue...`);
|
|
302
|
-
}
|
|
303
|
-
const { id } = await (0, _docker.dockerContainerRunDaemon)({ image, runArgs, cmd });
|
|
304
|
-
if (network) {
|
|
305
|
-
await (0, _docker2.dockerNetworkConnect)(network, id, alias);
|
|
306
|
-
}
|
|
307
|
-
return id;
|
|
137
|
+
export async function dockerPullAndRunContainer(options) {
|
|
138
|
+
const { image, runArgs = [], cmd = [], network, alias, offline = process.argv.includes('--offline'), testUrl, } = options;
|
|
139
|
+
try {
|
|
140
|
+
await dockerPull({ image, offline, testUrl });
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
buildLog(`docker pull failed (${err.message}), attempting to continue...`);
|
|
144
|
+
}
|
|
145
|
+
const { id } = await dockerContainerRunDaemon({ cmd, image, runArgs });
|
|
146
|
+
if (network) {
|
|
147
|
+
await dockerNetworkConnect(network, id, alias);
|
|
148
|
+
}
|
|
149
|
+
return id;
|
|
308
150
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
async function copyFilesFromDockerImage({
|
|
322
|
-
imageId,
|
|
323
|
-
filePaths,
|
|
324
|
-
ignoreErrors })
|
|
325
|
-
{
|
|
326
|
-
const container = await (0, _docker.dockerContainerRunDaemon)({
|
|
327
|
-
image: imageId,
|
|
328
|
-
runArgs: ['-it', '--rm', '--entrypoint=/bin/bash'],
|
|
329
|
-
cmd: ['read', '-p', 'pause'] });
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
(0, _run.buildLog)(`Copying Files from Docker Image - imageId (${imageId})`);
|
|
333
|
-
|
|
334
|
-
const spawnOptions = {
|
|
335
|
-
stdio: 'inherit',
|
|
336
|
-
pipeOutput: true,
|
|
337
|
-
captureOutput: false };
|
|
338
|
-
|
|
339
|
-
const copyErrors = [];
|
|
340
|
-
|
|
341
|
-
try {
|
|
342
|
-
filePaths.forEach(async (fp) => {
|
|
343
|
-
// Try to copy from the Debug Folder
|
|
344
|
-
try {
|
|
345
|
-
await (0, _cp.spawn)(
|
|
346
|
-
'docker',
|
|
347
|
-
['cp', `${container.id}:${fp.from}`, fp.to],
|
|
348
|
-
spawnOptions);
|
|
349
|
-
|
|
350
|
-
(0, _run.buildLog)(`Copied ${fp.from} => ${fp.to}`);
|
|
351
|
-
} catch (error) {
|
|
352
|
-
copyErrors.push(error);
|
|
353
|
-
(0, _run.buildLog)(`Error copying file ${fp.from}`);
|
|
354
|
-
}
|
|
151
|
+
export async function copyFilesFromDockerImage({ filePaths, ignoreErrors, imageId, }) {
|
|
152
|
+
const container = await dockerContainerRunDaemon({
|
|
153
|
+
cmd: ['read', '-p', 'pause'],
|
|
154
|
+
image: imageId,
|
|
155
|
+
runArgs: ['-it', '--rm', '--entrypoint=/bin/bash'],
|
|
355
156
|
});
|
|
356
|
-
|
|
157
|
+
buildLog(`Copying Files from Docker Image - imageId (${imageId})`);
|
|
158
|
+
const spawnOptions = {
|
|
159
|
+
captureOutput: false,
|
|
160
|
+
pipeOutput: true,
|
|
161
|
+
stdio: 'inherit',
|
|
162
|
+
};
|
|
163
|
+
const copyErrors = [];
|
|
357
164
|
try {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
165
|
+
filePaths.forEach(async (fp) => {
|
|
166
|
+
// Try to copy from the Debug Folder
|
|
167
|
+
try {
|
|
168
|
+
await spawn('docker', ['cp', `${container.id}:${fp.from}`, fp.to], spawnOptions);
|
|
169
|
+
buildLog(`Copied ${fp.from} => ${fp.to}`);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
copyErrors.push(error);
|
|
173
|
+
buildLog(`Error copying file ${fp.from}`);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
try {
|
|
179
|
+
await dockerContainerKill(container.id);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
copyErrors.push(error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (copyErrors.length > 0 && ignoreErrors !== true) {
|
|
186
|
+
throw new Error('Some files failed to copy');
|
|
361
187
|
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
if (copyErrors.length > 0 && ignoreErrors !== true) {
|
|
365
|
-
throw new Error('Some files failed to copy');
|
|
366
|
-
}
|
|
367
188
|
}
|
|
368
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kb2NrZXIuanMiXSwibmFtZXMiOlsiZ2V0RG9ja2VyQ29uZmlnIiwiZG9ja2VyIiwicGFyc2VEb2NrZXJEYXRlIiwiZGF0ZSIsInRvRGF0ZSIsImRvY2tlckJ1aWxkIiwidGFncyIsImJ1aWxkQXJncyIsInRhcmdldCIsImV4dHJhQXJncyIsInJlcG8iLCJnZXREb2NrZXJSZXBvIiwiZG9ja2VyRmlsZSIsIndvcmtEaXIiLCJhcmdzIiwicGF0aCIsInJlc29sdmUiLCJyZWR1Y2UiLCJhciIsInQiLCJhIiwic3RkaW8iLCJkb2NrZXJUYWciLCJpbWFnZUlkIiwiUHJvbWlzZSIsImFsbCIsIm1hcCIsImRvY2tlclRhZ1ZlcnNpb24iLCJpc1JlbGVhc2UiLCJtYWpvciIsIm1pbm9yIiwicGF0Y2giLCJicmFuY2giLCJtYXRjaCIsImRvY2tlckltYWdlcyIsImZpbHRlciIsImNhcHR1cmVPdXRwdXQiLCJzcGxpdCIsImxpbmUiLCJ0cmltIiwibCIsIlJlcG9zaXRvcnkiLCJyZXBvc2l0b3J5IiwiVGFnIiwidGFnIiwiSUQiLCJpZCIsIkRpZ2VzdCIsImRpZ2VzdCIsIkNyZWF0ZWRBdCIsIlNpemUiLCJKU09OIiwicGFyc2UiLCJjcmVhdGVkIiwic2l6ZSIsImJ5dGVzIiwibSIsImdldERvY2tlcklkIiwiZ2V0VW50YWdnZWREb2NrZXJJZHMiLCJnZXREb2NrZXJUYWdzIiwiZnVsbE5hbWUiLCJnZXREb2NrZXJEaWdlc3QiLCJkb2NrZXJMb2dpbiIsInVzZXIiLCJwYXNzd29yZCIsInJlZ2lzdHJ5IiwicmVnIiwicHJvY2VzcyIsImVudiIsIkFSVElGQUNUT1JZX1VTRVIiLCJBUlRJRkFDVE9SWV9QQVNTV09SRCIsImRvY2tlclB1c2giLCJwcmV2IiwiZG9ja2VyUHVsbCIsImltYWdlIiwib2ZmbGluZSIsImFyZ3YiLCJpbmNsdWRlcyIsInRlc3RVcmwiLCJFcnJvciIsImRvY2tlclJtaSIsImltYWdlcyIsImlnbm9yZUVycm9ycyIsImNhdGNoIiwiZXJyIiwibWVzc2FnZSIsImRrclJlcG8iLCJuYW1lIiwiZGtyTmFtZSIsImRvY2tlclB1bGxBbmRSdW5Db250YWluZXIiLCJvcHRpb25zIiwicnVuQXJncyIsImNtZCIsIm5ldHdvcmsiLCJhbGlhcyIsImNvcHlGaWxlc0Zyb21Eb2NrZXJJbWFnZSIsImZpbGVQYXRocyIsImNvbnRhaW5lciIsInNwYXduT3B0aW9ucyIsInBpcGVPdXRwdXQiLCJjb3B5RXJyb3JzIiwiZm9yRWFjaCIsImZwIiwiZnJvbSIsInRvIiwiZXJyb3IiLCJwdXNoIiwibGVuZ3RoIl0sIm1hcHBpbmdzIjoiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUEsMkM7Ozs7Ozs7O0FBUU8sU0FBU0EsZUFBVCxHQUF5QztBQUM5QyxTQUFPLG1CQUFTQyxNQUFULElBQW1CLEVBQTFCO0FBQ0Q7O0FBRU0sTUFBTUMsZUFBZSxHQUFHLENBQUNDLElBQUQ7QUFDN0IscUJBQU9BLElBQVAsRUFBYSx3QkFBYixFQUF1Q0MsTUFBdkMsRUFESyxDOztBQUdBLGVBQWVDLFdBQWY7QUFDTEMsSUFBYyxHQUFHLENBQUMsUUFBRCxDQURaO0FBRUxDLFNBQW1CLEdBQUcsRUFGakI7QUFHTEMsTUFBZSxHQUFHLElBSGI7QUFJTEMsU0FBdUIsR0FBRyxFQUpyQjtBQUtMQyxJQUFZLEdBQUdDLGFBQWEsRUFMdkI7QUFNTEMsVUFBa0IsR0FBRyxjQU5oQjtBQU9MQyxPQUFlLEdBQUcsR0FQYjtBQVFZO0FBQ2pCLFFBQU1DLElBQUksR0FBRztBQUNYLFNBRFc7QUFFWCxLQUFHLENBQUMsSUFBRCxFQUFPQyxjQUFLQyxPQUFMLENBQWFKLFVBQWIsQ0FBUCxDQUZRO0FBR1gsTUFBSUosTUFBTSxHQUFHLENBQUMsVUFBRCxFQUFhQSxNQUFiLENBQUgsR0FBMEIsRUFBcEMsQ0FIVztBQUlYLEtBQUdGLElBQUksQ0FBQ1csTUFBTCxDQUFZLENBQUNDLEVBQUQsRUFBS0MsQ0FBTCxLQUFXLENBQUMsR0FBR0QsRUFBSixF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RCxLQUFQLEVBQWM7QUFDZEwsTUFBQUEsVUFBVSxDQUFDTSxJQUFYLENBQWdCRCxLQUFoQjtBQUNEO0FBQ0Y7O0FBRUQsTUFBSUwsVUFBVSxDQUFDTyxNQUFYLEdBQW9CLENBQXBCLElBQXlCekIsWUFBWSxLQUFLLElBQTlDLEVBQW9EO0FBQ2xELFVBQU0sSUFBSUgsS0FBSixDQUFVLDJCQUFWLENBQU47QUFDRDtBQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGJ5dGVzIGZyb20gJ2J5dGVzJztcbmltcG9ydCBpc1JlYWNoYWJsZSBmcm9tICdpcy1yZWFjaGFibGUnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgYnVpbGRMb2cgfSBmcm9tICcuL3J1bic7XG5pbXBvcnQgeyBnZXRDZmcsIGdldFBrZ05hbWUsIGdldFBrZ1Njb3BlIH0gZnJvbSAnLi9wa2cnO1xuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICcuL2NwJztcbmltcG9ydCB7IGdldFZlcnNpb24sIGdldERldkJyYW5jaCB9IGZyb20gJy4vdmVyc2lvbic7XG5pbXBvcnQge1xuICBkb2NrZXJDb250YWluZXJSdW5EYWVtb24sXG4gIGRvY2tlckNvbnRhaW5lcktpbGwsXG59IGZyb20gJy4vZG9ja2VyLmNvbnRhaW5lcic7XG5pbXBvcnQgeyBkb2NrZXJOZXR3b3JrQ29ubmVjdCB9IGZyb20gJy4vZG9ja2VyLm5ldHdvcmsnO1xuXG5leHBvcnQgdHlwZSBEb2NrZXJDb25maWcgPSB7XG4gIHJlZ2lzdHJ5Pzogc3RyaW5nLFxuICByZXBvc2l0b3J5Pzogc3RyaW5nLFxuICBuYW1lPzogc3RyaW5nLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldERvY2tlckNvbmZpZygpOiBEb2NrZXJDb25maWcge1xuICByZXR1cm4gZ2V0Q2ZnKCkuZG9ja2VyIHx8IHt9O1xufVxuXG5leHBvcnQgY29uc3QgcGFyc2VEb2NrZXJEYXRlID0gKGRhdGU6IHN0cmluZyk6IERhdGUgPT5cbiAgbW9tZW50KGRhdGUsICdZWVlZLU1NLUREIEhIOm1tOnNzIFpaJykudG9EYXRlKCk7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJCdWlsZChcbiAgdGFnczogc3RyaW5nW10gPSBbJ2xhdGVzdCddLFxuICBidWlsZEFyZ3M6IHN0cmluZ1tdID0gW10sXG4gIHRhcmdldDogP3N0cmluZyA9IG51bGwsXG4gIGV4dHJhQXJncz86ID8oc3RyaW5nW10pID0gW10sXG4gIHJlcG86IHN0cmluZyA9IGdldERvY2tlclJlcG8oKSxcbiAgZG9ja2VyRmlsZTogc3RyaW5nID0gJy4vRG9ja2VyZmlsZScsXG4gIHdvcmtEaXI6IHN0cmluZyA9ICcuJyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgJ2J1aWxkJyxcbiAgICAuLi5bJy1mJywgcGF0aC5yZXNvbHZlKGRvY2tlckZpbGUpXSxcbiAgICAuLi4odGFyZ2V0ID8gWyctLXRhcmdldCcsIHRhcmdldF0gOiBbXSksXG4gICAgLi4udGFncy5yZWR1Y2UoKGFyLCB0KSA9PiBbLi4uYXIsICctdCcsIGAke3JlcG99OiR7dH1gXSwgW10pLFxuICAgIC4uLmJ1aWxkQXJncy5yZWR1Y2UoKGFyLCBhKSA9PiBbLi4uYXIsICctLWJ1aWxkLWFyZycsIGFdLCBbXSksXG4gICAgLi4uKGV4dHJhQXJncyB8fCBbXSksXG4gICAgcGF0aC5yZXNvbHZlKHdvcmtEaXIpLFxuICBdO1xuXG4gIHJldHVybiBzcGF3bignZG9ja2VyJywgYXJncywgeyBzdGRpbzogJ2luaGVyaXQnIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyVGFnKFxuICBpbWFnZUlkOiBzdHJpbmcsXG4gIHRhZ3M6IHN0cmluZ1tdID0gWydsYXRlc3QnXSxcbiAgcmVwbz86IHN0cmluZyA9IGdldERvY2tlclJlcG8oKSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICB0YWdzLm1hcChhc3luYyAodCkgPT4ge1xuICAgICAgYXdhaXQgc3Bhd24oJ2RvY2tlcicsIFsndGFnJywgaW1hZ2VJZCwgYCR7cmVwb306JHt0fWBdKTtcbiAgICAgIGJ1aWxkTG9nKGBUYWdnZWQgaW1hZ2UgJHtpbWFnZUlkfSBhcyAke3JlcG99OiR7dH1gKTtcbiAgICB9KSxcbiAgKTtcbn1cblxuLyoqXG4gKiBBcHBseSB0aGUgc3RhbmRhcmQgY29udmVudGlvbiBmb3IgdGFnZ2luZyB0aGUgZG9ja2VyIGltYWdlIGZvciB0aGUgcHJvamVjdCxcbiAqIGJhc2VkIG9uIHRoZSBzb3VyY2UgY29udHJvbCBicmFuY2ggYmVpbmcgYnVpbHQuXG4gKiBGb3IgcmVsZWFzZXMsIGFwcGxpZXMgYGxhdGVzdGAsIGBNLm0ucGAsIGBNLm1gLCBgTWBcbiAqIEZvciByZWxlYXNlIGNhbmRpZGF0ZXMsIGFwcGxpZXMgYGxhdGVzdC1yY2BcbiAqIEZvciBmZWF0dXJlIGJyYW5jaGVzLCBhcHBsaWVzIGBsYXRlc3QtZmVhdHVyZWBcbiAqIEZvciBkZXZlbG9wbWVudCBicmFuY2gsIGFwcGxpZXMgYGxhdGVzdC1kZXZgXG4gKiBBbGwgb3RoZXIgYnJhbmNoZXMsIG5vIHRhZyBpcyBhcHBsaWVzXG4gKiBAcGFyYW0ge3N0cmluZ30gaW1hZ2VJZCBpZCBvZiB0aGUgZG9ja2VyIGltYWdlIHRvIHdoaWNoIHRvIGFwcGx5IHRoZSB0YWdzXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVwbyBvcHRpb25hbCBvdmVycmlkZSBvZiB0aGUgZG9ja2VyIHJlcG8gdXJsIHRvIHVzZSAoZGVyaXZlZCBmcm9tIHBhY2thZ2UuanNvbiBieSBkZWZhdWx0KVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyVGFnVmVyc2lvbihcbiAgaW1hZ2VJZDogc3RyaW5nLFxuICByZXBvPzogc3RyaW5nID0gZ2V0RG9ja2VyUmVwbygpLFxuKSB7XG4gIGNvbnN0IHsgaXNSZWxlYXNlLCBtYWpvciwgbWlub3IsIHBhdGNoLCBicmFuY2ggfSA9IGF3YWl0IGdldFZlcnNpb24oKTtcbiAgLy8gZGV0ZXJtaW5lIHdoYXQgdGFncyB0byBhcHBseVxuICBpZiAoaXNSZWxlYXNlKSB7XG4gICAgYXdhaXQgZG9ja2VyVGFnKFxuICAgICAgaW1hZ2VJZCxcbiAgICAgIFsnbGF0ZXN0JywgYCR7bWFqb3J9YCwgYCR7bWFqb3J9LiR7bWlub3J9YCwgYCR7bWFqb3J9LiR7bWlub3J9LiR7cGF0Y2h9YF0sXG4gICAgICByZXBvLFxuICAgICk7XG4gIH0gZWxzZSBpZiAoYnJhbmNoID09PSBnZXREZXZCcmFuY2goKSkge1xuICAgIGF3YWl0IGRvY2tlclRhZyhpbWFnZUlkLCBbJ2xhdGVzdC1kZXYnXSwgcmVwbyk7XG4gIH0gZWxzZSBpZiAoYnJhbmNoLm1hdGNoKC9eKHJlbGVhc2V8cGF0Y2gpLS8pKSB7XG4gICAgYXdhaXQgZG9ja2VyVGFnKGltYWdlSWQsIFsnbGF0ZXN0LXJjJ10sIHJlcG8pO1xuICB9IGVsc2UgaWYgKGJyYW5jaC5tYXRjaCgvXmZlYXR1cmUtLykpIHtcbiAgICBhd2FpdCBkb2NrZXJUYWcoaW1hZ2VJZCwgWydsYXRlc3QtZmVhdHVyZSddLCByZXBvKTtcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBEb2NrZXJJbWFnZSA9IHtcbiAgcmVwb3NpdG9yeTogc3RyaW5nLFxuICB0YWc6IHN0cmluZyxcbiAgaWQ6IHN0cmluZyxcbiAgZGlnZXN0OiBzdHJpbmcsXG4gIGNyZWF0ZWQ6IERhdGUsXG4gIHNpemU6IG51bWJlcixcbn07XG5cbmV4cG9ydCB0eXBlIERvY2tlckltYWdlRmlsdGVyID0gKGk6IERvY2tlckltYWdlKSA9PiBib29sZWFuO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VySW1hZ2VzKFxuICByZXBvPzogP3N0cmluZyA9IGdldERvY2tlclJlcG8oKSxcbiAgZmlsdGVyPzogP0RvY2tlckltYWdlRmlsdGVyID0gbnVsbCxcbik6IFByb21pc2U8RG9ja2VySW1hZ2VbXT4ge1xuICByZXR1cm4gKFxuICAgIGF3YWl0IHNwYXduKFxuICAgICAgJ2RvY2tlcicsXG4gICAgICBbJ2ltYWdlcycsICctLWZvcm1hdCcsIGB7e2pzb24gLn19YCwgLi4uKHJlcG8gPyBbcmVwb10gOiBbXSldLFxuICAgICAgeyBjYXB0dXJlT3V0cHV0OiB0cnVlIH0sXG4gICAgKVxuICApXG4gICAgLnNwbGl0KCdcXG4nKVxuICAgIC5maWx0ZXIoKGxpbmUpID0+ICEhbGluZS50cmltKCkpXG4gICAgLm1hcCgobCkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBSZXBvc2l0b3J5OiByZXBvc2l0b3J5LFxuICAgICAgICBUYWc6IHRhZyxcbiAgICAgICAgSUQ6IGlkLFxuICAgICAgICBEaWdlc3Q6IGRpZ2VzdCxcbiAgICAgICAgQ3JlYXRlZEF0LFxuICAgICAgICBTaXplLFxuICAgICAgfSA9IEpTT04ucGFyc2UobC50cmltKCkpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVwb3NpdG9yeSxcbiAgICAgICAgdGFnLFxuICAgICAgICBpZCxcbiAgICAgICAgZGlnZXN0LFxuICAgICAgICBjcmVhdGVkOiBwYXJzZURvY2tlckRhdGUoQ3JlYXRlZEF0KSxcbiAgICAgICAgc2l6ZTogYnl0ZXMucGFyc2UoU2l6ZSksXG4gICAgICB9O1xuICAgIH0pXG4gICAgLmZpbHRlcihcbiAgICAgIChtKSA9PlxuICAgICAgICAobSAmJiBtLmlkKSAhPSBudWxsICYmXG4gICAgICAgICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nID8gZmlsdGVyKG0pIDogdHJ1ZSksXG4gICAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldERvY2tlcklkKFxuICB0YWc6IHN0cmluZyA9ICdsYXRlc3QnLFxuICByZXBvPzogP3N0cmluZyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIHJldHVybiAoYXdhaXQgZG9ja2VySW1hZ2VzKHJlcG8sIChtKSA9PiBtLnRhZyA9PT0gdGFnKSkubWFwKChtKSA9PiBtLmlkKVswXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldFVudGFnZ2VkRG9ja2VySWRzKFxuICByZXBvPzogP3N0cmluZyxcbiAgZmlsdGVyPzogP0RvY2tlckltYWdlRmlsdGVyID0gbnVsbCxcbik6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgcmV0dXJuIChcbiAgICBhd2FpdCBkb2NrZXJJbWFnZXMoXG4gICAgICByZXBvLFxuICAgICAgKG0pID0+XG4gICAgICAgIG0udGFnID09PSAnPG5vbmU+JyAmJiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJyA/IGZpbHRlcihtKSA6IHRydWUpLFxuICAgIClcbiAgKS5tYXAoKG0pID0+IG0uaWQpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RG9ja2VyVGFncyhcbiAgaWQ/OiA/c3RyaW5nLFxuICByZXBvPzogP3N0cmluZyxcbiAgZnVsbE5hbWU6IGJvb2xlYW4gPSBmYWxzZSxcbiAgZmlsdGVyPzogP0RvY2tlckltYWdlRmlsdGVyID0gbnVsbCxcbik6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgcmV0dXJuIChcbiAgICBhd2FpdCBkb2NrZXJJbWFnZXMoXG4gICAgICByZXBvLFxuICAgICAgKG0pID0+XG4gICAgICAgICghaWQgfHwgbS5pZCA9PT0gaWQpICYmXG4gICAgICAgICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nID8gZmlsdGVyKG0pIDogdHJ1ZSksXG4gICAgKVxuICApLm1hcCgobSkgPT4gKGZ1bGxOYW1lID8gYCR7bS5yZXBvc2l0b3J5fToke20udGFnfWAgOiBtLnRhZykpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0RG9ja2VyRGlnZXN0KFxuICBpbWFnZUlkOiBzdHJpbmcsXG4gIHJlcG8/OiBzdHJpbmcsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gKGF3YWl0IGRvY2tlckltYWdlcyhyZXBvLCAobSkgPT4gbS5pZCA9PT0gaW1hZ2VJZCkpLm1hcChcbiAgICAobSkgPT4gbS5kaWdlc3QsXG4gIClbMF07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJMb2dpbihcbiAgdXNlcjogc3RyaW5nLFxuICBwYXNzd29yZDogc3RyaW5nLFxuICByZWdpc3RyeTogc3RyaW5nLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHJlZyA9IHJlZ2lzdHJ5IHx8IGdldERvY2tlckNvbmZpZygpLnJlZ2lzdHJ5O1xuICBhd2FpdCBzcGF3bihcbiAgICAnZG9ja2VyJyxcbiAgICBbXG4gICAgICAnbG9naW4nLFxuICAgICAgJy11JyxcbiAgICAgIHVzZXIgfHwgcHJvY2Vzcy5lbnYuQVJUSUZBQ1RPUllfVVNFUiB8fCAnJyxcbiAgICAgICctcCcsXG4gICAgICBwYXNzd29yZCB8fCBwcm9jZXNzLmVudi5BUlRJRkFDVE9SWV9QQVNTV09SRCB8fCAnJyxcbiAgICAgIC4uLihyZWcgPyBbcmVnXSA6IFtdKSxcbiAgICBdLFxuICAgIHsgc3RkaW86ICdpbmhlcml0JyB9LFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyUHVzaChcbiAgdGFncz86IHN0cmluZ1tdID0gWydsYXRlc3QnXSxcbiAgcmVwbz86IHN0cmluZyA9IGdldERvY2tlclJlcG8oKSxcbikge1xuICAvLyBkbyB0aGlzIHNlcXVlbnRpYWxseSwgc28geW91IGRvbid0IHB1c2ggdGhlIHNhbWUgaW1hZ2Ugc2ltdWx0YW5lb3VzbHlcbiAgYXdhaXQgdGFncy5yZWR1Y2UoYXN5bmMgKHByZXYsIHRhZykgPT4ge1xuICAgIGF3YWl0IHByZXY7XG4gICAgYXdhaXQgc3Bhd24oJ2RvY2tlcicsIFsncHVzaCcsIGAke3JlcG99OiR7dGFnfWBdLCB7IHN0ZGlvOiAnaW5oZXJpdCcgfSk7XG4gIH0sIFByb21pc2UucmVzb2x2ZSgpKTtcbn1cblxuZXhwb3J0IHR5cGUgRG9ja2VyUHVsbE9wdGlvbnMgPSB7XG4gIGltYWdlOiBzdHJpbmcsXG4gIG9mZmxpbmU/OiBib29sZWFuLFxuICB0ZXN0VXJsPzogP3N0cmluZyxcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb2NrZXJQdWxsKHtcbiAgaW1hZ2UsXG4gIG9mZmxpbmUgPSBwcm9jZXNzLmFyZ3YuaW5jbHVkZXMoJy0tb2ZmbGluZScpLFxuICB0ZXN0VXJsLFxufTogRG9ja2VyUHVsbE9wdGlvbnMpIHtcbiAgaWYgKFxuICAgIG9mZmxpbmUgfHxcbiAgICAhKGF3YWl0IGlzUmVhY2hhYmxlKHRlc3RVcmwgfHwgJ2h0dHBzOi8vaHViLmRvY2tlci5jb20nKSlcbiAgKSB7XG4gICAgaWYgKG9mZmxpbmUgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09mZmxpbmUsIGNhbm5vdCBkb2NrZXIgcHVsbCcpO1xuICAgIH1cbiAgICBidWlsZExvZygnSXQgbG9va3MgbGlrZSB5b3UgYXJlIG9mZmxpbmUsIHNraXBwaW5nIGRvY2tlciBwdWxsJyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gdGhyb3dzIG9uIGZhaWx1cmVcbiAgICBhd2FpdCBzcGF3bignZG9ja2VyJywgWydwdWxsJywgaW1hZ2VdLCB7IHN0ZGlvOiAnaW5oZXJpdCcgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvY2tlclJtaShcbiAgaW1hZ2VzOiBzdHJpbmdbXSA9IFtdLFxuICBpZ25vcmVFcnJvcnM6IGJvb2xlYW4gPSB0cnVlLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIC8vIG11c3QgZG8gdGhlc2Ugc2VxdWVudGlhbGx5LCBvciB0aGV5IHdpbGwgaW50ZXJmZXJlIHdpdGggZWFjaCBvdGhlclxuICBhd2FpdCBpbWFnZXMucmVkdWNlKGFzeW5jIChwcmV2LCBpbWFnZSkgPT4ge1xuICAgIGF3YWl0IHByZXY7XG4gICAgYXdhaXQgc3Bhd24oJ2RvY2tlcicsIFsncm1pJywgaW1hZ2VdLCB7IHN0ZGlvOiAnaW5oZXJpdCcgfSkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgaWYgKGlnbm9yZUVycm9ycykge1xuICAgICAgICBidWlsZExvZyhcbiAgICAgICAgICBgV2FybmluZyAoaWdub3JlZCBFcnJvcik6IEZhaWxlZCB0byBybSBpbWFnZShzKTogJHtlcnIubWVzc2FnZX1gLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCBQcm9taXNlLnJlc29sdmUoKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREb2NrZXJSZXBvKCk6IHN0cmluZyB7XG4gIGNvbnN0IHsgcmVnaXN0cnksIHJlcG9zaXRvcnk6IGRrclJlcG8sIG5hbWU6IGRrck5hbWUgfSA9IGdldERvY2tlckNvbmZpZygpO1xuICBjb25zdCByZXBvc2l0b3J5ID0gZGtyUmVwbyB8fCBnZXRQa2dTY29wZSgpO1xuICBjb25zdCBuYW1lID0gZGtyTmFtZSB8fCBnZXRQa2dOYW1lKGZhbHNlKTtcbiAgaWYgKCFyZXBvc2l0b3J5IHx8ICFuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0RvY2tlciBjb25maWd1cmF0aW9uIGlzIG1pc3Npbmcgb3IgaW5jb21wbGV0ZSBpbiBwYWNrYWdlLmpzb24nLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGAke3JlZ2lzdHJ5ID8gYCR7cmVnaXN0cnl9L2AgOiAnJ30ke3JlcG9zaXRvcnl9LyR7bmFtZX1gO1xufVxuXG5leHBvcnQgdHlwZSBQdWxsQW5kUnVuQ29udGFpbmVyT3B0aW9ucyA9IHtcbiAgLi4uRG9ja2VyUHVsbE9wdGlvbnMsXG4gIHJ1bkFyZ3M/OiBzdHJpbmdbXSxcbiAgY21kPzogc3RyaW5nW10sXG4gIG5ldHdvcms/OiA/c3RyaW5nLFxuICBhbGlhcz86ID9zdHJpbmcsXG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZG9ja2VyUHVsbEFuZFJ1bkNvbnRhaW5lcihcbiAgaW1hZ2U6IHN0cmluZyxcbiAgb3B0aW9uczogUHVsbEFuZFJ1bkNvbnRhaW5lck9wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHtcbiAgICBydW5BcmdzID0gW10sXG4gICAgY21kID0gW10sXG4gICAgbmV0d29yayxcbiAgICBhbGlhcyxcbiAgICBvZmZsaW5lID0gcHJvY2Vzcy5hcmd2LmluY2x1ZGVzKCctLW9mZmxpbmUnKSxcbiAgICB0ZXN0VXJsLFxuICB9ID0gb3B0aW9ucztcblxuICB0cnkge1xuICAgIGF3YWl0IGRvY2tlclB1bGwoeyBpbWFnZSwgb2ZmbGluZSwgdGVzdFVybCB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgYnVpbGRMb2coYGRvY2tlciBwdWxsIGZhaWxlZCAoJHtlcnIubWVzc2FnZX0pLCBhdHRlbXB0aW5nIHRvIGNvbnRpbnVlLi4uYCk7XG4gIH1cbiAgY29uc3QgeyBpZCB9ID0gYXdhaXQgZG9ja2VyQ29udGFpbmVyUnVuRGFlbW9uKHsgaW1hZ2UsIHJ1bkFyZ3MsIGNtZCB9KTtcbiAgaWYgKG5ldHdvcmspIHtcbiAgICBhd2FpdCBkb2NrZXJOZXR3b3JrQ29ubmVjdChuZXR3b3JrLCBpZCwgYWxpYXMpO1xuICB9XG4gIHJldHVybiBpZDtcbn1cblxuZXhwb3J0IHR5cGUgQ29weUZpbGVQYXRoQ29uZmlnID0ge1xuICBmcm9tOiBzdHJpbmcsXG4gIHRvOiBzdHJpbmcsXG59O1xuXG5leHBvcnQgdHlwZSBDb3B5RmlsZXNGcm9tRG9ja2VySW1hZ2VDb25maWcgPSB7XG4gIGltYWdlSWQ6IHN0cmluZyxcbiAgZmlsZVBhdGhzOiBDb3B5RmlsZVBhdGhDb25maWdbXSxcbiAgaWdub3JlRXJyb3JzPzogP2Jvb2xlYW4sXG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29weUZpbGVzRnJvbURvY2tlckltYWdlKHtcbiAgaW1hZ2VJZCxcbiAgZmlsZVBhdGhzLFxuICBpZ25vcmVFcnJvcnMsXG59OiBDb3B5RmlsZXNGcm9tRG9ja2VySW1hZ2VDb25maWcpOiBQcm9taXNlPGFueT4ge1xuICBjb25zdCBjb250YWluZXIgPSBhd2FpdCBkb2NrZXJDb250YWluZXJSdW5EYWVtb24oe1xuICAgIGltYWdlOiBpbWFnZUlkLFxuICAgIHJ1bkFyZ3M6IFsnLWl0JywgJy0tcm0nLCAnLS1lbnRyeXBvaW50PS9iaW4vYmFzaCddLFxuICAgIGNtZDogWydyZWFkJywgJy1wJywgJ3BhdXNlJ10sXG4gIH0pO1xuXG4gIGJ1aWxkTG9nKGBDb3B5aW5nIEZpbGVzIGZyb20gRG9ja2VyIEltYWdlIC0gaW1hZ2VJZCAoJHtpbWFnZUlkfSlgKTtcblxuICBjb25zdCBzcGF3bk9wdGlvbnMgPSB7XG4gICAgc3RkaW86ICdpbmhlcml0JyxcbiAgICBwaXBlT3V0cHV0OiB0cnVlLFxuICAgIGNhcHR1cmVPdXRwdXQ6IGZhbHNlLFxuICB9O1xuICBjb25zdCBjb3B5RXJyb3JzID0gW107XG5cbiAgdHJ5IHtcbiAgICBmaWxlUGF0aHMuZm9yRWFjaChhc3luYyAoZnApID0+IHtcbiAgICAgIC8vIFRyeSB0byBjb3B5IGZyb20gdGhlIERlYnVnIEZvbGRlclxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc3Bhd24oXG4gICAgICAgICAgJ2RvY2tlcicsXG4gICAgICAgICAgWydjcCcsIGAke2NvbnRhaW5lci5pZH06JHtmcC5mcm9tfWAsIGZwLnRvXSxcbiAgICAgICAgICBzcGF3bk9wdGlvbnMsXG4gICAgICAgICk7XG4gICAgICAgIGJ1aWxkTG9nKGBDb3BpZWQgJHtmcC5mcm9tfSA9PiAke2ZwLnRvfWApO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29weUVycm9ycy5wdXNoKGVycm9yKTtcbiAgICAgICAgYnVpbGRMb2coYEVycm9yIGNvcHlpbmcgZmlsZSAke2ZwLmZyb219YCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZmluYWxseSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGRvY2tlckNvbnRhaW5lcktpbGwoY29udGFpbmVyLmlkKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29weUVycm9ycy5wdXNoKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBpZiAoY29weUVycm9ycy5sZW5ndGggPiAwICYmIGlnbm9yZUVycm9ycyAhPT0gdHJ1ZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU29tZSBmaWxlcyBmYWlsZWQgdG8gY29weScpO1xuICB9XG59XG4iXX0=
|