@aws-cdk-testing/cli-integ 2.173.4 → 3.0.1
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/.eslintrc.js +9 -0
- package/LICENSE +2 -1
- package/bin/query-github +1 -1
- package/bin/query-github.js +3 -3
- package/bin/query-github.ts +56 -0
- package/bin/run-suite +1 -1
- package/bin/run-suite.js +3 -3
- package/bin/run-suite.ts +140 -0
- package/bin/stage-distribution +1 -1
- package/bin/stage-distribution.js +3 -2
- package/bin/stage-distribution.ts +267 -0
- package/bin/test-root +1 -1
- package/bin/test-root.ts +3 -0
- package/lib/aws.js +9 -6
- package/lib/aws.ts +263 -0
- package/lib/cli/query-github.d.ts +1 -0
- package/lib/cli/query-github.js +54 -0
- package/lib/cli/query-github.ts +56 -0
- package/lib/cli/run-suite.d.ts +1 -0
- package/lib/cli/run-suite.js +131 -0
- package/lib/cli/run-suite.ts +140 -0
- package/lib/cli/stage-distribution.d.ts +1 -0
- package/lib/cli/stage-distribution.js +217 -0
- package/lib/cli/stage-distribution.ts +267 -0
- package/lib/cli/test-root.d.ts +1 -0
- package/lib/cli/test-root.js +6 -0
- package/lib/cli/test-root.ts +3 -0
- package/lib/corking.ts +33 -0
- package/lib/eventually.js +3 -3
- package/lib/eventually.ts +42 -0
- package/lib/files.js +3 -2
- package/lib/files.ts +80 -0
- package/lib/github.js +6 -5
- package/lib/github.ts +43 -0
- package/lib/index.ts +13 -0
- package/lib/integ-test.ts +81 -0
- package/lib/lists.ts +9 -0
- package/lib/memoize.ts +14 -0
- package/lib/npm.ts +41 -0
- package/lib/package-sources/release-source.js +3 -2
- package/lib/package-sources/release-source.ts +81 -0
- package/lib/package-sources/repo-source.ts +111 -0
- package/lib/package-sources/repo-tools/npm.js +5 -4
- package/lib/package-sources/repo-tools/npm.ts +48 -0
- package/lib/package-sources/source.ts +35 -0
- package/lib/package-sources/subprocess.ts +15 -0
- package/lib/resource-pool.js +2 -2
- package/lib/resource-pool.ts +140 -0
- package/lib/resources.ts +4 -0
- package/lib/shell.js +8 -5
- package/lib/shell.ts +168 -0
- package/lib/staging/codeartifact.js +11 -8
- package/lib/staging/codeartifact.ts +387 -0
- package/lib/staging/maven.js +5 -3
- package/lib/staging/maven.ts +95 -0
- package/lib/staging/npm.ts +62 -0
- package/lib/staging/nuget.ts +75 -0
- package/lib/staging/parallel-shell.js +2 -2
- package/lib/staging/parallel-shell.ts +51 -0
- package/lib/staging/pypi.ts +50 -0
- package/lib/staging/usage-dir.ts +99 -0
- package/lib/with-aws.js +3 -2
- package/lib/with-aws.ts +67 -0
- package/lib/with-cdk-app.js +23 -14
- package/lib/with-cdk-app.ts +742 -0
- package/lib/with-cli-lib.ts +134 -0
- package/lib/with-packages.ts +15 -0
- package/lib/with-sam.js +7 -4
- package/lib/with-sam.ts +288 -0
- package/lib/with-temporary-directory.ts +35 -0
- package/lib/with-timeout.ts +33 -0
- package/lib/xpmutex.js +2 -2
- package/lib/xpmutex.ts +218 -0
- package/package.json +86 -62
- package/resources/cloud-assemblies/0.36.0/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/cdk.out +1 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.js +22 -13
- package/tests/cli-integ-tests/bootstrapping.integtest.ts +493 -0
- package/tests/cli-integ-tests/cli-lib.integtest.js +3 -2
- package/tests/cli-integ-tests/cli-lib.integtest.ts +90 -0
- package/tests/cli-integ-tests/cli.integtest.js +76 -49
- package/tests/cli-integ-tests/cli.integtest.ts +2874 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.js +2 -2
- package/tests/cli-integ-tests/garbage-collection.integtest.ts +392 -0
- package/tests/init-csharp/init-csharp.integtest.ts +15 -0
- package/tests/init-fsharp/init-fsharp.integtest.ts +15 -0
- package/tests/init-go/init-go.integtest.ts +23 -0
- package/tests/init-java/init-java.integtest.ts +14 -0
- package/tests/init-javascript/init-javascript.integtest.ts +59 -0
- package/tests/init-python/init-python.integtest.ts +20 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.ts +66 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.ts +13 -0
- package/tests/tool-integrations/amplify.integtest.ts +43 -0
- package/tests/tool-integrations/with-tool-context.ts +14 -0
- package/tests/uberpackage/uberpackage.integtest.ts +11 -0
- package/resources/cdk-apps/cfn-include-app/.gitignore +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a, _b, _c;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
const child_process = require("child_process");
|
|
4
5
|
const fs = require("fs-extra");
|
|
@@ -13,15 +14,15 @@ if (argv[0] === 'install') {
|
|
|
13
14
|
// Replace paths in the 'package.json' in the current directory
|
|
14
15
|
if (fs.pathExistsSync('package.json')) {
|
|
15
16
|
const packageJson = fs.readJsonSync('package.json', { encoding: 'utf-8' });
|
|
16
|
-
for (const deps of [packageJson.dependencies
|
|
17
|
+
for (const deps of [(_a = packageJson.dependencies) !== null && _a !== void 0 ? _a : {}, (_b = packageJson.devDependencies) !== null && _b !== void 0 ? _b : {}]) {
|
|
17
18
|
for (const [name, version] of Object.entries(deps)) {
|
|
18
|
-
deps[name] = repoPackageMap[name]
|
|
19
|
+
deps[name] = (_c = repoPackageMap[name]) !== null && _c !== void 0 ? _c : version;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
fs.writeJsonSync('package.json', packageJson, { encoding: 'utf-8' });
|
|
22
23
|
}
|
|
23
24
|
// Replace package names on the command line
|
|
24
|
-
argv = argv.map(x => repoPackageMap[x]
|
|
25
|
+
argv = argv.map(x => { var _a; return (_a = repoPackageMap[x]) !== null && _a !== void 0 ? _a : x; });
|
|
25
26
|
}
|
|
26
27
|
////////////////////////////////////////////////////////////////////////
|
|
27
28
|
// Shell out to original npm
|
|
@@ -39,4 +40,4 @@ child.once('close', code => {
|
|
|
39
40
|
process.exitCode = code;
|
|
40
41
|
}
|
|
41
42
|
});
|
|
42
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnBtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibnBtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtDQUErQztBQUMvQywrQkFBK0I7QUFFL0IsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFakMsc0NBQXNDO0FBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7QUFFeEIsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxFQUFFLENBQUM7SUFDMUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUNELE1BQU0sY0FBYyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBRTVGLCtEQUErRDtJQUMvRCxJQUFJLEVBQUUsQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUN0QyxNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzNFLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFBLFdBQVcsQ0FBQyxZQUFZLG1DQUFJLEVBQUUsRUFBRSxNQUFBLFdBQVcsQ0FBQyxlQUFlLG1DQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDdkYsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQUEsY0FBYyxDQUFDLElBQUksQ0FBQyxtQ0FBSSxPQUFPLENBQUM7WUFDL0MsQ0FBQztRQUNILENBQUM7UUFDRCxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQUMsT0FBQSxNQUFBLGNBQWMsQ0FBQyxDQUFDLENBQUMsbUNBQUksQ0FBQyxDQUFBLEVBQUEsQ0FBQyxDQUFDO0FBQy9DLENBQUM7QUFFRCx3RUFBd0U7QUFDeEUsNkJBQTZCO0FBRTdCLE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFO0lBQzNFLEtBQUssRUFBRSxLQUFLO0lBQ1osS0FBSyxFQUFFLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUM7Q0FDeEMsQ0FBQyxDQUFDO0FBRUgsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUU7SUFDdEIsc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakIsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDdkIsQ0FBQyxDQUFDLENBQUM7QUFFSCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRTtJQUN6QixJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsT0FBTyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDMUIsQ0FBQztBQUNILENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2hpbGRfcHJvY2VzcyBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzLWV4dHJhJztcblxubGV0IGFyZ3YgPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoMik7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG5jb25zb2xlLmxvZygnZmFrZSBucG0nKTtcblxuaWYgKGFyZ3ZbMF0gPT09ICdpbnN0YWxsJykge1xuICBpZiAoIXByb2Nlc3MuZW52LlJFUE9fUEFDS0FHRV9NQVApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JFUE9fUEFDS0FHRV9NQVAgbm90IHNldCcpO1xuICB9XG4gIGNvbnN0IHJlcG9QYWNrYWdlTWFwID0gZnMucmVhZEpzb25TeW5jKHByb2Nlc3MuZW52LlJFUE9fUEFDS0FHRV9NQVAsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG5cbiAgLy8gUmVwbGFjZSBwYXRocyBpbiB0aGUgJ3BhY2thZ2UuanNvbicgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5XG4gIGlmIChmcy5wYXRoRXhpc3RzU3luYygncGFja2FnZS5qc29uJykpIHtcbiAgICBjb25zdCBwYWNrYWdlSnNvbiA9IGZzLnJlYWRKc29uU3luYygncGFja2FnZS5qc29uJywgeyBlbmNvZGluZzogJ3V0Zi04JyB9KTtcbiAgICBmb3IgKGNvbnN0IGRlcHMgb2YgW3BhY2thZ2VKc29uLmRlcGVuZGVuY2llcyA/PyB7fSwgcGFja2FnZUpzb24uZGV2RGVwZW5kZW5jaWVzID8/IHt9XSkge1xuICAgICAgZm9yIChjb25zdCBbbmFtZSwgdmVyc2lvbl0gb2YgT2JqZWN0LmVudHJpZXMoZGVwcykpIHtcbiAgICAgICAgZGVwc1tuYW1lXSA9IHJlcG9QYWNrYWdlTWFwW25hbWVdID8/IHZlcnNpb247XG4gICAgICB9XG4gICAgfVxuICAgIGZzLndyaXRlSnNvblN5bmMoJ3BhY2thZ2UuanNvbicsIHBhY2thZ2VKc29uLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pO1xuICB9XG5cbiAgLy8gUmVwbGFjZSBwYWNrYWdlIG5hbWVzIG9uIHRoZSBjb21tYW5kIGxpbmVcbiAgYXJndiA9IGFyZ3YubWFwKHggPT4gcmVwb1BhY2thZ2VNYXBbeF0gPz8geCk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gIFNoZWxsIG91dCB0byBvcmlnaW5hbCBucG1cblxuY29uc3QgY2hpbGQgPSBjaGlsZF9wcm9jZXNzLnNwYXduKCdub2RlJywgW3JlcXVpcmUucmVzb2x2ZSgnbnBtJyksIC4uLmFyZ3ZdLCB7XG4gIHNoZWxsOiBmYWxzZSxcbiAgc3RkaW86IFsnaWdub3JlJywgJ2luaGVyaXQnLCAnaW5oZXJpdCddLFxufSk7XG5cbmNoaWxkLm9uY2UoJ2Vycm9yJywgZSA9PiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUuZXJyb3IoZSk7XG4gIHByb2Nlc3MuZXhpdENvZGUgPSAxO1xufSk7XG5cbmNoaWxkLm9uY2UoJ2Nsb3NlJywgY29kZSA9PiB7XG4gIGlmIChjb2RlKSB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IGNvZGU7XG4gIH1cbn0pO1xuIl19
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as child_process from 'child_process';
|
|
2
|
+
import * as fs from 'fs-extra';
|
|
3
|
+
|
|
4
|
+
let argv = process.argv.slice(2);
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line no-console
|
|
7
|
+
console.log('fake npm');
|
|
8
|
+
|
|
9
|
+
if (argv[0] === 'install') {
|
|
10
|
+
if (!process.env.REPO_PACKAGE_MAP) {
|
|
11
|
+
throw new Error('REPO_PACKAGE_MAP not set');
|
|
12
|
+
}
|
|
13
|
+
const repoPackageMap = fs.readJsonSync(process.env.REPO_PACKAGE_MAP, { encoding: 'utf-8' });
|
|
14
|
+
|
|
15
|
+
// Replace paths in the 'package.json' in the current directory
|
|
16
|
+
if (fs.pathExistsSync('package.json')) {
|
|
17
|
+
const packageJson = fs.readJsonSync('package.json', { encoding: 'utf-8' });
|
|
18
|
+
for (const deps of [packageJson.dependencies ?? {}, packageJson.devDependencies ?? {}]) {
|
|
19
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
20
|
+
deps[name] = repoPackageMap[name] ?? version;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
fs.writeJsonSync('package.json', packageJson, { encoding: 'utf-8' });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Replace package names on the command line
|
|
27
|
+
argv = argv.map(x => repoPackageMap[x] ?? x);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
////////////////////////////////////////////////////////////////////////
|
|
31
|
+
// Shell out to original npm
|
|
32
|
+
|
|
33
|
+
const child = child_process.spawn('node', [require.resolve('npm'), ...argv], {
|
|
34
|
+
shell: false,
|
|
35
|
+
stdio: ['ignore', 'inherit', 'inherit'],
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
child.once('error', e => {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.error(e);
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
child.once('close', code => {
|
|
45
|
+
if (code) {
|
|
46
|
+
process.exitCode = code;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface IPackageSourceSetup {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly description: string;
|
|
4
|
+
|
|
5
|
+
prepare(): Promise<void>;
|
|
6
|
+
cleanup(): Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IPackageSource {
|
|
10
|
+
makeCliAvailable(): Promise<void>;
|
|
11
|
+
|
|
12
|
+
assertJsiiPackagesAvailable(): void;
|
|
13
|
+
majorVersion(): string;
|
|
14
|
+
|
|
15
|
+
initializeDotnetPackages(targetDir: string): Promise<void>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* CLI version
|
|
19
|
+
*/
|
|
20
|
+
requestedCliVersion(): string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Framework version if it's different than the CLI version
|
|
24
|
+
*
|
|
25
|
+
* Not all tests will respect this.
|
|
26
|
+
*/
|
|
27
|
+
requestedFrameworkVersion(): string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Versions of alpha packages if different than the CLI version
|
|
31
|
+
*
|
|
32
|
+
* Not all tests will respect this.
|
|
33
|
+
*/
|
|
34
|
+
requestedAlphaVersion(): string;
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReleasePackageSource } from './release-source';
|
|
2
|
+
import { RepoPackageSource } from './repo-source';
|
|
3
|
+
import { IPackageSourceSetup, IPackageSource } from './source';
|
|
4
|
+
|
|
5
|
+
export function serializeForSubprocess(s: IPackageSourceSetup) {
|
|
6
|
+
process.env.PACKAGE_SOURCE = s.name;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function packageSourceInSubprocess(): IPackageSource {
|
|
10
|
+
switch (process.env.PACKAGE_SOURCE) {
|
|
11
|
+
case 'repo': return new RepoPackageSource();
|
|
12
|
+
case 'release': return new ReleasePackageSource();
|
|
13
|
+
default: throw new Error(`Unrecognized package source: ${process.env.PACKAGE_SOURCE}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/lib/resource-pool.js
CHANGED
|
@@ -99,7 +99,7 @@ class ResourcePool {
|
|
|
99
99
|
async returnValue(value) {
|
|
100
100
|
const lock = this.locks[value];
|
|
101
101
|
delete this.locks[value];
|
|
102
|
-
await lock
|
|
102
|
+
await (lock === null || lock === void 0 ? void 0 : lock.release());
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
exports.ResourcePool = ResourcePool;
|
|
@@ -114,4 +114,4 @@ function fisherYatesShuffle(xs) {
|
|
|
114
114
|
xs[i] = h;
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
117
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2UtcG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInJlc291cmNlLXBvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsdUNBQXdEO0FBRXhEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQWEsWUFBWTtJQUNoQixNQUFNLENBQUMsYUFBYSxDQUFtQixJQUFZLEVBQUUsU0FBYztRQUN4RSxNQUFNLElBQUksR0FBRyxxQkFBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxPQUFPLElBQUksWUFBWSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBTUQsWUFBcUMsSUFBaUIsRUFBRSxTQUFjO1FBQWpDLFNBQUksR0FBSixJQUFJLENBQWE7UUFIckMsWUFBTyxHQUE0QixFQUFFLENBQUM7UUFDdEMsVUFBSyxHQUFzQyxFQUFFLENBQUM7UUFHN0QsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBRUQsK0JBQStCO1FBQy9CLFNBQVMsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUM7UUFDM0Isa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFFM0IsS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUM1QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLEtBQUssQ0FBQyxJQUFJO1FBQ2YsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNaLHFFQUFxRTtZQUNyRSxvRUFBb0U7WUFDcEUsRUFBRTtZQUNGLCtFQUEr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RyxDQUFDLENBQUM7SUFDWixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElMb2NrLCBYcE11dGV4LCBYcE11dGV4UG9vbCB9IGZyb20gJy4veHBtdXRleCc7XG5cbi8qKlxuICogQSBjbGFzcyB0aGF0IGhvbGRzIGEgcG9vbCBvZiByZXNvdXJjZXMgYW5kIGdpdmVzIHRoZW0gb3V0IGFuZCByZXR1cm5zIHRoZW0gb24tZGVtYW5kXG4gKlxuICogVGhlIHJlc291cmNlcyB3aWxsIGJlIGdpdmVuIG91dCBmcm9udCB0byBiYWNrLCB3aGVuIHRoZXkgYXJlIHJldHVybmVkXG4gKiB0aGUgbW9zdCByZWNlbnRseSByZXR1cm5lZCB2ZXJzaW9uIHdpbGwgYmUgZ2l2ZW4gb3V0IGFnYWluIChmb3IgYmVzdFxuICogY2FjaGUgY29oZXJlbmN5KS5cbiAqXG4gKiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgY29uc3VtZXJzIHdhaXRpbmcgZm9yIGEgcmVzb3VyY2UsIGNvbnN1bWVycyBhcmUgc2VydmljZWRcbiAqIGluIEZJRk8gb3JkZXIgZm9yIG1vc3QgZmFpcm5lc3MuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVBvb2w8QSBleHRlbmRzIHN0cmluZz1zdHJpbmc+IHtcbiAgcHVibGljIHN0YXRpYyB3aXRoUmVzb3VyY2VzPEEgZXh0ZW5kcyBzdHJpbmc+KG5hbWU6IHN0cmluZywgcmVzb3VyY2VzOiBBW10pIHtcbiAgICBjb25zdCBwb29sID0gWHBNdXRleFBvb2wuZnJvbU5hbWUobmFtZSk7XG4gICAgcmV0dXJuIG5ldyBSZXNvdXJjZVBvb2wocG9vbCwgcmVzb3VyY2VzKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb3VyY2VzOiBSZWFkb25seUFycmF5PEE+O1xuICBwcml2YXRlIHJlYWRvbmx5IG11dGV4ZXM6IFJlY29yZDxzdHJpbmcsIFhwTXV0ZXg+ID0ge307XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9ja3M6IFJlY29yZDxzdHJpbmcsIElMb2NrIHwgdW5kZWZpbmVkPiA9IHt9O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBwb29sOiBYcE11dGV4UG9vbCwgcmVzb3VyY2VzOiBBW10pIHtcbiAgICBpZiAocmVzb3VyY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHJlc291cmNlIGluIHRoZSBwb29sJyk7XG4gICAgfVxuXG4gICAgLy8gU2h1ZmZsZSB0byByZWR1Y2UgY29udGVudGlvblxuICAgIHJlc291cmNlcyA9IFsuLi5yZXNvdXJjZXNdO1xuICAgIGZpc2hlcllhdGVzU2h1ZmZsZShyZXNvdXJjZXMpO1xuICAgIHRoaXMucmVzb3VyY2VzID0gcmVzb3VyY2VzO1xuXG4gICAgZm9yIChjb25zdCByZXMgb2YgcmVzb3VyY2VzKSB7XG4gICAgICB0aGlzLm11dGV4ZXNbcmVzXSA9IHRoaXMucG9vbC5tdXRleChyZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUYWtlIG9uZSB2YWx1ZSBmcm9tIHRoZSByZXNvdXJjZSBwb29sXG4gICAqXG4gICAqIElmIG5vIHN1Y2ggdmFsdWUgaXMgY3VycmVudGx5IGF2YWlsYWJsZSwgd2FpdCB1bnRpbCBpdCBpcy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyB0YWtlKCk6IFByb21pc2U8SUxlYXNlPEE+PiB7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIC8vIFN0YXJ0IGEgd2FpdCBvbiB0aGUgdW5sb2NrIG5vdyAtLSBpZiB0aGUgdW5sb2NrIHNpZ25hbCBjb21lcyBhZnRlclxuICAgICAgLy8gd2UgdHJ5IHRvIGFjcXVpcmUgYnV0IGJlZm9yZSB3ZSBzdGFydCB0aGUgd2FpdCwgd2UgbWlnaHQgbWlzcyBpdC5cbiAgICAgIC8vXG4gICAgICAvLyAoVGhlIHRpbWVvdXQgaXMgaW4gY2FzZSB0aGUgdW5sb2NrIHNpZ25hbCBkb2Vzbid0IGNvbWUgZm9yIHdoYXRldmVyIHJlYXNvbikuXG4gICAgICBjb25zdCB3YWl0ID0gdGhpcy5wb29sLmF3YWl0VW5sb2NrKDEwXzAwMCk7XG5cbiAgICAgIC8vIFRyeSBhbGwgbXV0ZXhlcywgd2UgbWlnaHQgbmVlZCB0byByZWFjcXVpcmUgYW4gZXhwaXJlZCBsb2NrXG4gICAgICBmb3IgKGNvbnN0IHJlcyBvZiB0aGlzLnJlc291cmNlcykge1xuICAgICAgICBjb25zdCBsZWFzZSA9IGF3YWl0IHRoaXMudHJ5T2J0YWluTGVhc2UocmVzKTtcbiAgICAgICAgaWYgKGxlYXNlKSB7XG4gICAgICAgICAgLy8gSWdub3JlIHRoZSB3YWl0IChjb3VudCBhcyBoYW5kbGVkKVxuICAgICAgICAgIHdhaXQudGhlbigoKSA9PiB7fSwgKCkgPT4ge30pO1xuICAgICAgICAgIHJldHVybiBsZWFzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBOb25lIGF2YWlsYWJsZSwgd2FpdCB1bnRpbCBvbmUgZ2V0cyB1bmxvY2tlZCB0aGVuIHRyeSBhZ2FpblxuICAgICAgYXdhaXQgd2FpdDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIGJsb2NrIHVzaW5nIGEgc2luZ2xlIHJlc291cmNlIGZyb20gdGhlIHBvb2xcbiAgICovXG4gIHB1YmxpYyBhc3luYyB1c2luZzxCPihibG9jazogKHg6IEEpID0+IEIgfCBQcm9taXNlPEI+KTogUHJvbWlzZTxCPiB7XG4gICAgY29uc3QgbGVhc2UgPSBhd2FpdCB0aGlzLnRha2UoKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGJsb2NrKGxlYXNlLnZhbHVlKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgbGVhc2UuZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdHJ5T2J0YWluTGVhc2UodmFsdWU6IEEpIHtcbiAgICBjb25zdCBsb2NrID0gYXdhaXQgdGhpcy5tdXRleGVzW3ZhbHVlXS50cnlBY3F1aXJlKCk7XG4gICAgaWYgKCFsb2NrKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHRoaXMubG9ja3NbdmFsdWVdID0gbG9jaztcbiAgICByZXR1cm4gdGhpcy5tYWtlTGVhc2UodmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBtYWtlTGVhc2UodmFsdWU6IEEpOiBJTGVhc2U8QT4ge1xuICAgIGxldCBkaXNwb3NlZCA9IGZhbHNlO1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZSxcbiAgICAgIGRpc3Bvc2U6IGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKGRpc3Bvc2VkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIGRpc3Bvc2UoKSBvbiBhbiBhbHJlYWR5LWRpc3Bvc2VkIGxlYXNlLicpO1xuICAgICAgICB9XG4gICAgICAgIGRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV0dXJuVmFsdWUodmFsdWUpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZW4gYSB2YWx1ZSBpcyByZXR1cm5lZDpcbiAgICpcbiAgICogLSBJZiBzb21lb25lJ3Mgd2FpdGluZyBmb3IgaXQsIGdpdmUgaXQgdG8gdGhlbVxuICAgKiAtIE90aGVyd2lzZSBwdXQgaXQgYmFjayBpbnRvIHRoZSBwb29sXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJldHVyblZhbHVlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBjb25zdCBsb2NrID0gdGhpcy5sb2Nrc1t2YWx1ZV07XG4gICAgZGVsZXRlIHRoaXMubG9ja3NbdmFsdWVdO1xuICAgIGF3YWl0IGxvY2s/LnJlbGVhc2UoKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgc2luZ2xlIHZhbHVlIHRha2VuIGZyb20gdGhlIHBvb2xcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTGVhc2U8QT4ge1xuICAvKipcbiAgICogVGhlIHZhbHVlIG9idGFpbmVkIGJ5IHRoZSBsZWFzZVxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWU6IEE7XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbGVhc2VkIHZhbHVlIHRvIHRoZSBwb29sXG4gICAqL1xuICBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogU2h1ZmZsZSBhbiBhcnJheSBpbi1wbGFjZVxuICovXG5mdW5jdGlvbiBmaXNoZXJZYXRlc1NodWZmbGU8QT4oeHM6IEFbXSkge1xuICBmb3IgKGxldCBpID0geHMubGVuZ3RoIC0gMTsgaSA+PSAxOyBpLS0pIHtcbiAgICBjb25zdCBqID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogaSk7XG4gICAgY29uc3QgaCA9IHhzW2pdO1xuICAgIHhzW2pdID0geHNbaV07XG4gICAgeHNbaV0gPSBoO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { ILock, XpMutex, XpMutexPool } from './xpmutex';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A class that holds a pool of resources and gives them out and returns them on-demand
|
|
5
|
+
*
|
|
6
|
+
* The resources will be given out front to back, when they are returned
|
|
7
|
+
* the most recently returned version will be given out again (for best
|
|
8
|
+
* cache coherency).
|
|
9
|
+
*
|
|
10
|
+
* If there are multiple consumers waiting for a resource, consumers are serviced
|
|
11
|
+
* in FIFO order for most fairness.
|
|
12
|
+
*/
|
|
13
|
+
export class ResourcePool<A extends string=string> {
|
|
14
|
+
public static withResources<A extends string>(name: string, resources: A[]) {
|
|
15
|
+
const pool = XpMutexPool.fromName(name);
|
|
16
|
+
return new ResourcePool(pool, resources);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private readonly resources: ReadonlyArray<A>;
|
|
20
|
+
private readonly mutexes: Record<string, XpMutex> = {};
|
|
21
|
+
private readonly locks: Record<string, ILock | undefined> = {};
|
|
22
|
+
|
|
23
|
+
private constructor(private readonly pool: XpMutexPool, resources: A[]) {
|
|
24
|
+
if (resources.length === 0) {
|
|
25
|
+
throw new Error('Must have at least one resource in the pool');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Shuffle to reduce contention
|
|
29
|
+
resources = [...resources];
|
|
30
|
+
fisherYatesShuffle(resources);
|
|
31
|
+
this.resources = resources;
|
|
32
|
+
|
|
33
|
+
for (const res of resources) {
|
|
34
|
+
this.mutexes[res] = this.pool.mutex(res);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Take one value from the resource pool
|
|
40
|
+
*
|
|
41
|
+
* If no such value is currently available, wait until it is.
|
|
42
|
+
*/
|
|
43
|
+
public async take(): Promise<ILease<A>> {
|
|
44
|
+
while (true) {
|
|
45
|
+
// Start a wait on the unlock now -- if the unlock signal comes after
|
|
46
|
+
// we try to acquire but before we start the wait, we might miss it.
|
|
47
|
+
//
|
|
48
|
+
// (The timeout is in case the unlock signal doesn't come for whatever reason).
|
|
49
|
+
const wait = this.pool.awaitUnlock(10_000);
|
|
50
|
+
|
|
51
|
+
// Try all mutexes, we might need to reacquire an expired lock
|
|
52
|
+
for (const res of this.resources) {
|
|
53
|
+
const lease = await this.tryObtainLease(res);
|
|
54
|
+
if (lease) {
|
|
55
|
+
// Ignore the wait (count as handled)
|
|
56
|
+
wait.then(() => {}, () => {});
|
|
57
|
+
return lease;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// None available, wait until one gets unlocked then try again
|
|
62
|
+
await wait;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Execute a block using a single resource from the pool
|
|
68
|
+
*/
|
|
69
|
+
public async using<B>(block: (x: A) => B | Promise<B>): Promise<B> {
|
|
70
|
+
const lease = await this.take();
|
|
71
|
+
try {
|
|
72
|
+
return await block(lease.value);
|
|
73
|
+
} finally {
|
|
74
|
+
await lease.dispose();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private async tryObtainLease(value: A) {
|
|
79
|
+
const lock = await this.mutexes[value].tryAcquire();
|
|
80
|
+
if (!lock) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.locks[value] = lock;
|
|
85
|
+
return this.makeLease(value);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private makeLease(value: A): ILease<A> {
|
|
89
|
+
let disposed = false;
|
|
90
|
+
return {
|
|
91
|
+
value,
|
|
92
|
+
dispose: async () => {
|
|
93
|
+
if (disposed) {
|
|
94
|
+
throw new Error('Calling dispose() on an already-disposed lease.');
|
|
95
|
+
}
|
|
96
|
+
disposed = true;
|
|
97
|
+
return this.returnValue(value);
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* When a value is returned:
|
|
104
|
+
*
|
|
105
|
+
* - If someone's waiting for it, give it to them
|
|
106
|
+
* - Otherwise put it back into the pool
|
|
107
|
+
*/
|
|
108
|
+
private async returnValue(value: string) {
|
|
109
|
+
const lock = this.locks[value];
|
|
110
|
+
delete this.locks[value];
|
|
111
|
+
await lock?.release();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* A single value taken from the pool
|
|
117
|
+
*/
|
|
118
|
+
export interface ILease<A> {
|
|
119
|
+
/**
|
|
120
|
+
* The value obtained by the lease
|
|
121
|
+
*/
|
|
122
|
+
readonly value: A;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Return the leased value to the pool
|
|
126
|
+
*/
|
|
127
|
+
dispose(): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Shuffle an array in-place
|
|
132
|
+
*/
|
|
133
|
+
function fisherYatesShuffle<A>(xs: A[]) {
|
|
134
|
+
for (let i = xs.length - 1; i >= 1; i--) {
|
|
135
|
+
const j = Math.floor(Math.random() * i);
|
|
136
|
+
const h = xs[j];
|
|
137
|
+
xs[j] = xs[i];
|
|
138
|
+
xs[i] = h;
|
|
139
|
+
}
|
|
140
|
+
}
|
package/lib/resources.ts
ADDED
package/lib/shell.js
CHANGED
|
@@ -13,6 +13,7 @@ const path = require("path");
|
|
|
13
13
|
* Is platform-aware, handles errors nicely.
|
|
14
14
|
*/
|
|
15
15
|
async function shell(command, options = {}) {
|
|
16
|
+
var _a, _b;
|
|
16
17
|
if (options.modEnv && options.env) {
|
|
17
18
|
throw new Error('Use either env or modEnv but not both');
|
|
18
19
|
}
|
|
@@ -24,11 +25,11 @@ async function shell(command, options = {}) {
|
|
|
24
25
|
};
|
|
25
26
|
// Always output the command
|
|
26
27
|
writeToOutputs(`💻 ${command.join(' ')}\n`);
|
|
27
|
-
const show = options.show
|
|
28
|
+
const show = (_a = options.show) !== null && _a !== void 0 ? _a : 'always';
|
|
28
29
|
if (process.env.VERBOSE) {
|
|
29
30
|
outputs.add(process.stdout);
|
|
30
31
|
}
|
|
31
|
-
const env = options.env
|
|
32
|
+
const env = (_b = options.env) !== null && _b !== void 0 ? _b : (options.modEnv ? { ...process.env, ...options.modEnv } : process.env);
|
|
32
33
|
const child = child_process.spawn(command[0], command.slice(1), {
|
|
33
34
|
...options,
|
|
34
35
|
env,
|
|
@@ -46,10 +47,11 @@ async function shell(command, options = {}) {
|
|
|
46
47
|
stdout.push(chunk);
|
|
47
48
|
});
|
|
48
49
|
child.stderr.on('data', chunk => {
|
|
50
|
+
var _a;
|
|
49
51
|
if (show === 'always') {
|
|
50
52
|
writeToOutputs(chunk);
|
|
51
53
|
}
|
|
52
|
-
if (options.captureStderr
|
|
54
|
+
if ((_a = options.captureStderr) !== null && _a !== void 0 ? _a : true) {
|
|
53
55
|
stderr.push(chunk);
|
|
54
56
|
}
|
|
55
57
|
});
|
|
@@ -111,10 +113,11 @@ function rimraf(fsPath) {
|
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
function addToShellPath(x) {
|
|
114
|
-
|
|
116
|
+
var _a, _b;
|
|
117
|
+
const parts = (_b = (_a = process.env.PATH) === null || _a === void 0 ? void 0 : _a.split(':')) !== null && _b !== void 0 ? _b : [];
|
|
115
118
|
if (!parts.includes(x)) {
|
|
116
119
|
parts.unshift(x);
|
|
117
120
|
}
|
|
118
121
|
process.env.PATH = parts.join(':');
|
|
119
122
|
}
|
|
120
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFXQSxzQkFrRUM7QUFnRUQsd0JBZ0JDO0FBRUQsd0NBUUM7QUF2S0QsK0NBQStDO0FBQy9DLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFJN0I7Ozs7R0FJRztBQUNJLEtBQUssVUFBVSxLQUFLLENBQUMsT0FBaUIsRUFBRSxVQUF3QixFQUFFO0lBQ3ZFLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDbEMsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUNuQyxLQUFLLE1BQU0sWUFBWSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ25DLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLDRCQUE0QjtJQUM1QixjQUFjLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxJQUFJLFFBQVEsQ0FBQztJQUV0QyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDeEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLE9B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QUFDO0lBRWpELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2hpbGRfcHJvY2VzcyBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBUZXN0Q29udGV4dCB9IGZyb20gJy4vaW50ZWctdGVzdCc7XG5pbXBvcnQgeyBUZW1wb3JhcnlEaXJlY3RvcnlDb250ZXh0IH0gZnJvbSAnLi93aXRoLXRlbXBvcmFyeS1kaXJlY3RvcnknO1xuXG4vKipcbiAqIEEgc2hlbGwgY29tbWFuZCB0aGF0IGRvZXMgd2hhdCB5b3Ugd2FudFxuICpcbiAqIElzIHBsYXRmb3JtLWF3YXJlLCBoYW5kbGVzIGVycm9ycyBuaWNlbHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaGVsbChjb21tYW5kOiBzdHJpbmdbXSwgb3B0aW9uczogU2hlbGxPcHRpb25zID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAob3B0aW9ucy5tb2RFbnYgJiYgb3B0aW9ucy5lbnYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VzZSBlaXRoZXIgZW52IG9yIG1vZEVudiBidXQgbm90IGJvdGgnKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dHMgPSBuZXcgU2V0KG9wdGlvbnMub3V0cHV0cyk7XG4gIGNvbnN0IHdyaXRlVG9PdXRwdXRzID0gKHg6IHN0cmluZykgPT4ge1xuICAgIGZvciAoY29uc3Qgb3V0cHV0U3RyZWFtIG9mIG91dHB1dHMpIHtcbiAgICAgIG91dHB1dFN0cmVhbS53cml0ZSh4KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gQWx3YXlzIG91dHB1dCB0aGUgY29tbWFuZFxuICB3cml0ZVRvT3V0cHV0cyhg8J+SuyAke2NvbW1hbmQuam9pbignICcpfVxcbmApO1xuICBjb25zdCBzaG93ID0gb3B0aW9ucy5zaG93ID8/ICdhbHdheXMnO1xuXG4gIGlmIChwcm9jZXNzLmVudi5WRVJCT1NFKSB7XG4gICAgb3V0cHV0cy5hZGQocHJvY2Vzcy5zdGRvdXQpO1xuICB9XG5cbiAgY29uc3QgZW52ID0gb3B0aW9ucy5lbnYgPz8gKG9wdGlvbnMubW9kRW52ID8geyAuLi5wcm9jZXNzLmVudiwgLi4ub3B0aW9ucy5tb2RFbnYgfSA6IHByb2Nlc3MuZW52KTtcblxuICBjb25zdCBjaGlsZCA9IGNoaWxkX3Byb2Nlc3Muc3Bhd24oY29tbWFuZFswXSwgY29tbWFuZC5zbGljZSgxKSwge1xuICAgIC4uLm9wdGlvbnMsXG4gICAgZW52LFxuICAgIC8vIE5lZWQgdGhpcyBmb3IgV2luZG93cyB3aGVyZSB3ZSB3YW50IC5jbWQgYW5kIC5iYXQgdG8gYmUgZm91bmQgYXMgd2VsbC5cbiAgICBzaGVsbDogdHJ1ZSxcbiAgICBzdGRpbzogWydpZ25vcmUnLCAncGlwZScsICdwaXBlJ10sXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdGRvdXQgPSBuZXcgQXJyYXk8QnVmZmVyPigpO1xuICAgIGNvbnN0IHN0ZGVyciA9IG5ldyBBcnJheTxCdWZmZXI+KCk7XG5cbiAgICBjaGlsZC5zdGRvdXQhLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgaWYgKHNob3cgPT09ICdhbHdheXMnKSB7XG4gICAgICAgIHdyaXRlVG9PdXRwdXRzKGNodW5rKTtcbiAgICAgIH1cbiAgICAgIHN0ZG91dC5wdXNoKGNodW5rKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLnN0ZGVyciEub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBpZiAoc2hvdyA9PT0gJ2Fsd2F5cycpIHtcbiAgICAgICAgd3JpdGVUb091dHB1dHMoY2h1bmspO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuY2FwdHVyZVN0ZGVyciA/PyB0cnVlKSB7XG4gICAgICAgIHN0ZGVyci5wdXNoKGNodW5rKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Nsb3NlJywgY29kZSA9PiB7XG4gICAgICBjb25zdCBzdGRlcnJPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZGVycikudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBzdGRvdXRPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZG91dCkudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBvdXQgPSAob3B0aW9ucy5vbmx5U3RkZXJyID8gc3RkZXJyT3V0cHV0IDogc3Rkb3V0T3V0cHV0ICsgc3RkZXJyT3V0cHV0KS50cmltKCk7XG4gICAgICBpZiAoY29kZSA9PT0gMCB8fCBvcHRpb25zLmFsbG93RXJyRXhpdCkge1xuICAgICAgICByZXNvbHZlKG91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2hvdyA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgIHdyaXRlVG9PdXRwdXRzKGAke291dH1cXG5gKTtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGAnJHtjb21tYW5kLmpvaW4oJyAnKX0nIGV4aXRlZCB3aXRoIGVycm9yIGNvZGUgJHtjb2RlfS5gKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoZWxsT3B0aW9ucyBleHRlbmRzIGNoaWxkX3Byb2Nlc3MuU3Bhd25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgdG8gYWRkIHRvICdlbnYnXG4gICAqL1xuICByZWFkb25seSBtb2RFbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBEb24ndCBmYWlsIHdoZW4gZXhpdGluZyB3aXRoIGFuIGVycm9yXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhbGxvd0VyckV4aXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNhcHR1cmUgc3RkZXJyXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNhcHR1cmVTdGRlcnI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXNzIG91dHB1dCBoZXJlXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRzPzogTm9kZUpTLldyaXRhYmxlU3RyZWFtW107XG5cbiAgLyoqXG4gICAqIE9ubHkgcmV0dXJuIHN0ZGVyci4gRm9yIGV4YW1wbGUsIHRoaXMgaXMgdXNlZCB0byB2YWxpZGF0ZVxuICAgKiB0aGF0IHdoZW4gQ0k9dHJ1ZSwgYWxsIGxvZ3MgYXJlIHNlbnQgdG8gc3Rkb3V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgb25seVN0ZGVycj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERvbid0IGxvZyB0byBzdGRvdXRcbiAgICpcbiAgICogQGRlZmF1bHQgYWx3YXlzXG4gICAqL1xuICByZWFkb25seSBzaG93PzogJ2Fsd2F5cycgfCAnbmV2ZXInIHwgJ2Vycm9yJztcbn1cblxuZXhwb3J0IGNsYXNzIFNoZWxsSGVscGVyIHtcbiAgcHVibGljIHN0YXRpYyBmcm9tQ29udGV4dChjb250ZXh0OiBUZXN0Q29udGV4dCAmIFRlbXBvcmFyeURpcmVjdG9yeUNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFNoZWxsSGVscGVyKGNvbnRleHQuaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jd2Q6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkgeyB9XG5cbiAgcHVibGljIGFzeW5jIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdLCBvcHRpb25zOiBPbWl0PFNoZWxsT3B0aW9ucywgJ2N3ZCcgfCAnb3V0cHV0cyc+ID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBzaGVsbChjb21tYW5kLCB7XG4gICAgICBvdXRwdXRzOiBbdGhpcy5fb3V0cHV0XSxcbiAgICAgIGN3ZDogdGhpcy5fY3dkLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHJtIC1yZiByZWltcGxlbWVudGF0aW9uLCBkb24ndCB3YW50IHRvIGRlcGVuZCBvbiBhbiBOUE0gcGFja2FnZSBmb3IgdGhpc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmltcmFmKGZzUGF0aDogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgaXNEaXIgPSBmcy5sc3RhdFN5bmMoZnNQYXRoKS5pc0RpcmVjdG9yeSgpO1xuXG4gICAgaWYgKGlzRGlyKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZnMucmVhZGRpclN5bmMoZnNQYXRoKSkge1xuICAgICAgICByaW1yYWYocGF0aC5qb2luKGZzUGF0aCwgZmlsZSkpO1xuICAgICAgfVxuICAgICAgZnMucm1kaXJTeW5jKGZzUGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZzLnVubGlua1N5bmMoZnNQYXRoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIC8vIFdlIHdpbGwgc3Vydml2ZSBFTk9FTlRcbiAgICBpZiAoZS5jb2RlICE9PSAnRU5PRU5UJykgeyB0aHJvdyBlOyB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRvU2hlbGxQYXRoKHg6IHN0cmluZykge1xuICBjb25zdCBwYXJ0cyA9IHByb2Nlc3MuZW52LlBBVEg/LnNwbGl0KCc6JykgPz8gW107XG5cbiAgaWYgKCFwYXJ0cy5pbmNsdWRlcyh4KSkge1xuICAgIHBhcnRzLnVuc2hpZnQoeCk7XG4gIH1cblxuICBwcm9jZXNzLmVudi5QQVRIID0gcGFydHMuam9pbignOicpO1xufVxuIl19
|
|
123
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFXQSxzQkFrRUM7QUFnRUQsd0JBZ0JDO0FBRUQsd0NBUUM7QUF2S0QsK0NBQStDO0FBQy9DLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFJN0I7Ozs7R0FJRztBQUNJLEtBQUssVUFBVSxLQUFLLENBQUMsT0FBaUIsRUFBRSxVQUF3QixFQUFFOztJQUN2RSxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDbkMsS0FBSyxNQUFNLFlBQVksSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNuQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRiw0QkFBNEI7SUFDNUIsY0FBYyxDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsTUFBTSxJQUFJLEdBQUcsTUFBQSxPQUFPLENBQUMsSUFBSSxtQ0FBSSxRQUFRLENBQUM7SUFFdEMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFBLE9BQU8sQ0FBQyxHQUFHLG1DQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFH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LEtBQUssQ0FBQyxHQUFHLENBQUMsbUNBQUksRUFBRSxDQUFDO0lBRWpELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2hpbGRfcHJvY2VzcyBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBUZXN0Q29udGV4dCB9IGZyb20gJy4vaW50ZWctdGVzdCc7XG5pbXBvcnQgeyBUZW1wb3JhcnlEaXJlY3RvcnlDb250ZXh0IH0gZnJvbSAnLi93aXRoLXRlbXBvcmFyeS1kaXJlY3RvcnknO1xuXG4vKipcbiAqIEEgc2hlbGwgY29tbWFuZCB0aGF0IGRvZXMgd2hhdCB5b3Ugd2FudFxuICpcbiAqIElzIHBsYXRmb3JtLWF3YXJlLCBoYW5kbGVzIGVycm9ycyBuaWNlbHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaGVsbChjb21tYW5kOiBzdHJpbmdbXSwgb3B0aW9uczogU2hlbGxPcHRpb25zID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAob3B0aW9ucy5tb2RFbnYgJiYgb3B0aW9ucy5lbnYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VzZSBlaXRoZXIgZW52IG9yIG1vZEVudiBidXQgbm90IGJvdGgnKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dHMgPSBuZXcgU2V0KG9wdGlvbnMub3V0cHV0cyk7XG4gIGNvbnN0IHdyaXRlVG9PdXRwdXRzID0gKHg6IHN0cmluZykgPT4ge1xuICAgIGZvciAoY29uc3Qgb3V0cHV0U3RyZWFtIG9mIG91dHB1dHMpIHtcbiAgICAgIG91dHB1dFN0cmVhbS53cml0ZSh4KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gQWx3YXlzIG91dHB1dCB0aGUgY29tbWFuZFxuICB3cml0ZVRvT3V0cHV0cyhg8J+SuyAke2NvbW1hbmQuam9pbignICcpfVxcbmApO1xuICBjb25zdCBzaG93ID0gb3B0aW9ucy5zaG93ID8/ICdhbHdheXMnO1xuXG4gIGlmIChwcm9jZXNzLmVudi5WRVJCT1NFKSB7XG4gICAgb3V0cHV0cy5hZGQocHJvY2Vzcy5zdGRvdXQpO1xuICB9XG5cbiAgY29uc3QgZW52ID0gb3B0aW9ucy5lbnYgPz8gKG9wdGlvbnMubW9kRW52ID8geyAuLi5wcm9jZXNzLmVudiwgLi4ub3B0aW9ucy5tb2RFbnYgfSA6IHByb2Nlc3MuZW52KTtcblxuICBjb25zdCBjaGlsZCA9IGNoaWxkX3Byb2Nlc3Muc3Bhd24oY29tbWFuZFswXSwgY29tbWFuZC5zbGljZSgxKSwge1xuICAgIC4uLm9wdGlvbnMsXG4gICAgZW52LFxuICAgIC8vIE5lZWQgdGhpcyBmb3IgV2luZG93cyB3aGVyZSB3ZSB3YW50IC5jbWQgYW5kIC5iYXQgdG8gYmUgZm91bmQgYXMgd2VsbC5cbiAgICBzaGVsbDogdHJ1ZSxcbiAgICBzdGRpbzogWydpZ25vcmUnLCAncGlwZScsICdwaXBlJ10sXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdGRvdXQgPSBuZXcgQXJyYXk8QnVmZmVyPigpO1xuICAgIGNvbnN0IHN0ZGVyciA9IG5ldyBBcnJheTxCdWZmZXI+KCk7XG5cbiAgICBjaGlsZC5zdGRvdXQhLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgaWYgKHNob3cgPT09ICdhbHdheXMnKSB7XG4gICAgICAgIHdyaXRlVG9PdXRwdXRzKGNodW5rKTtcbiAgICAgIH1cbiAgICAgIHN0ZG91dC5wdXNoKGNodW5rKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLnN0ZGVyciEub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBpZiAoc2hvdyA9PT0gJ2Fsd2F5cycpIHtcbiAgICAgICAgd3JpdGVUb091dHB1dHMoY2h1bmspO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuY2FwdHVyZVN0ZGVyciA/PyB0cnVlKSB7XG4gICAgICAgIHN0ZGVyci5wdXNoKGNodW5rKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Nsb3NlJywgY29kZSA9PiB7XG4gICAgICBjb25zdCBzdGRlcnJPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZGVycikudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBzdGRvdXRPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZG91dCkudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBvdXQgPSAob3B0aW9ucy5vbmx5U3RkZXJyID8gc3RkZXJyT3V0cHV0IDogc3Rkb3V0T3V0cHV0ICsgc3RkZXJyT3V0cHV0KS50cmltKCk7XG4gICAgICBpZiAoY29kZSA9PT0gMCB8fCBvcHRpb25zLmFsbG93RXJyRXhpdCkge1xuICAgICAgICByZXNvbHZlKG91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2hvdyA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgIHdyaXRlVG9PdXRwdXRzKGAke291dH1cXG5gKTtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGAnJHtjb21tYW5kLmpvaW4oJyAnKX0nIGV4aXRlZCB3aXRoIGVycm9yIGNvZGUgJHtjb2RlfS5gKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoZWxsT3B0aW9ucyBleHRlbmRzIGNoaWxkX3Byb2Nlc3MuU3Bhd25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgdG8gYWRkIHRvICdlbnYnXG4gICAqL1xuICByZWFkb25seSBtb2RFbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBEb24ndCBmYWlsIHdoZW4gZXhpdGluZyB3aXRoIGFuIGVycm9yXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhbGxvd0VyckV4aXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNhcHR1cmUgc3RkZXJyXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNhcHR1cmVTdGRlcnI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXNzIG91dHB1dCBoZXJlXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRzPzogTm9kZUpTLldyaXRhYmxlU3RyZWFtW107XG5cbiAgLyoqXG4gICAqIE9ubHkgcmV0dXJuIHN0ZGVyci4gRm9yIGV4YW1wbGUsIHRoaXMgaXMgdXNlZCB0byB2YWxpZGF0ZVxuICAgKiB0aGF0IHdoZW4gQ0k9dHJ1ZSwgYWxsIGxvZ3MgYXJlIHNlbnQgdG8gc3Rkb3V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgb25seVN0ZGVycj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERvbid0IGxvZyB0byBzdGRvdXRcbiAgICpcbiAgICogQGRlZmF1bHQgYWx3YXlzXG4gICAqL1xuICByZWFkb25seSBzaG93PzogJ2Fsd2F5cycgfCAnbmV2ZXInIHwgJ2Vycm9yJztcbn1cblxuZXhwb3J0IGNsYXNzIFNoZWxsSGVscGVyIHtcbiAgcHVibGljIHN0YXRpYyBmcm9tQ29udGV4dChjb250ZXh0OiBUZXN0Q29udGV4dCAmIFRlbXBvcmFyeURpcmVjdG9yeUNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFNoZWxsSGVscGVyKGNvbnRleHQuaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jd2Q6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkgeyB9XG5cbiAgcHVibGljIGFzeW5jIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdLCBvcHRpb25zOiBPbWl0PFNoZWxsT3B0aW9ucywgJ2N3ZCcgfCAnb3V0cHV0cyc+ID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBzaGVsbChjb21tYW5kLCB7XG4gICAgICBvdXRwdXRzOiBbdGhpcy5fb3V0cHV0XSxcbiAgICAgIGN3ZDogdGhpcy5fY3dkLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHJtIC1yZiByZWltcGxlbWVudGF0aW9uLCBkb24ndCB3YW50IHRvIGRlcGVuZCBvbiBhbiBOUE0gcGFja2FnZSBmb3IgdGhpc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmltcmFmKGZzUGF0aDogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgaXNEaXIgPSBmcy5sc3RhdFN5bmMoZnNQYXRoKS5pc0RpcmVjdG9yeSgpO1xuXG4gICAgaWYgKGlzRGlyKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZnMucmVhZGRpclN5bmMoZnNQYXRoKSkge1xuICAgICAgICByaW1yYWYocGF0aC5qb2luKGZzUGF0aCwgZmlsZSkpO1xuICAgICAgfVxuICAgICAgZnMucm1kaXJTeW5jKGZzUGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZzLnVubGlua1N5bmMoZnNQYXRoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIC8vIFdlIHdpbGwgc3Vydml2ZSBFTk9FTlRcbiAgICBpZiAoZS5jb2RlICE9PSAnRU5PRU5UJykgeyB0aHJvdyBlOyB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRvU2hlbGxQYXRoKHg6IHN0cmluZykge1xuICBjb25zdCBwYXJ0cyA9IHByb2Nlc3MuZW52LlBBVEg/LnNwbGl0KCc6JykgPz8gW107XG5cbiAgaWYgKCFwYXJ0cy5pbmNsdWRlcyh4KSkge1xuICAgIHBhcnRzLnVuc2hpZnQoeCk7XG4gIH1cblxuICBwcm9jZXNzLmVudi5QQVRIID0gcGFydHMuam9pbignOicpO1xufVxuIl19
|
package/lib/shell.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as child_process from 'child_process';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { TestContext } from './integ-test';
|
|
5
|
+
import { TemporaryDirectoryContext } from './with-temporary-directory';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A shell command that does what you want
|
|
9
|
+
*
|
|
10
|
+
* Is platform-aware, handles errors nicely.
|
|
11
|
+
*/
|
|
12
|
+
export async function shell(command: string[], options: ShellOptions = {}): Promise<string> {
|
|
13
|
+
if (options.modEnv && options.env) {
|
|
14
|
+
throw new Error('Use either env or modEnv but not both');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const outputs = new Set(options.outputs);
|
|
18
|
+
const writeToOutputs = (x: string) => {
|
|
19
|
+
for (const outputStream of outputs) {
|
|
20
|
+
outputStream.write(x);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Always output the command
|
|
25
|
+
writeToOutputs(`💻 ${command.join(' ')}\n`);
|
|
26
|
+
const show = options.show ?? 'always';
|
|
27
|
+
|
|
28
|
+
if (process.env.VERBOSE) {
|
|
29
|
+
outputs.add(process.stdout);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const env = options.env ?? (options.modEnv ? { ...process.env, ...options.modEnv } : process.env);
|
|
33
|
+
|
|
34
|
+
const child = child_process.spawn(command[0], command.slice(1), {
|
|
35
|
+
...options,
|
|
36
|
+
env,
|
|
37
|
+
// Need this for Windows where we want .cmd and .bat to be found as well.
|
|
38
|
+
shell: true,
|
|
39
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return new Promise<string>((resolve, reject) => {
|
|
43
|
+
const stdout = new Array<Buffer>();
|
|
44
|
+
const stderr = new Array<Buffer>();
|
|
45
|
+
|
|
46
|
+
child.stdout!.on('data', chunk => {
|
|
47
|
+
if (show === 'always') {
|
|
48
|
+
writeToOutputs(chunk);
|
|
49
|
+
}
|
|
50
|
+
stdout.push(chunk);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
child.stderr!.on('data', chunk => {
|
|
54
|
+
if (show === 'always') {
|
|
55
|
+
writeToOutputs(chunk);
|
|
56
|
+
}
|
|
57
|
+
if (options.captureStderr ?? true) {
|
|
58
|
+
stderr.push(chunk);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
child.once('error', reject);
|
|
63
|
+
|
|
64
|
+
child.once('close', code => {
|
|
65
|
+
const stderrOutput = Buffer.concat(stderr).toString('utf-8');
|
|
66
|
+
const stdoutOutput = Buffer.concat(stdout).toString('utf-8');
|
|
67
|
+
const out = (options.onlyStderr ? stderrOutput : stdoutOutput + stderrOutput).trim();
|
|
68
|
+
if (code === 0 || options.allowErrExit) {
|
|
69
|
+
resolve(out);
|
|
70
|
+
} else {
|
|
71
|
+
if (show === 'error') {
|
|
72
|
+
writeToOutputs(`${out}\n`);
|
|
73
|
+
}
|
|
74
|
+
reject(new Error(`'${command.join(' ')}' exited with error code ${code}.`));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface ShellOptions extends child_process.SpawnOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Properties to add to 'env'
|
|
83
|
+
*/
|
|
84
|
+
readonly modEnv?: Record<string, string>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Don't fail when exiting with an error
|
|
88
|
+
*
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
readonly allowErrExit?: boolean;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Whether to capture stderr
|
|
95
|
+
*
|
|
96
|
+
* @default true
|
|
97
|
+
*/
|
|
98
|
+
readonly captureStderr?: boolean;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Pass output here
|
|
102
|
+
*/
|
|
103
|
+
readonly outputs?: NodeJS.WritableStream[];
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Only return stderr. For example, this is used to validate
|
|
107
|
+
* that when CI=true, all logs are sent to stdout.
|
|
108
|
+
*
|
|
109
|
+
* @default false
|
|
110
|
+
*/
|
|
111
|
+
readonly onlyStderr?: boolean;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Don't log to stdout
|
|
115
|
+
*
|
|
116
|
+
* @default always
|
|
117
|
+
*/
|
|
118
|
+
readonly show?: 'always' | 'never' | 'error';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class ShellHelper {
|
|
122
|
+
public static fromContext(context: TestContext & TemporaryDirectoryContext) {
|
|
123
|
+
return new ShellHelper(context.integTestDir, context.output);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
constructor(
|
|
127
|
+
private readonly _cwd: string,
|
|
128
|
+
private readonly _output: NodeJS.WritableStream) { }
|
|
129
|
+
|
|
130
|
+
public async shell(command: string[], options: Omit<ShellOptions, 'cwd' | 'outputs'> = {}): Promise<string> {
|
|
131
|
+
return shell(command, {
|
|
132
|
+
outputs: [this._output],
|
|
133
|
+
cwd: this._cwd,
|
|
134
|
+
...options,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* rm -rf reimplementation, don't want to depend on an NPM package for this
|
|
141
|
+
*/
|
|
142
|
+
export function rimraf(fsPath: string) {
|
|
143
|
+
try {
|
|
144
|
+
const isDir = fs.lstatSync(fsPath).isDirectory();
|
|
145
|
+
|
|
146
|
+
if (isDir) {
|
|
147
|
+
for (const file of fs.readdirSync(fsPath)) {
|
|
148
|
+
rimraf(path.join(fsPath, file));
|
|
149
|
+
}
|
|
150
|
+
fs.rmdirSync(fsPath);
|
|
151
|
+
} else {
|
|
152
|
+
fs.unlinkSync(fsPath);
|
|
153
|
+
}
|
|
154
|
+
} catch (e: any) {
|
|
155
|
+
// We will survive ENOENT
|
|
156
|
+
if (e.code !== 'ENOENT') { throw e; }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function addToShellPath(x: string) {
|
|
161
|
+
const parts = process.env.PATH?.split(':') ?? [];
|
|
162
|
+
|
|
163
|
+
if (!parts.includes(x)) {
|
|
164
|
+
parts.unshift(x);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
process.env.PATH = parts.join(':');
|
|
168
|
+
}
|