@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.
Files changed (257) hide show
  1. package/.eslintrc.js +9 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +16 -0
  4. package/README.md +205 -0
  5. package/bin/apply-patches +22 -0
  6. package/bin/download-and-run-old-tests +52 -0
  7. package/bin/query-github +2 -0
  8. package/bin/query-github.d.ts +1 -0
  9. package/bin/query-github.js +54 -0
  10. package/bin/query-github.ts +56 -0
  11. package/bin/run-suite +2 -0
  12. package/bin/run-suite.d.ts +1 -0
  13. package/bin/run-suite.js +131 -0
  14. package/bin/run-suite.ts +140 -0
  15. package/bin/stage-distribution +2 -0
  16. package/bin/stage-distribution.d.ts +1 -0
  17. package/bin/stage-distribution.js +217 -0
  18. package/bin/stage-distribution.ts +267 -0
  19. package/bin/test-root +2 -0
  20. package/bin/test-root.d.ts +1 -0
  21. package/bin/test-root.js +6 -0
  22. package/bin/test-root.ts +3 -0
  23. package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
  24. package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
  25. package/entrypoints/test-cli-regression.bash +83 -0
  26. package/entrypoints/test.sh +12 -0
  27. package/lib/aws.d.ts +51 -0
  28. package/lib/aws.js +206 -0
  29. package/lib/aws.ts +263 -0
  30. package/lib/corking.d.ts +12 -0
  31. package/lib/corking.js +35 -0
  32. package/lib/corking.ts +33 -0
  33. package/lib/eventually.d.ts +20 -0
  34. package/lib/eventually.js +34 -0
  35. package/lib/eventually.ts +42 -0
  36. package/lib/files.d.ts +15 -0
  37. package/lib/files.js +80 -0
  38. package/lib/files.ts +80 -0
  39. package/lib/github.d.ts +4 -0
  40. package/lib/github.js +43 -0
  41. package/lib/github.ts +43 -0
  42. package/lib/index.d.ts +13 -0
  43. package/lib/index.js +30 -0
  44. package/lib/index.ts +13 -0
  45. package/lib/integ-test.d.ts +10 -0
  46. package/lib/integ-test.js +70 -0
  47. package/lib/integ-test.ts +81 -0
  48. package/lib/lists.d.ts +1 -0
  49. package/lib/lists.js +11 -0
  50. package/lib/lists.ts +9 -0
  51. package/lib/memoize.d.ts +6 -0
  52. package/lib/memoize.js +18 -0
  53. package/lib/memoize.ts +14 -0
  54. package/lib/npm.d.ts +8 -0
  55. package/lib/npm.js +38 -0
  56. package/lib/npm.ts +41 -0
  57. package/lib/package-sources/release-source.d.ts +23 -0
  58. package/lib/package-sources/release-source.js +71 -0
  59. package/lib/package-sources/release-source.ts +81 -0
  60. package/lib/package-sources/repo-source.d.ts +30 -0
  61. package/lib/package-sources/repo-source.js +97 -0
  62. package/lib/package-sources/repo-source.ts +111 -0
  63. package/lib/package-sources/repo-tools/npm +2 -0
  64. package/lib/package-sources/repo-tools/npm.d.ts +1 -0
  65. package/lib/package-sources/repo-tools/npm.js +43 -0
  66. package/lib/package-sources/repo-tools/npm.ts +48 -0
  67. package/lib/package-sources/source.d.ts +28 -0
  68. package/lib/package-sources/source.js +3 -0
  69. package/lib/package-sources/source.ts +35 -0
  70. package/lib/package-sources/subprocess.d.ts +3 -0
  71. package/lib/package-sources/subprocess.js +17 -0
  72. package/lib/package-sources/subprocess.ts +15 -0
  73. package/lib/resource-pool.d.ts +50 -0
  74. package/lib/resource-pool.js +117 -0
  75. package/lib/resource-pool.ts +140 -0
  76. package/lib/resources.d.ts +1 -0
  77. package/lib/resources.js +6 -0
  78. package/lib/resources.ts +4 -0
  79. package/lib/shell.d.ts +56 -0
  80. package/lib/shell.js +123 -0
  81. package/lib/shell.ts +168 -0
  82. package/lib/staging/codeartifact.d.ts +44 -0
  83. package/lib/staging/codeartifact.js +281 -0
  84. package/lib/staging/codeartifact.ts +387 -0
  85. package/lib/staging/maven.d.ts +5 -0
  86. package/lib/staging/maven.js +91 -0
  87. package/lib/staging/maven.ts +95 -0
  88. package/lib/staging/npm.d.ts +4 -0
  89. package/lib/staging/npm.js +55 -0
  90. package/lib/staging/npm.ts +62 -0
  91. package/lib/staging/nuget.d.ts +4 -0
  92. package/lib/staging/nuget.js +69 -0
  93. package/lib/staging/nuget.ts +75 -0
  94. package/lib/staging/parallel-shell.d.ts +5 -0
  95. package/lib/staging/parallel-shell.js +45 -0
  96. package/lib/staging/parallel-shell.ts +51 -0
  97. package/lib/staging/pypi.d.ts +4 -0
  98. package/lib/staging/pypi.js +48 -0
  99. package/lib/staging/pypi.ts +50 -0
  100. package/lib/staging/usage-dir.d.ts +31 -0
  101. package/lib/staging/usage-dir.js +87 -0
  102. package/lib/staging/usage-dir.ts +99 -0
  103. package/lib/with-aws.d.ts +14 -0
  104. package/lib/with-aws.js +60 -0
  105. package/lib/with-aws.ts +67 -0
  106. package/lib/with-cdk-app.d.ts +210 -0
  107. package/lib/with-cdk-app.js +539 -0
  108. package/lib/with-cdk-app.ts +742 -0
  109. package/lib/with-cli-lib.d.ts +17 -0
  110. package/lib/with-cli-lib.js +123 -0
  111. package/lib/with-cli-lib.ts +134 -0
  112. package/lib/with-packages.d.ts +5 -0
  113. package/lib/with-packages.js +13 -0
  114. package/lib/with-packages.ts +15 -0
  115. package/lib/with-sam.d.ts +33 -0
  116. package/lib/with-sam.js +258 -0
  117. package/lib/with-sam.ts +288 -0
  118. package/lib/with-temporary-directory.d.ts +5 -0
  119. package/lib/with-temporary-directory.js +31 -0
  120. package/lib/with-temporary-directory.ts +35 -0
  121. package/lib/with-timeout.d.ts +19 -0
  122. package/lib/with-timeout.js +34 -0
  123. package/lib/with-timeout.ts +33 -0
  124. package/lib/xpmutex.d.ts +43 -0
  125. package/lib/xpmutex.js +207 -0
  126. package/lib/xpmutex.ts +218 -0
  127. package/package.json +111 -0
  128. package/resources/bootstrap-templates/session-tags.all-roles-deny-all.yaml +703 -0
  129. package/resources/bootstrap-templates/session-tags.deploy-role-deny-sqs.yaml +700 -0
  130. package/resources/cdk-apps/app/app.js +926 -0
  131. package/resources/cdk-apps/app/appsync.hotswap.graphql +3 -0
  132. package/resources/cdk-apps/app/cdk.json +7 -0
  133. package/resources/cdk-apps/app/docker/Dockerfile +2 -0
  134. package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
  135. package/resources/cdk-apps/app/lambda/index.js +4 -0
  136. package/resources/cdk-apps/app/lambda/response.json +3 -0
  137. package/resources/cdk-apps/app/nested-stack.js +65 -0
  138. package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
  139. package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
  140. package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
  141. package/resources/cdk-apps/rollback-test-app/app.js +110 -0
  142. package/resources/cdk-apps/rollback-test-app/cdk.json +7 -0
  143. package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
  144. package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
  145. package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
  146. package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
  147. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
  148. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
  149. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
  150. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
  151. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
  152. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
  153. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
  154. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
  155. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
  156. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
  157. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
  158. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
  159. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
  160. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
  161. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
  162. package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
  163. package/resources/cdk-apps/simple-app/app.js +26 -0
  164. package/resources/cdk-apps/simple-app/cdk.json +7 -0
  165. package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
  166. package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
  167. package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
  168. package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
  169. package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
  170. package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
  171. package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
  172. package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
  173. package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
  174. package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
  175. package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
  176. package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
  177. package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
  178. package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
  179. package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
  180. package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
  181. package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
  182. package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
  183. package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
  184. package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
  185. package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
  186. package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
  187. package/resources/cli-regression-patches/v2.130.0/NOTES.md +1 -0
  188. 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
  189. 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
  190. package/resources/cli-regression-patches/v2.130.0/skip-tests.txt +5 -0
  191. package/resources/cli-regression-patches/v2.132.0/NOTES.md +1 -0
  192. package/resources/cli-regression-patches/v2.132.0/skip-tests.txt +4 -0
  193. package/resources/cli-regression-patches/v2.142.0/NOTES.md +1 -0
  194. package/resources/cli-regression-patches/v2.142.0/skip-tests.txt +4 -0
  195. package/resources/cli-regression-patches/v2.160.0/skip-tests.txt +2 -0
  196. package/resources/cli-regression-patches/v2.161.0/NOTES.md +1 -0
  197. package/resources/cli-regression-patches/v2.161.0/skip-tests.txt +5 -0
  198. package/resources/cli-regression-patches/v2.166.0/NOTES.md +1 -0
  199. package/resources/cli-regression-patches/v2.166.0/skip-tests.txt +2 -0
  200. package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
  201. package/resources/cloud-assemblies/0.36.0/cdk.out +1 -0
  202. package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
  203. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
  204. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/cdk.out +1 -0
  205. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
  206. package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
  207. package/resources/cloud-assemblies/1.10.0-request-azs/cdk.out +1 -0
  208. package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
  209. package/resources/integ.jest.config.js +25 -0
  210. package/resources/templates/sqs-template.json +36 -0
  211. package/skip-tests.txt +8 -0
  212. package/tests/cli-integ-tests/README.md +47 -0
  213. package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
  214. package/tests/cli-integ-tests/bootstrapping.integtest.js +412 -0
  215. package/tests/cli-integ-tests/bootstrapping.integtest.ts +493 -0
  216. package/tests/cli-integ-tests/cli-lib.integtest.d.ts +1 -0
  217. package/tests/cli-integ-tests/cli-lib.integtest.js +62 -0
  218. package/tests/cli-integ-tests/cli-lib.integtest.ts +90 -0
  219. package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
  220. package/tests/cli-integ-tests/cli.integtest.js +2104 -0
  221. package/tests/cli-integ-tests/cli.integtest.ts +2874 -0
  222. package/tests/cli-integ-tests/garbage-collection.integtest.d.ts +1 -0
  223. package/tests/cli-integ-tests/garbage-collection.integtest.js +314 -0
  224. package/tests/cli-integ-tests/garbage-collection.integtest.ts +392 -0
  225. package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
  226. package/tests/init-csharp/init-csharp.integtest.js +14 -0
  227. package/tests/init-csharp/init-csharp.integtest.ts +15 -0
  228. package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
  229. package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
  230. package/tests/init-fsharp/init-fsharp.integtest.ts +15 -0
  231. package/tests/init-go/init-go.integtest.d.ts +1 -0
  232. package/tests/init-go/init-go.integtest.js +21 -0
  233. package/tests/init-go/init-go.integtest.ts +23 -0
  234. package/tests/init-java/init-java.integtest.d.ts +1 -0
  235. package/tests/init-java/init-java.integtest.js +14 -0
  236. package/tests/init-java/init-java.integtest.ts +14 -0
  237. package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
  238. package/tests/init-javascript/init-javascript.integtest.js +53 -0
  239. package/tests/init-javascript/init-javascript.integtest.ts +59 -0
  240. package/tests/init-python/init-python.integtest.d.ts +1 -0
  241. package/tests/init-python/init-python.integtest.js +19 -0
  242. package/tests/init-python/init-python.integtest.ts +20 -0
  243. package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
  244. package/tests/init-typescript-app/init-typescript-app.integtest.js +54 -0
  245. package/tests/init-typescript-app/init-typescript-app.integtest.ts +66 -0
  246. package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
  247. package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
  248. package/tests/init-typescript-lib/init-typescript-lib.integtest.ts +13 -0
  249. package/tests/tool-integrations/amplify.integtest.d.ts +1 -0
  250. package/tests/tool-integrations/amplify.integtest.js +39 -0
  251. package/tests/tool-integrations/amplify.integtest.ts +43 -0
  252. package/tests/tool-integrations/with-tool-context.d.ts +9 -0
  253. package/tests/tool-integrations/with-tool-context.js +13 -0
  254. package/tests/tool-integrations/with-tool-context.ts +14 -0
  255. package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
  256. package/tests/uberpackage/uberpackage.integtest.js +11 -0
  257. 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,3 @@
1
+ import { IPackageSourceSetup, IPackageSource } from './source';
2
+ export declare function serializeForSubprocess(s: IPackageSourceSetup): void;
3
+ export declare function packageSourceInSubprocess(): IPackageSource;
@@ -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;
@@ -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
@@ -0,0 +1,4 @@
1
+ import * as path from 'path';
2
+
3
+ export const RESOURCES_DIR = path.resolve(__dirname, '..', 'resources');
4
+
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hlbGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzaGVsbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFXQSxzQkFrRUM7QUFnRUQsd0JBZ0JDO0FBRUQsd0NBUUM7QUF2S0QsK0NBQStDO0FBQy9DLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFJN0I7Ozs7R0FJRztBQUNJLEtBQUssVUFBVSxLQUFLLENBQUMsT0FBaUIsRUFBRSxVQUF3QixFQUFFOztJQUN2RSxJQUFJLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUU7UUFDbkMsS0FBSyxNQUFNLFlBQVksSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNuQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hCLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRiw0QkFBNEI7SUFDNUIsY0FBYyxDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsTUFBTSxJQUFJLEdBQUcsTUFBQSxPQUFPLENBQUMsSUFBSSxtQ0FBSSxRQUFRLENBQUM7SUFFdEMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFBLE9BQU8sQ0FBQyxHQUFHLG1DQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVsRyxNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQzlELEdBQUcsT0FBTztRQUNWLEdBQUc7UUFDSCx5RUFBeUU7UUFDekUsS0FBSyxFQUFFLElBQUk7UUFDWCxLQUFLLEVBQUUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztLQUNsQyxDQUFDLENBQUM7SUFFSCxPQUFPLElBQUksT0FBTyxDQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQzdDLE1BQU0sTUFBTSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7UUFDbkMsTUFBTSxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztRQUVuQyxLQUFLLENBQUMsTUFBTyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUU7WUFDL0IsSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3RCLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QixDQUFDO1lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxNQUFPLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRTs7WUFDL0IsSUFBSSxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3RCLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QixDQUFDO1lBQ0QsSUFBSSxNQUFBLE9BQU8sQ0FBQyxhQUFhLG1DQUFJLElBQUksRUFBRSxDQUFDO2dCQUNsQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRTVCLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFO1lBQ3pCLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzdELE1BQU0sR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDckYsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDdkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO29CQUNyQixjQUFjLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDO2dCQUM3QixDQUFDO2dCQUNELE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDRCQUE0QixJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDOUUsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBMkNELE1BQWEsV0FBVztJQUNmLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBZ0Q7UUFDeEUsT0FBTyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsWUFDbUIsSUFBWSxFQUNaLE9BQThCO1FBRDlCLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixZQUFPLEdBQVAsT0FBTyxDQUF1QjtJQUFJLENBQUM7SUFFL0MsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFpQixFQUFFLFVBQWlELEVBQUU7UUFDdkYsT0FBTyxLQUFLLENBQUMsT0FBTyxFQUFFO1lBQ3BCLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDdkIsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2QsR0FBRyxPQUFPO1NBQ1gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBaEJELGtDQWdCQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsTUFBTSxDQUFDLE1BQWM7SUFDbkMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVqRCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsS0FBSyxNQUFNLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFDRCxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7YUFBTSxDQUFDO1lBQ04sRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7UUFDaEIseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQUMsQ0FBQztJQUN2QyxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQWdCLGNBQWMsQ0FBQyxDQUFTOztJQUN0QyxNQUFNLEtBQUssR0FBRyxNQUFBLE1BQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLDBDQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsbUNBQUksRUFBRSxDQUFDO0lBRWpELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2hpbGRfcHJvY2VzcyBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBUZXN0Q29udGV4dCB9IGZyb20gJy4vaW50ZWctdGVzdCc7XG5pbXBvcnQgeyBUZW1wb3JhcnlEaXJlY3RvcnlDb250ZXh0IH0gZnJvbSAnLi93aXRoLXRlbXBvcmFyeS1kaXJlY3RvcnknO1xuXG4vKipcbiAqIEEgc2hlbGwgY29tbWFuZCB0aGF0IGRvZXMgd2hhdCB5b3Ugd2FudFxuICpcbiAqIElzIHBsYXRmb3JtLWF3YXJlLCBoYW5kbGVzIGVycm9ycyBuaWNlbHkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzaGVsbChjb21tYW5kOiBzdHJpbmdbXSwgb3B0aW9uczogU2hlbGxPcHRpb25zID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAob3B0aW9ucy5tb2RFbnYgJiYgb3B0aW9ucy5lbnYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1VzZSBlaXRoZXIgZW52IG9yIG1vZEVudiBidXQgbm90IGJvdGgnKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dHMgPSBuZXcgU2V0KG9wdGlvbnMub3V0cHV0cyk7XG4gIGNvbnN0IHdyaXRlVG9PdXRwdXRzID0gKHg6IHN0cmluZykgPT4ge1xuICAgIGZvciAoY29uc3Qgb3V0cHV0U3RyZWFtIG9mIG91dHB1dHMpIHtcbiAgICAgIG91dHB1dFN0cmVhbS53cml0ZSh4KTtcbiAgICB9XG4gIH07XG5cbiAgLy8gQWx3YXlzIG91dHB1dCB0aGUgY29tbWFuZFxuICB3cml0ZVRvT3V0cHV0cyhg8J+SuyAke2NvbW1hbmQuam9pbignICcpfVxcbmApO1xuICBjb25zdCBzaG93ID0gb3B0aW9ucy5zaG93ID8/ICdhbHdheXMnO1xuXG4gIGlmIChwcm9jZXNzLmVudi5WRVJCT1NFKSB7XG4gICAgb3V0cHV0cy5hZGQocHJvY2Vzcy5zdGRvdXQpO1xuICB9XG5cbiAgY29uc3QgZW52ID0gb3B0aW9ucy5lbnYgPz8gKG9wdGlvbnMubW9kRW52ID8geyAuLi5wcm9jZXNzLmVudiwgLi4ub3B0aW9ucy5tb2RFbnYgfSA6IHByb2Nlc3MuZW52KTtcblxuICBjb25zdCBjaGlsZCA9IGNoaWxkX3Byb2Nlc3Muc3Bhd24oY29tbWFuZFswXSwgY29tbWFuZC5zbGljZSgxKSwge1xuICAgIC4uLm9wdGlvbnMsXG4gICAgZW52LFxuICAgIC8vIE5lZWQgdGhpcyBmb3IgV2luZG93cyB3aGVyZSB3ZSB3YW50IC5jbWQgYW5kIC5iYXQgdG8gYmUgZm91bmQgYXMgd2VsbC5cbiAgICBzaGVsbDogdHJ1ZSxcbiAgICBzdGRpbzogWydpZ25vcmUnLCAncGlwZScsICdwaXBlJ10sXG4gIH0pO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZTxzdHJpbmc+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBzdGRvdXQgPSBuZXcgQXJyYXk8QnVmZmVyPigpO1xuICAgIGNvbnN0IHN0ZGVyciA9IG5ldyBBcnJheTxCdWZmZXI+KCk7XG5cbiAgICBjaGlsZC5zdGRvdXQhLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgaWYgKHNob3cgPT09ICdhbHdheXMnKSB7XG4gICAgICAgIHdyaXRlVG9PdXRwdXRzKGNodW5rKTtcbiAgICAgIH1cbiAgICAgIHN0ZG91dC5wdXNoKGNodW5rKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLnN0ZGVyciEub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBpZiAoc2hvdyA9PT0gJ2Fsd2F5cycpIHtcbiAgICAgICAgd3JpdGVUb091dHB1dHMoY2h1bmspO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMuY2FwdHVyZVN0ZGVyciA/PyB0cnVlKSB7XG4gICAgICAgIHN0ZGVyci5wdXNoKGNodW5rKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Vycm9yJywgcmVqZWN0KTtcblxuICAgIGNoaWxkLm9uY2UoJ2Nsb3NlJywgY29kZSA9PiB7XG4gICAgICBjb25zdCBzdGRlcnJPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZGVycikudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBzdGRvdXRPdXRwdXQgPSBCdWZmZXIuY29uY2F0KHN0ZG91dCkudG9TdHJpbmcoJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBvdXQgPSAob3B0aW9ucy5vbmx5U3RkZXJyID8gc3RkZXJyT3V0cHV0IDogc3Rkb3V0T3V0cHV0ICsgc3RkZXJyT3V0cHV0KS50cmltKCk7XG4gICAgICBpZiAoY29kZSA9PT0gMCB8fCBvcHRpb25zLmFsbG93RXJyRXhpdCkge1xuICAgICAgICByZXNvbHZlKG91dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2hvdyA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgIHdyaXRlVG9PdXRwdXRzKGAke291dH1cXG5gKTtcbiAgICAgICAgfVxuICAgICAgICByZWplY3QobmV3IEVycm9yKGAnJHtjb21tYW5kLmpvaW4oJyAnKX0nIGV4aXRlZCB3aXRoIGVycm9yIGNvZGUgJHtjb2RlfS5gKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoZWxsT3B0aW9ucyBleHRlbmRzIGNoaWxkX3Byb2Nlc3MuU3Bhd25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgdG8gYWRkIHRvICdlbnYnXG4gICAqL1xuICByZWFkb25seSBtb2RFbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBEb24ndCBmYWlsIHdoZW4gZXhpdGluZyB3aXRoIGFuIGVycm9yXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBhbGxvd0VyckV4aXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNhcHR1cmUgc3RkZXJyXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGNhcHR1cmVTdGRlcnI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXNzIG91dHB1dCBoZXJlXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRzPzogTm9kZUpTLldyaXRhYmxlU3RyZWFtW107XG5cbiAgLyoqXG4gICAqIE9ubHkgcmV0dXJuIHN0ZGVyci4gRm9yIGV4YW1wbGUsIHRoaXMgaXMgdXNlZCB0byB2YWxpZGF0ZVxuICAgKiB0aGF0IHdoZW4gQ0k9dHJ1ZSwgYWxsIGxvZ3MgYXJlIHNlbnQgdG8gc3Rkb3V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgb25seVN0ZGVycj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERvbid0IGxvZyB0byBzdGRvdXRcbiAgICpcbiAgICogQGRlZmF1bHQgYWx3YXlzXG4gICAqL1xuICByZWFkb25seSBzaG93PzogJ2Fsd2F5cycgfCAnbmV2ZXInIHwgJ2Vycm9yJztcbn1cblxuZXhwb3J0IGNsYXNzIFNoZWxsSGVscGVyIHtcbiAgcHVibGljIHN0YXRpYyBmcm9tQ29udGV4dChjb250ZXh0OiBUZXN0Q29udGV4dCAmIFRlbXBvcmFyeURpcmVjdG9yeUNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IFNoZWxsSGVscGVyKGNvbnRleHQuaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9jd2Q6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkgeyB9XG5cbiAgcHVibGljIGFzeW5jIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdLCBvcHRpb25zOiBPbWl0PFNoZWxsT3B0aW9ucywgJ2N3ZCcgfCAnb3V0cHV0cyc+ID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBzaGVsbChjb21tYW5kLCB7XG4gICAgICBvdXRwdXRzOiBbdGhpcy5fb3V0cHV0XSxcbiAgICAgIGN3ZDogdGhpcy5fY3dkLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIHJtIC1yZiByZWltcGxlbWVudGF0aW9uLCBkb24ndCB3YW50IHRvIGRlcGVuZCBvbiBhbiBOUE0gcGFja2FnZSBmb3IgdGhpc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmltcmFmKGZzUGF0aDogc3RyaW5nKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgaXNEaXIgPSBmcy5sc3RhdFN5bmMoZnNQYXRoKS5pc0RpcmVjdG9yeSgpO1xuXG4gICAgaWYgKGlzRGlyKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZnMucmVhZGRpclN5bmMoZnNQYXRoKSkge1xuICAgICAgICByaW1yYWYocGF0aC5qb2luKGZzUGF0aCwgZmlsZSkpO1xuICAgICAgfVxuICAgICAgZnMucm1kaXJTeW5jKGZzUGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZzLnVubGlua1N5bmMoZnNQYXRoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIC8vIFdlIHdpbGwgc3Vydml2ZSBFTk9FTlRcbiAgICBpZiAoZS5jb2RlICE9PSAnRU5PRU5UJykgeyB0aHJvdyBlOyB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRvU2hlbGxQYXRoKHg6IHN0cmluZykge1xuICBjb25zdCBwYXJ0cyA9IHByb2Nlc3MuZW52LlBBVEg/LnNwbGl0KCc6JykgPz8gW107XG5cbiAgaWYgKCFwYXJ0cy5pbmNsdWRlcyh4KSkge1xuICAgIHBhcnRzLnVuc2hpZnQoeCk7XG4gIH1cblxuICBwcm9jZXNzLmVudi5QQVRIID0gcGFydHMuam9pbignOicpO1xufVxuIl19