@aws-cdk-testing/cli-integ 0.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.
- package/.eslintrc.js +9 -0
- package/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +205 -0
- package/bin/apply-patches +22 -0
- package/bin/download-and-run-old-tests +52 -0
- package/bin/query-github +2 -0
- package/bin/query-github.d.ts +1 -0
- package/bin/query-github.js +54 -0
- package/bin/query-github.ts +56 -0
- package/bin/run-suite +2 -0
- package/bin/run-suite.d.ts +1 -0
- package/bin/run-suite.js +131 -0
- package/bin/run-suite.ts +140 -0
- package/bin/stage-distribution +2 -0
- package/bin/stage-distribution.d.ts +1 -0
- package/bin/stage-distribution.js +217 -0
- package/bin/stage-distribution.ts +267 -0
- package/bin/test-root +2 -0
- package/bin/test-root.d.ts +1 -0
- package/bin/test-root.js +6 -0
- package/bin/test-root.ts +3 -0
- package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
- package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
- package/entrypoints/test-cli-regression.bash +83 -0
- package/entrypoints/test.sh +12 -0
- package/lib/aws.d.ts +51 -0
- package/lib/aws.js +206 -0
- package/lib/aws.ts +263 -0
- package/lib/corking.d.ts +12 -0
- package/lib/corking.js +35 -0
- package/lib/corking.ts +33 -0
- package/lib/eventually.d.ts +20 -0
- package/lib/eventually.js +34 -0
- package/lib/eventually.ts +42 -0
- package/lib/files.d.ts +15 -0
- package/lib/files.js +80 -0
- package/lib/files.ts +80 -0
- package/lib/github.d.ts +4 -0
- package/lib/github.js +43 -0
- package/lib/github.ts +43 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +30 -0
- package/lib/index.ts +13 -0
- package/lib/integ-test.d.ts +10 -0
- package/lib/integ-test.js +70 -0
- package/lib/integ-test.ts +81 -0
- package/lib/lists.d.ts +1 -0
- package/lib/lists.js +11 -0
- package/lib/lists.ts +9 -0
- package/lib/memoize.d.ts +6 -0
- package/lib/memoize.js +18 -0
- package/lib/memoize.ts +14 -0
- package/lib/npm.d.ts +8 -0
- package/lib/npm.js +38 -0
- package/lib/npm.ts +41 -0
- package/lib/package-sources/release-source.d.ts +23 -0
- package/lib/package-sources/release-source.js +71 -0
- package/lib/package-sources/release-source.ts +81 -0
- package/lib/package-sources/repo-source.d.ts +30 -0
- package/lib/package-sources/repo-source.js +97 -0
- package/lib/package-sources/repo-source.ts +111 -0
- package/lib/package-sources/repo-tools/npm +2 -0
- package/lib/package-sources/repo-tools/npm.d.ts +1 -0
- package/lib/package-sources/repo-tools/npm.js +43 -0
- package/lib/package-sources/repo-tools/npm.ts +48 -0
- package/lib/package-sources/source.d.ts +28 -0
- package/lib/package-sources/source.js +3 -0
- package/lib/package-sources/source.ts +35 -0
- package/lib/package-sources/subprocess.d.ts +3 -0
- package/lib/package-sources/subprocess.js +17 -0
- package/lib/package-sources/subprocess.ts +15 -0
- package/lib/resource-pool.d.ts +50 -0
- package/lib/resource-pool.js +117 -0
- package/lib/resource-pool.ts +140 -0
- package/lib/resources.d.ts +1 -0
- package/lib/resources.js +6 -0
- package/lib/resources.ts +4 -0
- package/lib/shell.d.ts +56 -0
- package/lib/shell.js +123 -0
- package/lib/shell.ts +168 -0
- package/lib/staging/codeartifact.d.ts +44 -0
- package/lib/staging/codeartifact.js +281 -0
- package/lib/staging/codeartifact.ts +387 -0
- package/lib/staging/maven.d.ts +5 -0
- package/lib/staging/maven.js +91 -0
- package/lib/staging/maven.ts +95 -0
- package/lib/staging/npm.d.ts +4 -0
- package/lib/staging/npm.js +55 -0
- package/lib/staging/npm.ts +62 -0
- package/lib/staging/nuget.d.ts +4 -0
- package/lib/staging/nuget.js +69 -0
- package/lib/staging/nuget.ts +75 -0
- package/lib/staging/parallel-shell.d.ts +5 -0
- package/lib/staging/parallel-shell.js +45 -0
- package/lib/staging/parallel-shell.ts +51 -0
- package/lib/staging/pypi.d.ts +4 -0
- package/lib/staging/pypi.js +48 -0
- package/lib/staging/pypi.ts +50 -0
- package/lib/staging/usage-dir.d.ts +31 -0
- package/lib/staging/usage-dir.js +87 -0
- package/lib/staging/usage-dir.ts +99 -0
- package/lib/with-aws.d.ts +14 -0
- package/lib/with-aws.js +60 -0
- package/lib/with-aws.ts +67 -0
- package/lib/with-cdk-app.d.ts +210 -0
- package/lib/with-cdk-app.js +539 -0
- package/lib/with-cdk-app.ts +742 -0
- package/lib/with-cli-lib.d.ts +17 -0
- package/lib/with-cli-lib.js +123 -0
- package/lib/with-cli-lib.ts +134 -0
- package/lib/with-packages.d.ts +5 -0
- package/lib/with-packages.js +13 -0
- package/lib/with-packages.ts +15 -0
- package/lib/with-sam.d.ts +33 -0
- package/lib/with-sam.js +258 -0
- package/lib/with-sam.ts +288 -0
- package/lib/with-temporary-directory.d.ts +5 -0
- package/lib/with-temporary-directory.js +31 -0
- package/lib/with-temporary-directory.ts +35 -0
- package/lib/with-timeout.d.ts +19 -0
- package/lib/with-timeout.js +34 -0
- package/lib/with-timeout.ts +33 -0
- package/lib/xpmutex.d.ts +43 -0
- package/lib/xpmutex.js +207 -0
- package/lib/xpmutex.ts +218 -0
- package/package.json +111 -0
- package/resources/bootstrap-templates/session-tags.all-roles-deny-all.yaml +703 -0
- package/resources/bootstrap-templates/session-tags.deploy-role-deny-sqs.yaml +700 -0
- package/resources/cdk-apps/app/app.js +926 -0
- package/resources/cdk-apps/app/appsync.hotswap.graphql +3 -0
- package/resources/cdk-apps/app/cdk.json +7 -0
- package/resources/cdk-apps/app/docker/Dockerfile +2 -0
- package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
- package/resources/cdk-apps/app/lambda/index.js +4 -0
- package/resources/cdk-apps/app/lambda/response.json +3 -0
- package/resources/cdk-apps/app/nested-stack.js +65 -0
- package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
- package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
- package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
- package/resources/cdk-apps/rollback-test-app/app.js +110 -0
- package/resources/cdk-apps/rollback-test-app/cdk.json +7 -0
- package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
- package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
- package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
- package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
- package/resources/cdk-apps/simple-app/app.js +26 -0
- package/resources/cdk-apps/simple-app/cdk.json +7 -0
- package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
- package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
- package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
- package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
- package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
- package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
- package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
- package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
- package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
- package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
- package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
- package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
- package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
- package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
- package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
- package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
- package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
- package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
- package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
- package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
- package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
- package/resources/cli-regression-patches/v2.130.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.130.0/node_modules/@aws-cdk-testing/cli-integ/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
- package/resources/cli-regression-patches/v2.130.0/node_modules/@aws-cdk-testing/cli-integ/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
- package/resources/cli-regression-patches/v2.130.0/skip-tests.txt +5 -0
- package/resources/cli-regression-patches/v2.132.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.132.0/skip-tests.txt +4 -0
- package/resources/cli-regression-patches/v2.142.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.142.0/skip-tests.txt +4 -0
- package/resources/cli-regression-patches/v2.160.0/skip-tests.txt +2 -0
- package/resources/cli-regression-patches/v2.161.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.161.0/skip-tests.txt +5 -0
- package/resources/cli-regression-patches/v2.166.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.166.0/skip-tests.txt +2 -0
- package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
- package/resources/cloud-assemblies/0.36.0/cdk.out +1 -0
- package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
- package/resources/integ.jest.config.js +25 -0
- package/resources/templates/sqs-template.json +36 -0
- package/skip-tests.txt +8 -0
- package/tests/cli-integ-tests/README.md +47 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.js +412 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.ts +493 -0
- package/tests/cli-integ-tests/cli-lib.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/cli-lib.integtest.js +62 -0
- package/tests/cli-integ-tests/cli-lib.integtest.ts +90 -0
- package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/cli.integtest.js +2104 -0
- package/tests/cli-integ-tests/cli.integtest.ts +2874 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.js +314 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.ts +392 -0
- package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
- package/tests/init-csharp/init-csharp.integtest.js +14 -0
- package/tests/init-csharp/init-csharp.integtest.ts +15 -0
- package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
- package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
- package/tests/init-fsharp/init-fsharp.integtest.ts +15 -0
- package/tests/init-go/init-go.integtest.d.ts +1 -0
- package/tests/init-go/init-go.integtest.js +21 -0
- package/tests/init-go/init-go.integtest.ts +23 -0
- package/tests/init-java/init-java.integtest.d.ts +1 -0
- package/tests/init-java/init-java.integtest.js +14 -0
- package/tests/init-java/init-java.integtest.ts +14 -0
- package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
- package/tests/init-javascript/init-javascript.integtest.js +53 -0
- package/tests/init-javascript/init-javascript.integtest.ts +59 -0
- package/tests/init-python/init-python.integtest.d.ts +1 -0
- package/tests/init-python/init-python.integtest.js +19 -0
- package/tests/init-python/init-python.integtest.ts +20 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.js +54 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.ts +66 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.ts +13 -0
- package/tests/tool-integrations/amplify.integtest.d.ts +1 -0
- package/tests/tool-integrations/amplify.integtest.js +39 -0
- package/tests/tool-integrations/amplify.integtest.ts +43 -0
- package/tests/tool-integrations/with-tool-context.d.ts +9 -0
- package/tests/tool-integrations/with-tool-context.js +13 -0
- package/tests/tool-integrations/with-tool-context.ts +14 -0
- package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
- package/tests/uberpackage/uberpackage.integtest.js +11 -0
- package/tests/uberpackage/uberpackage.integtest.ts +11 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface IPackageSourceSetup {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly description: string;
|
|
4
|
+
prepare(): Promise<void>;
|
|
5
|
+
cleanup(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface IPackageSource {
|
|
8
|
+
makeCliAvailable(): Promise<void>;
|
|
9
|
+
assertJsiiPackagesAvailable(): void;
|
|
10
|
+
majorVersion(): string;
|
|
11
|
+
initializeDotnetPackages(targetDir: string): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* CLI version
|
|
14
|
+
*/
|
|
15
|
+
requestedCliVersion(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Framework version if it's different than the CLI version
|
|
18
|
+
*
|
|
19
|
+
* Not all tests will respect this.
|
|
20
|
+
*/
|
|
21
|
+
requestedFrameworkVersion(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Versions of alpha packages if different than the CLI version
|
|
24
|
+
*
|
|
25
|
+
* Not all tests will respect this.
|
|
26
|
+
*/
|
|
27
|
+
requestedAlphaVersion(): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgaW50ZXJmYWNlIElQYWNrYWdlU291cmNlU2V0dXAge1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uOiBzdHJpbmc7XG5cbiAgcHJlcGFyZSgpOiBQcm9taXNlPHZvaWQ+O1xuICBjbGVhbnVwKCk6IFByb21pc2U8dm9pZD47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVBhY2thZ2VTb3VyY2Uge1xuICBtYWtlQ2xpQXZhaWxhYmxlKCk6IFByb21pc2U8dm9pZD47XG5cbiAgYXNzZXJ0SnNpaVBhY2thZ2VzQXZhaWxhYmxlKCk6IHZvaWQ7XG4gIG1ham9yVmVyc2lvbigpOiBzdHJpbmc7XG5cbiAgaW5pdGlhbGl6ZURvdG5ldFBhY2thZ2VzKHRhcmdldERpcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcblxuICAvKipcbiAgICogQ0xJIHZlcnNpb25cbiAgICovXG4gIHJlcXVlc3RlZENsaVZlcnNpb24oKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGcmFtZXdvcmsgdmVyc2lvbiBpZiBpdCdzIGRpZmZlcmVudCB0aGFuIHRoZSBDTEkgdmVyc2lvblxuICAgKlxuICAgKiBOb3QgYWxsIHRlc3RzIHdpbGwgcmVzcGVjdCB0aGlzLlxuICAgKi9cbiAgcmVxdWVzdGVkRnJhbWV3b3JrVmVyc2lvbigpOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFZlcnNpb25zIG9mIGFscGhhIHBhY2thZ2VzIGlmIGRpZmZlcmVudCB0aGFuIHRoZSBDTEkgdmVyc2lvblxuICAgKlxuICAgKiBOb3QgYWxsIHRlc3RzIHdpbGwgcmVzcGVjdCB0aGlzLlxuICAgKi9cbiAgcmVxdWVzdGVkQWxwaGFWZXJzaW9uKCk6IHN0cmluZztcbn1cbiJdfQ==
|
|
@@ -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,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeForSubprocess = serializeForSubprocess;
|
|
4
|
+
exports.packageSourceInSubprocess = packageSourceInSubprocess;
|
|
5
|
+
const release_source_1 = require("./release-source");
|
|
6
|
+
const repo_source_1 = require("./repo-source");
|
|
7
|
+
function serializeForSubprocess(s) {
|
|
8
|
+
process.env.PACKAGE_SOURCE = s.name;
|
|
9
|
+
}
|
|
10
|
+
function packageSourceInSubprocess() {
|
|
11
|
+
switch (process.env.PACKAGE_SOURCE) {
|
|
12
|
+
case 'repo': return new repo_source_1.RepoPackageSource();
|
|
13
|
+
case 'release': return new release_source_1.ReleasePackageSource();
|
|
14
|
+
default: throw new Error(`Unrecognized package source: ${process.env.PACKAGE_SOURCE}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VicHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInN1YnByb2Nlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFJQSx3REFFQztBQUVELDhEQU1DO0FBZEQscURBQXdEO0FBQ3hELCtDQUFrRDtBQUdsRCxTQUFnQixzQkFBc0IsQ0FBQyxDQUFzQjtJQUMzRCxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFnQix5QkFBeUI7SUFDdkMsUUFBUSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ25DLEtBQUssTUFBTSxDQUFDLENBQUMsT0FBTyxJQUFJLCtCQUFpQixFQUFFLENBQUM7UUFDNUMsS0FBSyxTQUFTLENBQUMsQ0FBQyxPQUFPLElBQUkscUNBQW9CLEVBQUUsQ0FBQztRQUNsRCxPQUFPLENBQUMsQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7SUFDekYsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZWxlYXNlUGFja2FnZVNvdXJjZSB9IGZyb20gJy4vcmVsZWFzZS1zb3VyY2UnO1xuaW1wb3J0IHsgUmVwb1BhY2thZ2VTb3VyY2UgfSBmcm9tICcuL3JlcG8tc291cmNlJztcbmltcG9ydCB7IElQYWNrYWdlU291cmNlU2V0dXAsIElQYWNrYWdlU291cmNlIH0gZnJvbSAnLi9zb3VyY2UnO1xuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplRm9yU3VicHJvY2VzcyhzOiBJUGFja2FnZVNvdXJjZVNldHVwKSB7XG4gIHByb2Nlc3MuZW52LlBBQ0tBR0VfU09VUkNFID0gcy5uYW1lO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFja2FnZVNvdXJjZUluU3VicHJvY2VzcygpOiBJUGFja2FnZVNvdXJjZSB7XG4gIHN3aXRjaCAocHJvY2Vzcy5lbnYuUEFDS0FHRV9TT1VSQ0UpIHtcbiAgICBjYXNlICdyZXBvJzogcmV0dXJuIG5ldyBSZXBvUGFja2FnZVNvdXJjZSgpO1xuICAgIGNhc2UgJ3JlbGVhc2UnOiByZXR1cm4gbmV3IFJlbGVhc2VQYWNrYWdlU291cmNlKCk7XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgcGFja2FnZSBzb3VyY2U6ICR7cHJvY2Vzcy5lbnYuUEFDS0FHRV9TT1VSQ0V9YCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A class that holds a pool of resources and gives them out and returns them on-demand
|
|
3
|
+
*
|
|
4
|
+
* The resources will be given out front to back, when they are returned
|
|
5
|
+
* the most recently returned version will be given out again (for best
|
|
6
|
+
* cache coherency).
|
|
7
|
+
*
|
|
8
|
+
* If there are multiple consumers waiting for a resource, consumers are serviced
|
|
9
|
+
* in FIFO order for most fairness.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ResourcePool<A extends string = string> {
|
|
12
|
+
private readonly pool;
|
|
13
|
+
static withResources<A extends string>(name: string, resources: A[]): ResourcePool<A>;
|
|
14
|
+
private readonly resources;
|
|
15
|
+
private readonly mutexes;
|
|
16
|
+
private readonly locks;
|
|
17
|
+
private constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Take one value from the resource pool
|
|
20
|
+
*
|
|
21
|
+
* If no such value is currently available, wait until it is.
|
|
22
|
+
*/
|
|
23
|
+
take(): Promise<ILease<A>>;
|
|
24
|
+
/**
|
|
25
|
+
* Execute a block using a single resource from the pool
|
|
26
|
+
*/
|
|
27
|
+
using<B>(block: (x: A) => B | Promise<B>): Promise<B>;
|
|
28
|
+
private tryObtainLease;
|
|
29
|
+
private makeLease;
|
|
30
|
+
/**
|
|
31
|
+
* When a value is returned:
|
|
32
|
+
*
|
|
33
|
+
* - If someone's waiting for it, give it to them
|
|
34
|
+
* - Otherwise put it back into the pool
|
|
35
|
+
*/
|
|
36
|
+
private returnValue;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A single value taken from the pool
|
|
40
|
+
*/
|
|
41
|
+
export interface ILease<A> {
|
|
42
|
+
/**
|
|
43
|
+
* The value obtained by the lease
|
|
44
|
+
*/
|
|
45
|
+
readonly value: A;
|
|
46
|
+
/**
|
|
47
|
+
* Return the leased value to the pool
|
|
48
|
+
*/
|
|
49
|
+
dispose(): Promise<void>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResourcePool = void 0;
|
|
4
|
+
const xpmutex_1 = require("./xpmutex");
|
|
5
|
+
/**
|
|
6
|
+
* A class that holds a pool of resources and gives them out and returns them on-demand
|
|
7
|
+
*
|
|
8
|
+
* The resources will be given out front to back, when they are returned
|
|
9
|
+
* the most recently returned version will be given out again (for best
|
|
10
|
+
* cache coherency).
|
|
11
|
+
*
|
|
12
|
+
* If there are multiple consumers waiting for a resource, consumers are serviced
|
|
13
|
+
* in FIFO order for most fairness.
|
|
14
|
+
*/
|
|
15
|
+
class ResourcePool {
|
|
16
|
+
static withResources(name, resources) {
|
|
17
|
+
const pool = xpmutex_1.XpMutexPool.fromName(name);
|
|
18
|
+
return new ResourcePool(pool, resources);
|
|
19
|
+
}
|
|
20
|
+
constructor(pool, resources) {
|
|
21
|
+
this.pool = pool;
|
|
22
|
+
this.mutexes = {};
|
|
23
|
+
this.locks = {};
|
|
24
|
+
if (resources.length === 0) {
|
|
25
|
+
throw new Error('Must have at least one resource in the pool');
|
|
26
|
+
}
|
|
27
|
+
// Shuffle to reduce contention
|
|
28
|
+
resources = [...resources];
|
|
29
|
+
fisherYatesShuffle(resources);
|
|
30
|
+
this.resources = resources;
|
|
31
|
+
for (const res of resources) {
|
|
32
|
+
this.mutexes[res] = this.pool.mutex(res);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Take one value from the resource pool
|
|
37
|
+
*
|
|
38
|
+
* If no such value is currently available, wait until it is.
|
|
39
|
+
*/
|
|
40
|
+
async take() {
|
|
41
|
+
while (true) {
|
|
42
|
+
// Start a wait on the unlock now -- if the unlock signal comes after
|
|
43
|
+
// we try to acquire but before we start the wait, we might miss it.
|
|
44
|
+
//
|
|
45
|
+
// (The timeout is in case the unlock signal doesn't come for whatever reason).
|
|
46
|
+
const wait = this.pool.awaitUnlock(10000);
|
|
47
|
+
// Try all mutexes, we might need to reacquire an expired lock
|
|
48
|
+
for (const res of this.resources) {
|
|
49
|
+
const lease = await this.tryObtainLease(res);
|
|
50
|
+
if (lease) {
|
|
51
|
+
// Ignore the wait (count as handled)
|
|
52
|
+
wait.then(() => { }, () => { });
|
|
53
|
+
return lease;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// None available, wait until one gets unlocked then try again
|
|
57
|
+
await wait;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Execute a block using a single resource from the pool
|
|
62
|
+
*/
|
|
63
|
+
async using(block) {
|
|
64
|
+
const lease = await this.take();
|
|
65
|
+
try {
|
|
66
|
+
return await block(lease.value);
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
await lease.dispose();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async tryObtainLease(value) {
|
|
73
|
+
const lock = await this.mutexes[value].tryAcquire();
|
|
74
|
+
if (!lock) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
this.locks[value] = lock;
|
|
78
|
+
return this.makeLease(value);
|
|
79
|
+
}
|
|
80
|
+
makeLease(value) {
|
|
81
|
+
let disposed = false;
|
|
82
|
+
return {
|
|
83
|
+
value,
|
|
84
|
+
dispose: async () => {
|
|
85
|
+
if (disposed) {
|
|
86
|
+
throw new Error('Calling dispose() on an already-disposed lease.');
|
|
87
|
+
}
|
|
88
|
+
disposed = true;
|
|
89
|
+
return this.returnValue(value);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* When a value is returned:
|
|
95
|
+
*
|
|
96
|
+
* - If someone's waiting for it, give it to them
|
|
97
|
+
* - Otherwise put it back into the pool
|
|
98
|
+
*/
|
|
99
|
+
async returnValue(value) {
|
|
100
|
+
const lock = this.locks[value];
|
|
101
|
+
delete this.locks[value];
|
|
102
|
+
await (lock === null || lock === void 0 ? void 0 : lock.release());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.ResourcePool = ResourcePool;
|
|
106
|
+
/**
|
|
107
|
+
* Shuffle an array in-place
|
|
108
|
+
*/
|
|
109
|
+
function fisherYatesShuffle(xs) {
|
|
110
|
+
for (let i = xs.length - 1; i >= 1; i--) {
|
|
111
|
+
const j = Math.floor(Math.random() * i);
|
|
112
|
+
const h = xs[j];
|
|
113
|
+
xs[j] = xs[i];
|
|
114
|
+
xs[i] = h;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const RESOURCES_DIR: string;
|
package/lib/resources.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESOURCES_DIR = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
exports.RESOURCES_DIR = path.resolve(__dirname, '..', 'resources');
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVzb3VyY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE2QjtBQUVoQixRQUFBLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG5leHBvcnQgY29uc3QgUkVTT1VSQ0VTX0RJUiA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLicsICdyZXNvdXJjZXMnKTtcblxuIl19
|
package/lib/resources.ts
ADDED
package/lib/shell.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as child_process from 'child_process';
|
|
2
|
+
import { TestContext } from './integ-test';
|
|
3
|
+
import { TemporaryDirectoryContext } from './with-temporary-directory';
|
|
4
|
+
/**
|
|
5
|
+
* A shell command that does what you want
|
|
6
|
+
*
|
|
7
|
+
* Is platform-aware, handles errors nicely.
|
|
8
|
+
*/
|
|
9
|
+
export declare function shell(command: string[], options?: ShellOptions): Promise<string>;
|
|
10
|
+
export interface ShellOptions extends child_process.SpawnOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Properties to add to 'env'
|
|
13
|
+
*/
|
|
14
|
+
readonly modEnv?: Record<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* Don't fail when exiting with an error
|
|
17
|
+
*
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
readonly allowErrExit?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether to capture stderr
|
|
23
|
+
*
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
readonly captureStderr?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Pass output here
|
|
29
|
+
*/
|
|
30
|
+
readonly outputs?: NodeJS.WritableStream[];
|
|
31
|
+
/**
|
|
32
|
+
* Only return stderr. For example, this is used to validate
|
|
33
|
+
* that when CI=true, all logs are sent to stdout.
|
|
34
|
+
*
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
readonly onlyStderr?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Don't log to stdout
|
|
40
|
+
*
|
|
41
|
+
* @default always
|
|
42
|
+
*/
|
|
43
|
+
readonly show?: 'always' | 'never' | 'error';
|
|
44
|
+
}
|
|
45
|
+
export declare class ShellHelper {
|
|
46
|
+
private readonly _cwd;
|
|
47
|
+
private readonly _output;
|
|
48
|
+
static fromContext(context: TestContext & TemporaryDirectoryContext): ShellHelper;
|
|
49
|
+
constructor(_cwd: string, _output: NodeJS.WritableStream);
|
|
50
|
+
shell(command: string[], options?: Omit<ShellOptions, 'cwd' | 'outputs'>): Promise<string>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* rm -rf reimplementation, don't want to depend on an NPM package for this
|
|
54
|
+
*/
|
|
55
|
+
export declare function rimraf(fsPath: string): void;
|
|
56
|
+
export declare function addToShellPath(x: string): void;
|
package/lib/shell.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ShellHelper = void 0;
|
|
4
|
+
exports.shell = shell;
|
|
5
|
+
exports.rimraf = rimraf;
|
|
6
|
+
exports.addToShellPath = addToShellPath;
|
|
7
|
+
const child_process = require("child_process");
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
/**
|
|
11
|
+
* A shell command that does what you want
|
|
12
|
+
*
|
|
13
|
+
* Is platform-aware, handles errors nicely.
|
|
14
|
+
*/
|
|
15
|
+
async function shell(command, options = {}) {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
if (options.modEnv && options.env) {
|
|
18
|
+
throw new Error('Use either env or modEnv but not both');
|
|
19
|
+
}
|
|
20
|
+
const outputs = new Set(options.outputs);
|
|
21
|
+
const writeToOutputs = (x) => {
|
|
22
|
+
for (const outputStream of outputs) {
|
|
23
|
+
outputStream.write(x);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
// Always output the command
|
|
27
|
+
writeToOutputs(`💻 ${command.join(' ')}\n`);
|
|
28
|
+
const show = (_a = options.show) !== null && _a !== void 0 ? _a : 'always';
|
|
29
|
+
if (process.env.VERBOSE) {
|
|
30
|
+
outputs.add(process.stdout);
|
|
31
|
+
}
|
|
32
|
+
const env = (_b = options.env) !== null && _b !== void 0 ? _b : (options.modEnv ? { ...process.env, ...options.modEnv } : process.env);
|
|
33
|
+
const child = child_process.spawn(command[0], command.slice(1), {
|
|
34
|
+
...options,
|
|
35
|
+
env,
|
|
36
|
+
// Need this for Windows where we want .cmd and .bat to be found as well.
|
|
37
|
+
shell: true,
|
|
38
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
39
|
+
});
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
const stdout = new Array();
|
|
42
|
+
const stderr = new Array();
|
|
43
|
+
child.stdout.on('data', chunk => {
|
|
44
|
+
if (show === 'always') {
|
|
45
|
+
writeToOutputs(chunk);
|
|
46
|
+
}
|
|
47
|
+
stdout.push(chunk);
|
|
48
|
+
});
|
|
49
|
+
child.stderr.on('data', chunk => {
|
|
50
|
+
var _a;
|
|
51
|
+
if (show === 'always') {
|
|
52
|
+
writeToOutputs(chunk);
|
|
53
|
+
}
|
|
54
|
+
if ((_a = options.captureStderr) !== null && _a !== void 0 ? _a : true) {
|
|
55
|
+
stderr.push(chunk);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
child.once('error', reject);
|
|
59
|
+
child.once('close', code => {
|
|
60
|
+
const stderrOutput = Buffer.concat(stderr).toString('utf-8');
|
|
61
|
+
const stdoutOutput = Buffer.concat(stdout).toString('utf-8');
|
|
62
|
+
const out = (options.onlyStderr ? stderrOutput : stdoutOutput + stderrOutput).trim();
|
|
63
|
+
if (code === 0 || options.allowErrExit) {
|
|
64
|
+
resolve(out);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
if (show === 'error') {
|
|
68
|
+
writeToOutputs(`${out}\n`);
|
|
69
|
+
}
|
|
70
|
+
reject(new Error(`'${command.join(' ')}' exited with error code ${code}.`));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
class ShellHelper {
|
|
76
|
+
static fromContext(context) {
|
|
77
|
+
return new ShellHelper(context.integTestDir, context.output);
|
|
78
|
+
}
|
|
79
|
+
constructor(_cwd, _output) {
|
|
80
|
+
this._cwd = _cwd;
|
|
81
|
+
this._output = _output;
|
|
82
|
+
}
|
|
83
|
+
async shell(command, options = {}) {
|
|
84
|
+
return shell(command, {
|
|
85
|
+
outputs: [this._output],
|
|
86
|
+
cwd: this._cwd,
|
|
87
|
+
...options,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
exports.ShellHelper = ShellHelper;
|
|
92
|
+
/**
|
|
93
|
+
* rm -rf reimplementation, don't want to depend on an NPM package for this
|
|
94
|
+
*/
|
|
95
|
+
function rimraf(fsPath) {
|
|
96
|
+
try {
|
|
97
|
+
const isDir = fs.lstatSync(fsPath).isDirectory();
|
|
98
|
+
if (isDir) {
|
|
99
|
+
for (const file of fs.readdirSync(fsPath)) {
|
|
100
|
+
rimraf(path.join(fsPath, file));
|
|
101
|
+
}
|
|
102
|
+
fs.rmdirSync(fsPath);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
fs.unlinkSync(fsPath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
// We will survive ENOENT
|
|
110
|
+
if (e.code !== 'ENOENT') {
|
|
111
|
+
throw e;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function addToShellPath(x) {
|
|
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 : [];
|
|
118
|
+
if (!parts.includes(x)) {
|
|
119
|
+
parts.unshift(x);
|
|
120
|
+
}
|
|
121
|
+
process.env.PATH = parts.join(':');
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFXQSxzQkFrRUM7QUFnRUQsd0JBZ0JDO0FBRUQsd0NBUUM7QUF2S0QsK0NBQStDO0FBQy9DLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFJN0I7Ozs7R0FJRztBQUNJLEtBQUssVUFBVSxLQUFLLENBQUMsT0FBaUIsRUFBRSxVQUF3QixFQUFFOztJQUN2RSxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDbkMsS0FBSyxNQUFNLFlBQVksSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNuQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRiw0QkFBNEI7SUFDNUIsY0FBYyxDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsTUFBTSxJQUFJLEdBQUcsTUFBQSxPQUFPLENBQUMsSUFBSSxtQ0FBSSxRQUFRLENBQUM7SUFFdEMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFBLE9BQU8sQ0FBQyxHQUFHLG1DQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFH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LEtBQUssQ0FBQyxHQUFHLENBQUMsbUNBQUksRUFBRSxDQUFDO0lBRWpELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2hpbGRfcHJvY2VzcyBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBUZXN0Q29udGV4dCB9IGZyb20gJy4vaW50ZWctdGVzdCc7XG5pbXBvcnQgeyBUZW1wb3JhcnlEaXJlY3RvcnlDb250ZXh0IH0gZnJvbSAnLi93aXRoLXRlbXBvcmFyeS1kaXJlY3RvcnknO1xuXG4vKipcbiAqIEEgc2hlbGwgY29tbWFuZCB0aGF0IGRvZXMgd2hhdCB5b3Ugd2FudFxuICpcbiAqIElzIHBsYXRmb3JtLWF3YXJlLCBoYW5kbGVzIGVycm9ycyBuaWNlbHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaGVsbChjb21tYW5kOiBzdHJpbmdbXSwgb3B0aW9uczogU2hlbGxPcHRpb25zID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAob3B0aW9ucy5tb2RFbnYgJiYgb3B0aW9ucy5lbnYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VzZSBlaXRoZXIgZW52IG9yIG1vZEVudiBidXQgbm90IGJvdGgnKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dHMgPSBuZXcgU2V0KG9wdGlvbnMub3V0cHV0cyk7XG4gIGNvbnN0IHdyaXRlVG9PdXRwdXRzID0gKHg6IHN0cmluZykgPT4ge1xuICAgIGZvciAoY29uc3Qgb3V0cHV0U3RyZWFtIG9mIG91dHB1dHMpIHtcbiAgICAgIG91dHB1dFN0cmVhbS53cml0ZSh4KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gQWx3YXlzIG91dHB1dCB0aGUgY29tbWFuZFxuICB3cml0ZVRvT3V0cHV0cyhg8J+SuyAke2NvbW1hbmQuam9pbignICcpfVxcbmApO1xuICBjb25zdCBzaG93ID0gb3B0aW9ucy5zaG93ID8/ICdhbHdheXMnO1xuXG4gIGlmIChwcm9jZXNzLmVudi5WRVJCT1NFKSB7XG4gICAgb3V0cHV0cy5hZGQocHJvY2Vzcy5zdGRvdXQpO1xuICB9XG5cbiAgY29uc3QgZW52ID0gb3B0aW9ucy5lbnYgPz8gKG9wdGlvbnMubW9kRW52ID8geyAuLi5wcm9jZXNzLmVudiwgLi4ub3B0aW9ucy5tb2RFbnYgfSA6IHByb2Nlc3MuZW52KTtcblxuICBjb25zdCBjaGlsZCA9IGNoaWxkX3Byb2Nlc3Muc3Bhd24oY29tbWFuZFswXSwgY29tbWFuZC5zbGljZSgxKSwge1xuICAgIC4uLm9wdGlvbnMsXG4gICAgZW52LFxuICAgIC8vIE5lZWQgdGhpcyBmb3IgV2luZG93cyB3aGVyZSB3ZSB3YW50IC5jbWQgYW5kIC5iYXQgdG8gYmUgZm91bmQgYXMgd2VsbC5cbiAgICBzaGVsbDogdHJ1ZSxcbiAgICBzdGRpbzogWydpZ25vcmUnLCAncGlwZScsICdwaXBlJ10sXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdGRvdXQgPSBuZXcgQXJyYXk8QnVmZmVyPigpO1xuICAgIGNvbnN0IHN0ZGVyciA9IG5ldyBBcnJheTxCdWZmZXI+KCk7XG5cbiAgICBjaGlsZC5zdGRvdXQhLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgaWYgKHNob3cgPT09ICdhbHdheXMnKSB7XG4gICAgICAgIHdyaXRlVG9PdXRwdXRzKGNodW5rKTtcbiAgICAgIH1cbiAgICAgIHN0ZG91dC5wdXNoKGNodW5rKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLnN0ZGVyciEub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBpZiAoc2hvdyA9PT0gJ2Fsd2F5cycpIHtcbiAgICAgICAgd3JpdGVUb091dHB1dHMoY2h1bmspO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuY2FwdHVyZVN0ZGVyciA/PyB0cnVlKSB7XG4gICAgICAgIHN0ZGVyci5wdXNoKGNodW5rKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Nsb3NlJywgY29kZSA9PiB7XG4gICAgICBjb25zdCBzdGRlcnJPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZGVycikudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBzdGRvdXRPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZG91dCkudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBvdXQgPSAob3B0aW9ucy5vbmx5U3RkZXJyID8gc3RkZXJyT3V0cHV0IDogc3Rkb3V0T3V0cHV0ICsgc3RkZXJyT3V0cHV0KS50cmltKCk7XG4gICAgICBpZiAoY29kZSA9PT0gMCB8fCBvcHRpb25zLmFsbG93RXJyRXhpdCkge1xuICAgICAgICByZXNvbHZlKG91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2hvdyA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgIHdyaXRlVG9PdXRwdXRzKGAke291dH1cXG5gKTtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGAnJHtjb21tYW5kLmpvaW4oJyAnKX0nIGV4aXRlZCB3aXRoIGVycm9yIGNvZGUgJHtjb2RlfS5gKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoZWxsT3B0aW9ucyBleHRlbmRzIGNoaWxkX3Byb2Nlc3MuU3Bhd25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgdG8gYWRkIHRvICdlbnYnXG4gICAqL1xuICByZWFkb25seSBtb2RFbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBEb24ndCBmYWlsIHdoZW4gZXhpdGluZyB3aXRoIGFuIGVycm9yXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhbGxvd0VyckV4aXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNhcHR1cmUgc3RkZXJyXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNhcHR1cmVTdGRlcnI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXNzIG91dHB1dCBoZXJlXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRzPzogTm9kZUpTLldyaXRhYmxlU3RyZWFtW107XG5cbiAgLyoqXG4gICAqIE9ubHkgcmV0dXJuIHN0ZGVyci4gRm9yIGV4YW1wbGUsIHRoaXMgaXMgdXNlZCB0byB2YWxpZGF0ZVxuICAgKiB0aGF0IHdoZW4gQ0k9dHJ1ZSwgYWxsIGxvZ3MgYXJlIHNlbnQgdG8gc3Rkb3V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgb25seVN0ZGVycj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERvbid0IGxvZyB0byBzdGRvdXRcbiAgICpcbiAgICogQGRlZmF1bHQgYWx3YXlzXG4gICAqL1xuICByZWFkb25seSBzaG93PzogJ2Fsd2F5cycgfCAnbmV2ZXInIHwgJ2Vycm9yJztcbn1cblxuZXhwb3J0IGNsYXNzIFNoZWxsSGVscGVyIHtcbiAgcHVibGljIHN0YXRpYyBmcm9tQ29udGV4dChjb250ZXh0OiBUZXN0Q29udGV4dCAmIFRlbXBvcmFyeURpcmVjdG9yeUNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFNoZWxsSGVscGVyKGNvbnRleHQuaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jd2Q6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkgeyB9XG5cbiAgcHVibGljIGFzeW5jIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdLCBvcHRpb25zOiBPbWl0PFNoZWxsT3B0aW9ucywgJ2N3ZCcgfCAnb3V0cHV0cyc+ID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBzaGVsbChjb21tYW5kLCB7XG4gICAgICBvdXRwdXRzOiBbdGhpcy5fb3V0cHV0XSxcbiAgICAgIGN3ZDogdGhpcy5fY3dkLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHJtIC1yZiByZWltcGxlbWVudGF0aW9uLCBkb24ndCB3YW50IHRvIGRlcGVuZCBvbiBhbiBOUE0gcGFja2FnZSBmb3IgdGhpc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmltcmFmKGZzUGF0aDogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgaXNEaXIgPSBmcy5sc3RhdFN5bmMoZnNQYXRoKS5pc0RpcmVjdG9yeSgpO1xuXG4gICAgaWYgKGlzRGlyKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZnMucmVhZGRpclN5bmMoZnNQYXRoKSkge1xuICAgICAgICByaW1yYWYocGF0aC5qb2luKGZzUGF0aCwgZmlsZSkpO1xuICAgICAgfVxuICAgICAgZnMucm1kaXJTeW5jKGZzUGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZzLnVubGlua1N5bmMoZnNQYXRoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIC8vIFdlIHdpbGwgc3Vydml2ZSBFTk9FTlRcbiAgICBpZiAoZS5jb2RlICE9PSAnRU5PRU5UJykgeyB0aHJvdyBlOyB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRvU2hlbGxQYXRoKHg6IHN0cmluZykge1xuICBjb25zdCBwYXJ0cyA9IHByb2Nlc3MuZW52LlBBVEg/LnNwbGl0KCc6JykgPz8gW107XG5cbiAgaWYgKCFwYXJ0cy5pbmNsdWRlcyh4KSkge1xuICAgIHBhcnRzLnVuc2hpZnQoeCk7XG4gIH1cblxuICBwcm9jZXNzLmVudi5QQVRIID0gcGFydHMuam9pbignOicpO1xufVxuIl19
|