hammerkit 1.5.0 → 1.6.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (480) hide show
  1. package/.agents/FEEDBACK.md +74 -0
  2. package/.agents/skills/before-commit/SKILL.md +101 -0
  3. package/.agents/skills/do-the-work/SKILL.md +64 -0
  4. package/.agents/skills/fix-ci/SKILL.md +98 -0
  5. package/.agents/skills/speckit-git-commit/SKILL.md +53 -0
  6. package/.agents/skills/speckit-git-feature/SKILL.md +72 -0
  7. package/.agents/skills/speckit-git-initialize/SKILL.md +54 -0
  8. package/.agents/skills/speckit-git-remote/SKILL.md +50 -0
  9. package/.agents/skills/speckit-git-validate/SKILL.md +54 -0
  10. package/.gitbook.yaml +5 -0
  11. package/.specify/extensions/.registry +37 -0
  12. package/.specify/extensions/git/README.md +100 -0
  13. package/.specify/extensions/git/commands/speckit.git.commit.md +48 -0
  14. package/.specify/extensions/git/commands/speckit.git.feature.md +67 -0
  15. package/.specify/extensions/git/commands/speckit.git.initialize.md +49 -0
  16. package/.specify/extensions/git/commands/speckit.git.remote.md +45 -0
  17. package/.specify/extensions/git/commands/speckit.git.validate.md +49 -0
  18. package/.specify/extensions/git/config-template.yml +62 -0
  19. package/.specify/extensions/git/extension.yml +140 -0
  20. package/.specify/extensions/git/git-config.yml +62 -0
  21. package/.specify/extensions.yml +149 -0
  22. package/.specify/feature.json +3 -0
  23. package/.specify/init-options.json +10 -0
  24. package/.specify/integration.json +15 -0
  25. package/.specify/integrations/claude.manifest.json +16 -0
  26. package/.specify/integrations/speckit.manifest.json +17 -0
  27. package/.specify/memory/constitution.md +162 -0
  28. package/.specify/templates/checklist-template.md +40 -0
  29. package/.specify/templates/constitution-template.md +50 -0
  30. package/.specify/templates/plan-template.md +113 -0
  31. package/.specify/templates/spec-template.md +131 -0
  32. package/.specify/templates/tasks-template.md +252 -0
  33. package/.specify/workflows/speckit/workflow.yml +77 -0
  34. package/.specify/workflows/workflow-registry.json +13 -0
  35. package/AGENTS.md +94 -0
  36. package/Dockerfile +3 -3
  37. package/FOLLOWUPS.md +34 -0
  38. package/README.md +9 -7
  39. package/SUMMARY.md +30 -5
  40. package/VALUES.md +53 -0
  41. package/build.schema.json +542 -408
  42. package/dist/cache/auto-pull.spec.js +123 -0
  43. package/dist/cache/backends/local-cache-backend.js +56 -0
  44. package/dist/cache/backends/local-cache-backend.spec.js +72 -0
  45. package/dist/cache/backends/s3-cache-backend.js +124 -0
  46. package/dist/cache/backends/s3-cache-backend.spec.js +118 -0
  47. package/dist/cache/cache-backend-registry.js +21 -0
  48. package/dist/cache/cache-backend-registry.spec.js +22 -0
  49. package/dist/cache/cache-backend.js +3 -0
  50. package/dist/cache/resolve-cache.js +60 -0
  51. package/dist/cache/resolve-cache.spec.js +52 -0
  52. package/dist/cli.js +112 -82
  53. package/dist/cli.spec.js +20 -2
  54. package/dist/console/get-logger.spec.js +23 -0
  55. package/dist/docker/get-default-platform.spec.js +29 -0
  56. package/dist/docker/longest-common-prefix.spec.js +26 -0
  57. package/dist/docker/package.js +283 -0
  58. package/dist/docker/package.spec.js +145 -0
  59. package/dist/docker/pull.js +4 -4
  60. package/dist/docker/remove-container.spec.js +32 -0
  61. package/dist/docker/stream.js +3 -3
  62. package/dist/docker/using-container.js +29 -11
  63. package/dist/docker/using-container.spec.js +90 -0
  64. package/dist/environment/merge-environment-variables.js +21 -0
  65. package/dist/environment/merge-environment-variables.spec.js +24 -0
  66. package/dist/environment/replace-env-variables.js +43 -10
  67. package/dist/environment/replace-env-variables.spec.js +47 -0
  68. package/dist/executer/abort.spec.js +18 -0
  69. package/dist/executer/await-completed-dependencies.js +56 -0
  70. package/dist/executer/cache-metadata.js +11 -0
  71. package/dist/executer/check-readiness.js +1 -1
  72. package/dist/{planner/work-node-port.js → executer/container-bind.js} +1 -1
  73. package/dist/executer/docker-service.js +110 -86
  74. package/dist/executer/docker-task.js +132 -0
  75. package/dist/executer/environment-mock.js +3 -4
  76. package/dist/executer/environment-mock.spec.js +22 -0
  77. package/dist/executer/event-cache.js +60 -127
  78. package/dist/executer/execute-command.js +4 -3
  79. package/dist/executer/execute-docker.js +32 -14
  80. package/dist/executer/execute-work-service.js +61 -0
  81. package/dist/executer/execute-work-task.js +107 -0
  82. package/dist/executer/execute-work-tree.js +27 -0
  83. package/dist/executer/execute.spec.js +14 -10
  84. package/dist/executer/execution-steps.js +47 -31
  85. package/dist/executer/get-container-binds.js +19 -0
  86. package/dist/executer/get-docker-executor.js +12 -12
  87. package/dist/executer/get-scheduler-down-result.js +12 -0
  88. package/dist/executer/get-scheduler-execute-result.js +28 -0
  89. package/dist/executer/get-scheduler-up-result.js +12 -0
  90. package/dist/executer/get-service-containers.js +14 -0
  91. package/dist/executer/get-service-containers.spec.js +59 -0
  92. package/dist/executer/get-service-env-hints.js +35 -0
  93. package/dist/executer/get-service-env-hints.spec.js +65 -0
  94. package/dist/executer/kubernetes-service.js +116 -48
  95. package/dist/executer/label-values.js +29 -46
  96. package/dist/executer/label-values.spec.js +61 -0
  97. package/dist/executer/lazy-resolver.js +16 -0
  98. package/dist/executer/lazy-resolver.spec.js +20 -0
  99. package/dist/executer/local-task.js +44 -0
  100. package/dist/executer/process-manager.js +16 -70
  101. package/dist/executer/process-manager.spec.js +39 -76
  102. package/dist/executer/reset-work-tree.js +30 -0
  103. package/dist/executer/scheduler/check-for-loop.js +17 -7
  104. package/dist/executer/scheduler/{scheduler-state.js → dependency-state.js} +1 -1
  105. package/dist/executer/scheduler/enqueue-next.js +83 -19
  106. package/dist/executer/scheduler/enqueue-next.spec.js +136 -0
  107. package/dist/executer/scheduler/{node-state.js → need-state.js} +1 -1
  108. package/dist/{parser/build-file.js → executer/scheduler/task-state.js} +1 -1
  109. package/dist/executer/set-user-permission.js +1 -1
  110. package/dist/executer/state-resolver.js +61 -0
  111. package/dist/executer/state-resolver.spec.js +37 -0
  112. package/dist/executer/state.js +37 -31
  113. package/dist/executer/state.spec.js +66 -0
  114. package/dist/executer/states.spec.js +14 -0
  115. package/dist/executer/watch-loop.js +68 -0
  116. package/dist/executer/watch-state-key.js +44 -0
  117. package/dist/executer/work-scope.js +1 -5
  118. package/dist/file/get-file-context.js +24 -3
  119. package/dist/file/get-file-context.spec.js +178 -0
  120. package/dist/file/move-files.js +2 -2
  121. package/dist/file/move-files.spec.js +48 -0
  122. package/dist/index.js +7 -8
  123. package/dist/json-schema.js +12 -0
  124. package/dist/kubernetes/apply.js +34 -0
  125. package/dist/kubernetes/await-running-state.js +71 -0
  126. package/dist/kubernetes/ensure-http-route.js +53 -0
  127. package/dist/kubernetes/ensure-http-route.spec.js +70 -0
  128. package/dist/kubernetes/ensure-ingress.js +54 -0
  129. package/dist/kubernetes/ensure-kubernetes-deployment-exists.js +105 -0
  130. package/dist/kubernetes/ensure-kubernetes-persistent-volume-claim-exists.js +40 -0
  131. package/dist/kubernetes/ensure-kubernetes-service-exists.js +36 -0
  132. package/dist/kubernetes/ensure-namespace.js +43 -0
  133. package/dist/kubernetes/ensure-namespace.spec.js +39 -0
  134. package/dist/kubernetes/ensure-persistent-data.js +158 -0
  135. package/dist/kubernetes/get-service-ip.js +11 -0
  136. package/dist/kubernetes/kubernetes-instance.js +48 -0
  137. package/dist/kubernetes/remove-persistent-data.js +19 -0
  138. package/dist/kubernetes/resolve-pod-name.js +42 -0
  139. package/dist/kubernetes/resolve-pod-name.spec.js +81 -0
  140. package/dist/kubernetes/resources.js +12 -0
  141. package/dist/kubernetes/restore-kubernetes-data.js +42 -0
  142. package/dist/kubernetes/store-kubernetes-data.js +39 -0
  143. package/dist/kubernetes/volumes.js +64 -0
  144. package/dist/log.js +69 -69
  145. package/dist/log.spec.js +131 -0
  146. package/dist/logging/grouped-logger.js +17 -15
  147. package/dist/logging/grouped-logger.spec.js +84 -0
  148. package/dist/logging/interactive-logger.js +1 -1
  149. package/dist/logging/interactive-logger.spec.js +57 -0
  150. package/dist/logging/live-logger.js +2 -2
  151. package/dist/logging/live-logger.spec.js +37 -0
  152. package/dist/logging/loggers.spec.js +154 -0
  153. package/dist/optimizer/calculate-checksum.spec.js +34 -0
  154. package/dist/optimizer/get-cache-directory.js +6 -6
  155. package/dist/optimizer/get-cache-directory.spec.js +59 -0
  156. package/dist/optimizer/get-work-cache-stats.js +53 -0
  157. package/dist/optimizer/get-work-cache-stats.spec.js +79 -0
  158. package/dist/{parser/build-file-task.js → optimizer/work-cache-stats.js} +1 -1
  159. package/dist/optimizer/work-task-cache-description.js +25 -0
  160. package/dist/optimizer/work-task-cache-description.spec.js +45 -0
  161. package/dist/parser/default-build-file.js +14 -7
  162. package/dist/parser/default-build-file.spec.js +48 -0
  163. package/dist/parser/parse-label-arguments.spec.js +27 -0
  164. package/dist/parser/read-build-file.js +2 -13
  165. package/dist/parser/read-build-file.spec.js +89 -0
  166. package/dist/parser/read-env-file.js +4 -5
  167. package/dist/parser/read-env-file.spec.js +42 -0
  168. package/dist/planner/utils/append-work-dependencies.js +55 -0
  169. package/dist/planner/utils/append-work-environment.js +22 -0
  170. package/dist/planner/utils/append-work-needs.js +18 -0
  171. package/dist/planner/utils/append-work-service.js +107 -0
  172. package/dist/planner/utils/append-work-service.spec.js +71 -0
  173. package/dist/planner/utils/append-work-task.js +81 -0
  174. package/dist/planner/utils/get-container-user.js +14 -0
  175. package/dist/planner/utils/get-container-user.spec.js +30 -0
  176. package/dist/planner/utils/get-default-kube-config.js +10 -0
  177. package/dist/planner/utils/get-default-kube-config.spec.js +11 -0
  178. package/dist/planner/utils/get-work-runtime.js +44 -0
  179. package/dist/planner/utils/normalize-path.js +1 -1
  180. package/dist/planner/utils/normalize-path.spec.js +24 -0
  181. package/dist/planner/utils/parse-work-command.js +80 -0
  182. package/dist/planner/utils/parse-work-command.spec.js +21 -0
  183. package/dist/planner/utils/parse-work-generate.js +38 -0
  184. package/dist/planner/utils/parse-work-generate.spec.js +45 -0
  185. package/dist/planner/utils/{parse-work-node-mount.js → parse-work-mount.js} +10 -7
  186. package/dist/planner/utils/{parse-work-node-mount.spec.js → parse-work-mount.spec.js} +14 -11
  187. package/dist/planner/utils/parse-work-mounts.js +13 -0
  188. package/dist/planner/utils/parse-work-mounts.spec.js +19 -0
  189. package/dist/planner/utils/{parse-work-node-port.js → parse-work-port.js} +11 -8
  190. package/dist/planner/utils/parse-work-port.spec.js +24 -0
  191. package/dist/planner/utils/parse-work-ports.js +10 -0
  192. package/dist/planner/utils/parse-work-ports.spec.js +24 -0
  193. package/dist/planner/utils/parse-work-source.js +72 -0
  194. package/dist/planner/utils/parse-work-source.spec.js +58 -0
  195. package/dist/planner/utils/parse-work-volume.js +45 -0
  196. package/dist/planner/utils/parse-work-volume.spec.js +18 -0
  197. package/dist/planner/utils/plan-work-tasks.js +41 -0
  198. package/dist/planner/utils/plan-work-tasks.spec.js +30 -0
  199. package/dist/planner/utils/plan-work-volume.js +1 -0
  200. package/dist/planner/utils/plan-work-volume.spec.js +33 -0
  201. package/dist/planner/utils/split-name.js +2 -2
  202. package/dist/planner/utils/split-name.spec.js +16 -0
  203. package/dist/planner/utils/template-value.js +1 -2
  204. package/dist/planner/utils/template-value.spec.js +14 -0
  205. package/dist/planner/validate.js +71 -38
  206. package/dist/planner/validate.spec.js +251 -0
  207. package/dist/planner/work-cache-id.js +12 -0
  208. package/dist/planner/work-cache-id.spec.js +173 -0
  209. package/dist/planner/work-command.js +3 -0
  210. package/dist/planner/work-environment.js +3 -0
  211. package/dist/planner/work-healthcheck.js +3 -0
  212. package/dist/planner/{work-node-status.js → work-item-status.js} +16 -62
  213. package/dist/{parser/build-file-service.js → planner/work-item-validation.js} +1 -1
  214. package/dist/planner/work-item.js +16 -0
  215. package/dist/{optimizer/work-node-cache-stats.js → planner/work-kubernetes-selector.js} +1 -1
  216. package/dist/planner/{work-nodes.js → work-port.js} +1 -1
  217. package/dist/planner/work-runtime-docker.js +224 -0
  218. package/dist/planner/work-runtime-kubernetes.js +264 -0
  219. package/dist/planner/work-runtime-local.js +109 -0
  220. package/dist/planner/work-runtime-local.spec.js +193 -0
  221. package/dist/planner/work-service-id.js +15 -5
  222. package/dist/planner/work-source.js +3 -0
  223. package/dist/planner/work-task.js +8 -0
  224. package/dist/program-commands.spec.js +84 -0
  225. package/dist/program.js +219 -73
  226. package/dist/program.spec.js +34 -11
  227. package/dist/run-program.js +28 -0
  228. package/dist/{executer/process.js → runtime/runtime.js} +1 -1
  229. package/dist/schema/build-file-base-task-schema.js +27 -0
  230. package/dist/schema/build-file-container-service-schema.js +28 -0
  231. package/dist/schema/build-file-container-task-schema.js +13 -0
  232. package/dist/schema/build-file-environment-schema-ingress.js +14 -0
  233. package/dist/schema/build-file-environment-schema.js +23 -0
  234. package/dist/schema/build-file-kubernetes-service-schema.js +17 -0
  235. package/dist/schema/build-file-kubernetes-service-selector-schema.js +9 -0
  236. package/dist/schema/build-file-local-platform-schema.js +9 -0
  237. package/dist/schema/build-file-local-task-schema.js +12 -0
  238. package/dist/schema/build-file-need-schema.js +12 -0
  239. package/dist/schema/build-file-schema.js +23 -0
  240. package/dist/schema/build-file-schema.spec.js +61 -0
  241. package/dist/schema/build-file-service-container-healthcheck.js +8 -0
  242. package/dist/schema/build-file-service-schema.js +15 -0
  243. package/dist/schema/build-file-task-command-schema.js +12 -0
  244. package/dist/schema/build-file-task-schema.js +12 -0
  245. package/dist/schema/build-file-volume-schema.js +14 -0
  246. package/dist/schema/cache-schema.js +31 -0
  247. package/dist/schema/doc-build-files.spec.js +223 -0
  248. package/dist/schema/envs-schema.js +6 -0
  249. package/dist/schema/labels-schema.js +6 -0
  250. package/dist/schema/parse-context.js +3 -0
  251. package/dist/schema/parse-error.js +12 -0
  252. package/dist/schema/parse-error.spec.js +18 -0
  253. package/dist/schema/reference-parser.js +209 -0
  254. package/dist/schema/reference-parser.spec.js +83 -0
  255. package/dist/schema/schema-parser.js +66 -0
  256. package/dist/schema/schema-parser.spec.js +80 -0
  257. package/dist/schema/type-guards.spec.js +23 -0
  258. package/dist/schema/work-scope-parser.js +77 -0
  259. package/dist/schema/work-scope-parser.spec.js +66 -0
  260. package/dist/service/update-service-status.js +11 -0
  261. package/dist/service/update-service-status.spec.js +27 -0
  262. package/dist/testing/ensure-local-registry.js +134 -0
  263. package/dist/testing/example-test-suite.js +16 -18
  264. package/dist/testing/expect.js +46 -22
  265. package/dist/testing/http-get.js +21 -0
  266. package/dist/testing/integration/cache.spec.js +13 -14
  267. package/dist/testing/integration/cancellation.spec.js +14 -9
  268. package/dist/testing/integration/clean.spec.js +14 -11
  269. package/dist/testing/integration/cmd.spec.js +1 -1
  270. package/dist/testing/integration/concurrency.spec.js +3 -3
  271. package/dist/testing/integration/docker-package-registry.spec.js +44 -0
  272. package/dist/testing/integration/docker-service-crash.spec.js +36 -0
  273. package/dist/testing/integration/docker.spec.js +4 -3
  274. package/dist/testing/integration/env.spec.js +9 -8
  275. package/dist/testing/integration/environment.spec.js +97 -0
  276. package/dist/testing/integration/error.spec.js +5 -4
  277. package/dist/testing/integration/export.spec.js +22 -0
  278. package/dist/testing/integration/extend.spec.js +9 -12
  279. package/dist/testing/integration/glob.spec.js +12 -20
  280. package/dist/testing/integration/include.spec.js +3 -3
  281. package/dist/testing/integration/invalid.spec.js +2 -3
  282. package/dist/testing/integration/invalid_loop.spec.js +49 -6
  283. package/dist/testing/integration/k8s-state-cache.spec.js +41 -0
  284. package/dist/testing/integration/kubernetes-service.spec.js +148 -0
  285. package/dist/testing/integration/kubernetes.spec.js +93 -9
  286. package/dist/testing/integration/labels.spec.js +6 -11
  287. package/dist/testing/integration/local.spec.js +1 -1
  288. package/dist/testing/integration/monorepo.spec.js +4 -4
  289. package/dist/testing/integration/multi-line.spec.js +3 -3
  290. package/dist/testing/integration/reference.spec.js +4 -5
  291. package/dist/testing/integration/services.spec.js +22 -4
  292. package/dist/testing/integration/store.spec.js +15 -16
  293. package/dist/testing/integration/unknown.spec.js +20 -18
  294. package/dist/testing/integration/validate.spec.js +143 -26
  295. package/dist/testing/integration/watch-dependency.spec.js +11 -8
  296. package/dist/testing/integration/watch.spec.js +15 -16
  297. package/dist/testing/requires-kubernetes.js +18 -0
  298. package/dist/testing/requires-linux-containers.js +18 -0
  299. package/dist/testing/requires-windows-containers.js +18 -0
  300. package/dist/testing/test-case.js +75 -0
  301. package/dist/testing/test-streams.js +28 -0
  302. package/dist/testing/testing-timeout.js +32 -0
  303. package/dist/utils/abort-event.js +10 -4
  304. package/dist/utils/abort-event.spec.js +46 -0
  305. package/dist/utils/buffer-context.js +44 -0
  306. package/dist/utils/buffer-context.spec.js +38 -0
  307. package/dist/utils/ci.spec.js +53 -0
  308. package/dist/utils/emitter.spec.js +34 -0
  309. package/dist/utils/empty-writable.spec.js +18 -0
  310. package/dist/utils/environment-config.js +4 -1
  311. package/dist/utils/environment-config.spec.js +26 -0
  312. package/dist/utils/fail-never.spec.js +9 -0
  313. package/dist/version.js +9 -0
  314. package/dist/version.spec.js +12 -0
  315. package/package.json +41 -23
  316. package/specs/build-file/caches/spec.md +114 -0
  317. package/specs/build-file/environment-variables/spec.md +82 -0
  318. package/specs/build-file/includes/spec.md +60 -0
  319. package/specs/build-file/references/spec.md +56 -0
  320. package/specs/build-file/spec.md +62 -0
  321. package/specs/cli/clean/spec.md +85 -0
  322. package/specs/cli/down/spec.md +85 -0
  323. package/specs/cli/execute/spec.md +101 -0
  324. package/specs/cli/init/spec.md +64 -0
  325. package/specs/cli/ls/spec.md +66 -0
  326. package/specs/cli/package/spec.md +110 -0
  327. package/specs/cli/spec.md +73 -0
  328. package/specs/cli/store-restore/spec.md +74 -0
  329. package/specs/cli/up/spec.md +80 -0
  330. package/specs/cli/validate/spec.md +70 -0
  331. package/specs/labels/spec.md +91 -0
  332. package/specs/service/container/spec.md +120 -0
  333. package/specs/service/kubernetes/spec.md +97 -0
  334. package/specs/service/spec.md +105 -0
  335. package/specs/task/caching/spec.md +107 -0
  336. package/specs/task/container/spec.md +118 -0
  337. package/specs/task/dependencies/spec.md +70 -0
  338. package/specs/task/extending/spec.md +74 -0
  339. package/specs/task/kubernetes/spec.md +125 -0
  340. package/specs/task/needs/spec.md +59 -0
  341. package/specs/task/spec.md +87 -0
  342. package/specs/task/watching/spec.md +69 -0
  343. package/dist/console/console-context-mock.js +0 -14
  344. package/dist/environment/get-process-env.js +0 -15
  345. package/dist/executer/create-scheduler-state.js +0 -32
  346. package/dist/executer/docker-node.js +0 -123
  347. package/dist/executer/hierarchy-scheduler.js +0 -94
  348. package/dist/executer/local-node.js +0 -57
  349. package/dist/executer/schedule.js +0 -137
  350. package/dist/executer/start-node.js +0 -67
  351. package/dist/executer/watch-node.js +0 -56
  352. package/dist/executer/watch-service.js +0 -54
  353. package/dist/file/get-file-context-mock.js +0 -187
  354. package/dist/file/get-file-context-mock.spec.js +0 -56
  355. package/dist/get-work-context.js +0 -29
  356. package/dist/optimizer/get-work-node-cache-stats.js +0 -104
  357. package/dist/optimizer/read-work-node-cache.js +0 -19
  358. package/dist/optimizer/work-node-cache-description.js +0 -32
  359. package/dist/optimizer/write-work-node-cache.js +0 -21
  360. package/dist/parser/build-file-task-command.js +0 -3
  361. package/dist/parser/build-file-task-platform.js +0 -3
  362. package/dist/parser/build-file-task-source.js +0 -3
  363. package/dist/parser/get-build-file.js +0 -9
  364. package/dist/parser/parse-boolean.js +0 -29
  365. package/dist/parser/parse-boolean.spec.js +0 -48
  366. package/dist/parser/parse-build-file-references.js +0 -35
  367. package/dist/parser/parse-build-file-services.js +0 -58
  368. package/dist/parser/parse-build-file-task-command.js +0 -36
  369. package/dist/parser/parse-build-file-task-source.js +0 -63
  370. package/dist/parser/parse-build-file.js +0 -125
  371. package/dist/parser/parse-context.js +0 -13
  372. package/dist/parser/parse-envs.js +0 -29
  373. package/dist/parser/parse-healthcheck.js +0 -28
  374. package/dist/parser/parse-service-selector.js +0 -39
  375. package/dist/parser/parse-string-array.js +0 -20
  376. package/dist/parser/parse-string-map.js +0 -30
  377. package/dist/parser/parse-string.js +0 -20
  378. package/dist/planner/utils/get-container-mounts.js +0 -24
  379. package/dist/planner/utils/parse-work-service-volume.js +0 -23
  380. package/dist/planner/utils/plan-work-command.js +0 -21
  381. package/dist/planner/utils/plan-work-dependency.js +0 -36
  382. package/dist/planner/utils/plan-work-node.js +0 -293
  383. package/dist/planner/utils/plan-work-nodes.js +0 -78
  384. package/dist/planner/utils/plan-work-tree.js +0 -15
  385. package/dist/planner/work-context.js +0 -23
  386. package/dist/planner/work-node-command.js +0 -3
  387. package/dist/planner/work-node-id.js +0 -12
  388. package/dist/planner/work-node-id.spec.js +0 -106
  389. package/dist/planner/work-node-path.js +0 -2
  390. package/dist/planner/work-node-source.js +0 -3
  391. package/dist/planner/work-node-validation.js +0 -3
  392. package/dist/planner/work-node.js +0 -8
  393. package/dist/planner/work-service-volume.js +0 -3
  394. package/dist/planner/work-services.js +0 -3
  395. package/dist/start-watch-processes.js +0 -28
  396. package/dist/testing/cli.js +0 -73
  397. package/dist/testing/create-build-file.js +0 -9
  398. package/dist/testing/get-logger.js +0 -23
  399. package/dist/testing/get-node.js +0 -12
  400. package/dist/testing/get-test-context.js +0 -19
  401. package/dist/testing/integration/program.spec.js +0 -25
  402. package/dist/testing/lazy.js +0 -17
  403. package/dist/testing/start-watch-processes.js +0 -29
  404. package/dist/testing/test-suite-options.js +0 -3
  405. package/dist/utils/abortable-function.js +0 -71
  406. package/logs/cache-console.log +0 -0
  407. package/logs/cache-status.log +0 -6
  408. package/logs/cache-stout.log +0 -0
  409. package/logs/cancellation-console.log +0 -0
  410. package/logs/cancellation-status.log +0 -3
  411. package/logs/cancellation-stout.log +0 -3
  412. package/logs/clean-console.log +0 -0
  413. package/logs/clean-status.log +0 -37
  414. package/logs/clean-stout.log +0 -95
  415. package/logs/cmd-console.log +0 -0
  416. package/logs/cmd-status.log +0 -8
  417. package/logs/cmd-stout.log +0 -9
  418. package/logs/concurrency-console.log +0 -0
  419. package/logs/concurrency-status.log +0 -14
  420. package/logs/concurrency-stout.log +0 -88
  421. package/logs/docker-console.log +0 -0
  422. package/logs/docker-status.log +0 -14
  423. package/logs/docker-stout.log +0 -39
  424. package/logs/env-console.log +0 -1
  425. package/logs/env-status.log +0 -1
  426. package/logs/env-stout.log +0 -0
  427. package/logs/error-console.log +0 -0
  428. package/logs/error-status.log +0 -10
  429. package/logs/error-stout.log +0 -36
  430. package/logs/extend-console.log +0 -0
  431. package/logs/extend-status.log +0 -1
  432. package/logs/extend-stout.log +0 -0
  433. package/logs/glob-console.log +0 -28
  434. package/logs/glob-status.log +0 -23
  435. package/logs/glob-stout.log +0 -52
  436. package/logs/hello-world-node-console.log +0 -0
  437. package/logs/hello-world-node-status.log +0 -37
  438. package/logs/hello-world-node-stout.log +0 -41
  439. package/logs/include-console.log +0 -0
  440. package/logs/include-status.log +0 -3
  441. package/logs/include-stout.log +0 -0
  442. package/logs/invalid-console.log +0 -0
  443. package/logs/invalid-status.log +0 -1
  444. package/logs/invalid-stout.log +0 -0
  445. package/logs/invalid_loop-console.log +0 -0
  446. package/logs/invalid_loop-status.log +0 -1
  447. package/logs/invalid_loop-stout.log +0 -11
  448. package/logs/labels-console.log +0 -0
  449. package/logs/labels-status.log +0 -1
  450. package/logs/labels-stout.log +0 -0
  451. package/logs/local-console.log +0 -0
  452. package/logs/local-status.log +0 -7
  453. package/logs/local-stout.log +0 -8
  454. package/logs/monorepo-console.log +0 -0
  455. package/logs/monorepo-status.log +0 -152
  456. package/logs/monorepo-stout.log +0 -2354
  457. package/logs/multi-line-console.log +0 -0
  458. package/logs/multi-line-status.log +0 -1
  459. package/logs/multi-line-stout.log +0 -0
  460. package/logs/reference-console.log +0 -0
  461. package/logs/reference-status.log +0 -5
  462. package/logs/reference-stout.log +0 -0
  463. package/logs/services-console.log +0 -0
  464. package/logs/services-status.log +0 -129
  465. package/logs/services-stout.log +0 -639
  466. package/logs/store-restore-console.log +0 -0
  467. package/logs/store-restore-status.log +0 -40
  468. package/logs/store-restore-stout.log +0 -97
  469. package/logs/unknown-console.log +0 -3
  470. package/logs/unknown-status.log +0 -1
  471. package/logs/unknown-stout.log +0 -0
  472. package/logs/validate-console.log +0 -0
  473. package/logs/validate-status.log +0 -2
  474. package/logs/validate-stout.log +0 -0
  475. package/logs/watch-console.log +0 -0
  476. package/logs/watch-dependency-console.log +0 -0
  477. package/logs/watch-dependency-status.log +0 -176
  478. package/logs/watch-dependency-stout.log +0 -779
  479. package/logs/watch-status.log +0 -100
  480. package/logs/watch-stout.log +0 -349
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appendWorkService = void 0;
4
+ const work_service_id_1 = require("../work-service-id");
5
+ const parse_work_ports_1 = require("./parse-work-ports");
6
+ const template_value_1 = require("./template-value");
7
+ const build_file_service_schema_1 = require("../../schema/build-file-service-schema");
8
+ const get_default_kube_config_1 = require("./get-default-kube-config");
9
+ const parse_work_command_1 = require("./parse-work-command");
10
+ const parse_work_volume_1 = require("./parse-work-volume");
11
+ const parse_work_mounts_1 = require("./parse-work-mounts");
12
+ const parse_work_source_1 = require("./parse-work-source");
13
+ const append_work_dependencies_1 = require("./append-work-dependencies");
14
+ const append_work_needs_1 = require("./append-work-needs");
15
+ const replace_env_variables_1 = require("../../environment/replace-env-variables");
16
+ const state_1 = require("../../executer/state");
17
+ const lazy_resolver_1 = require("../../executer/lazy-resolver");
18
+ const get_work_runtime_1 = require("./get-work-runtime");
19
+ const resolve_cache_1 = require("../../cache/resolve-cache");
20
+ function appendWorkService(workTree, service, environment, context) {
21
+ const workService = parseService(workTree, service, environment, context);
22
+ if (!workTree.services[workService.name]) {
23
+ const workItem = {
24
+ id: (0, lazy_resolver_1.lazyResolver)(() => (0, work_service_id_1.getWorkServiceId)(workService)),
25
+ name: workService.name,
26
+ data: workService,
27
+ status: environment.status.from(workService),
28
+ deps: [],
29
+ needs: [],
30
+ requiredBy: [],
31
+ };
32
+ const workStateItem = {
33
+ ...workItem,
34
+ state: new state_1.State({
35
+ type: 'pending',
36
+ stateKey: null,
37
+ }),
38
+ runtime: (0, get_work_runtime_1.getWorkServiceRuntime)(workTree, workItem),
39
+ };
40
+ workTree.services[workItem.name] = workStateItem;
41
+ (0, append_work_dependencies_1.appendWorkDependencies)(workTree, service, workStateItem, environment, context);
42
+ (0, append_work_needs_1.appendWorkNeeds)(workTree, service, workStateItem, environment, context);
43
+ return workStateItem;
44
+ }
45
+ else {
46
+ return workTree.services[workService.name];
47
+ }
48
+ }
49
+ exports.appendWorkService = appendWorkService;
50
+ function parseService(workTree, service, environment, context) {
51
+ const envs = (0, replace_env_variables_1.buildEnvironmentVariables)(service.envs, environment, context);
52
+ const workService = {
53
+ cwd: service.cwd,
54
+ name: service.relativeName,
55
+ ports: (0, parse_work_ports_1.parseWorkPorts)(service.schema, envs),
56
+ scope: service.scope,
57
+ labels: service.labels,
58
+ description: (0, template_value_1.templateValue)(service.schema.description || '', envs),
59
+ };
60
+ const caching = (0, resolve_cache_1.resolveCache)(null, context.caches, service.relativeName);
61
+ if ((0, build_file_service_schema_1.isBuildFileKubernetesServiceSchema)(service.schema)) {
62
+ const k8sEnv = workTree.environment.type === 'kubernetes' ? workTree.environment : undefined;
63
+ const kubeconfig = service.schema.kubeconfig ?? k8sEnv?.kubeConfig ?? (0, get_default_kube_config_1.getDefaultKubeConfig)();
64
+ const serviceContext = service.schema.context ? (0, template_value_1.templateValue)(service.schema.context, envs) : k8sEnv?.context;
65
+ if (!serviceContext) {
66
+ throw new Error(`kubernetes service ${service.relativeName} has no context: set "context" on the service or select a ` +
67
+ `kubernetes environment (environments.<name>.kubernetes.context) with --env`);
68
+ }
69
+ const namespace = service.schema.namespace
70
+ ? (0, template_value_1.templateValue)(service.schema.namespace, envs)
71
+ : k8sEnv?.namespace ?? 'default';
72
+ return {
73
+ type: 'kubernetes-service',
74
+ ...workService,
75
+ kubeconfig,
76
+ namespace,
77
+ selector: {
78
+ name: (0, template_value_1.templateValue)(service.schema.selector.name, envs),
79
+ type: (0, template_value_1.templateValue)(service.schema.selector.type, envs),
80
+ },
81
+ context: serviceContext,
82
+ src: [(0, parse_work_source_1.createSource)(kubeconfig)],
83
+ caching,
84
+ };
85
+ }
86
+ else {
87
+ return {
88
+ ...workService,
89
+ type: 'container-service',
90
+ continuous: service.schema.continuous ?? false,
91
+ healthcheck: service.schema.healthcheck
92
+ ? {
93
+ cmd: (0, parse_work_command_1.parseWorkCommand)(service.cwd, service.schema.healthcheck, envs),
94
+ }
95
+ : null,
96
+ envs: (0, replace_env_variables_1.buildEnvironmentVariables)(service.envs, environment, context),
97
+ image: service.schema.image,
98
+ cwd: service.cwd,
99
+ cmd: service.schema.cmd ? (0, parse_work_command_1.parseWorkCommand)(service.cwd, service.schema.cmd, envs) : null,
100
+ volumes: (0, parse_work_volume_1.parseWorkVolumes)(service.cwd, service.schema.volumes, envs),
101
+ mounts: (0, parse_work_mounts_1.parseWorkMounts)(service.cwd, service.schema, envs),
102
+ src: (0, parse_work_source_1.parseWorkSource)(service.cwd, service.schema.src, envs),
103
+ caching,
104
+ };
105
+ }
106
+ }
107
+ //# sourceMappingURL=append-work-service.js.map
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path_1 = require("path");
4
+ const os_1 = require("os");
5
+ const fs_1 = require("fs");
6
+ const environment_mock_1 = require("../../executer/environment-mock");
7
+ const schema_parser_1 = require("../../schema/schema-parser");
8
+ const reference_parser_1 = require("../../schema/reference-parser");
9
+ const work_scope_parser_1 = require("../../schema/work-scope-parser");
10
+ describe('appendWorkService (kubernetes service env inheritance)', () => {
11
+ let scratch;
12
+ beforeEach(() => {
13
+ scratch = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-k8s-svc-'));
14
+ });
15
+ afterEach(() => {
16
+ (0, fs_1.rmSync)(scratch, { recursive: true, force: true });
17
+ });
18
+ async function parse(content, environmentName) {
19
+ const env = (0, environment_mock_1.environmentMock)(scratch);
20
+ const file = (0, path_1.join)(scratch, '.hammerkit.yaml');
21
+ (0, fs_1.writeFileSync)(file, content);
22
+ const { ctx, scope } = await (0, schema_parser_1.createParseContext)(file, env);
23
+ const referenced = await (0, reference_parser_1.parseReferences)(ctx, scope, env);
24
+ const workScope = { environmentName, filterLabels: {}, excludeLabels: {} };
25
+ return { referenced, env, workScope };
26
+ }
27
+ const envBlock = `environments:
28
+ prod:
29
+ kubernetes:
30
+ context: gke_prod
31
+ kubeconfig: ./prod-kube.yaml
32
+ namespace: databases
33
+ `;
34
+ function postgres(extra = '') {
35
+ return `services:
36
+ postgres:
37
+ ${extra} selector:
38
+ type: deployment
39
+ name: postgres
40
+ ports:
41
+ - 5432:5432
42
+ `;
43
+ }
44
+ it('inherits context, kubeconfig and namespace from the selected environment', async () => {
45
+ const { referenced, env, workScope } = await parse(envBlock + postgres(), 'prod');
46
+ const work = (0, work_scope_parser_1.getWorkContext)(referenced, workScope, env);
47
+ const service = work.services['postgres'].data;
48
+ expect(service.type).toEqual('kubernetes-service');
49
+ expect(service.context).toEqual('gke_prod');
50
+ expect(service.kubeconfig).toEqual('./prod-kube.yaml');
51
+ expect(service.namespace).toEqual('databases');
52
+ });
53
+ it('lets a service override the namespace while inheriting the context', async () => {
54
+ const { referenced, env, workScope } = await parse(envBlock + postgres(' namespace: orders\n'), 'prod');
55
+ const work = (0, work_scope_parser_1.getWorkContext)(referenced, workScope, env);
56
+ const service = work.services['postgres'].data;
57
+ expect(service.namespace).toEqual('orders');
58
+ expect(service.context).toEqual('gke_prod');
59
+ });
60
+ it('keeps an explicit service context over the environment (backward compatible)', async () => {
61
+ const { referenced, env, workScope } = await parse(envBlock + postgres(' context: own-ctx\n'), 'prod');
62
+ const work = (0, work_scope_parser_1.getWorkContext)(referenced, workScope, env);
63
+ const service = work.services['postgres'].data;
64
+ expect(service.context).toEqual('own-ctx');
65
+ });
66
+ it('throws a descriptive error when no context can be resolved', async () => {
67
+ const { referenced, env, workScope } = await parse(postgres(), null);
68
+ expect(() => (0, work_scope_parser_1.getWorkContext)(referenced, workScope, env)).toThrow(/postgres has no context/);
69
+ });
70
+ });
71
+ //# sourceMappingURL=append-work-service.spec.js.map
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appendWorkTask = void 0;
4
+ const parse_work_generate_1 = require("./parse-work-generate");
5
+ const template_value_1 = require("./template-value");
6
+ const parse_work_mounts_1 = require("./parse-work-mounts");
7
+ const get_container_user_1 = require("./get-container-user");
8
+ const build_file_task_schema_1 = require("../../schema/build-file-task-schema");
9
+ const parse_work_command_1 = require("./parse-work-command");
10
+ const parse_work_source_1 = require("./parse-work-source");
11
+ const work_cache_id_1 = require("../work-cache-id");
12
+ const append_work_dependencies_1 = require("./append-work-dependencies");
13
+ const append_work_needs_1 = require("./append-work-needs");
14
+ const state_1 = require("../../executer/state");
15
+ const replace_env_variables_1 = require("../../environment/replace-env-variables");
16
+ const lazy_resolver_1 = require("../../executer/lazy-resolver");
17
+ const get_work_runtime_1 = require("./get-work-runtime");
18
+ const resolve_cache_1 = require("../../cache/resolve-cache");
19
+ function appendWorkTask(workTree, cwd, referenceTask, environment, context) {
20
+ const task = parseTask(cwd, referenceTask, environment, context);
21
+ if (!workTree.tasks[task.name]) {
22
+ const workItem = {
23
+ id: (0, lazy_resolver_1.lazyResolver)(() => (0, work_cache_id_1.getWorkTaskId)(task)),
24
+ name: task.name,
25
+ data: task,
26
+ status: environment.status.from(task),
27
+ needs: [],
28
+ deps: [],
29
+ requiredBy: [],
30
+ };
31
+ const workItemState = {
32
+ ...workItem,
33
+ state: new state_1.State({
34
+ type: 'pending',
35
+ stateKey: null,
36
+ }),
37
+ runtime: (0, get_work_runtime_1.getWorkTaskRuntime)(workTree, workItem),
38
+ };
39
+ workTree.tasks[task.name] = workItemState;
40
+ (0, append_work_dependencies_1.appendWorkDependencies)(workTree, referenceTask, workItemState, environment, context);
41
+ (0, append_work_needs_1.appendWorkNeeds)(workTree, referenceTask, workItemState, environment, context);
42
+ return workItemState;
43
+ }
44
+ else {
45
+ return workTree.tasks[task.name];
46
+ }
47
+ }
48
+ exports.appendWorkTask = appendWorkTask;
49
+ function parseTask(cwd, task, environment, context) {
50
+ const envs = (0, replace_env_variables_1.buildEnvironmentVariables)(task.envs, environment, context);
51
+ const baseWorkNode = {
52
+ envs,
53
+ description: (0, template_value_1.templateValue)(task.schema.description || '', envs).trim(),
54
+ name: task.relativeName,
55
+ cwd,
56
+ cmds: (0, parse_work_command_1.parseWorkCommands)(cwd, task.schema.cmds || [], envs),
57
+ src: (0, parse_work_source_1.parseWorkSource)(cwd, task.schema.src, envs),
58
+ generates: (0, parse_work_generate_1.parseWorkGenerate)(cwd, task.schema, envs),
59
+ scope: task.scope,
60
+ labels: task.labels,
61
+ caching: (0, resolve_cache_1.resolveCache)(task.schema.cache ?? null, context.caches, task.relativeName),
62
+ shell: task.schema.shell ? (0, template_value_1.templateValue)(task.schema.shell, envs) : '/bin/sh',
63
+ continuous: task.schema.continuous ?? false,
64
+ };
65
+ if ((0, build_file_task_schema_1.isBuildFileContainerTaskSchema)(task.schema)) {
66
+ return {
67
+ ...baseWorkNode,
68
+ type: 'container-task',
69
+ user: (0, get_container_user_1.getContainerUser)(),
70
+ image: (0, template_value_1.templateValue)(task.schema.image, envs),
71
+ mounts: (0, parse_work_mounts_1.parseWorkMounts)(cwd, task.schema, envs),
72
+ };
73
+ }
74
+ else {
75
+ return {
76
+ ...baseWorkNode,
77
+ type: 'local-task',
78
+ };
79
+ }
80
+ }
81
+ //# sourceMappingURL=append-work-task.js.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getContainerUser = void 0;
4
+ const os_1 = require("os");
5
+ function getContainerUser() {
6
+ return ((0, os_1.platform)() === 'linux' || (0, os_1.platform)() === 'freebsd' || (0, os_1.platform)() === 'openbsd' || (0, os_1.platform)() === 'sunos') &&
7
+ !!process &&
8
+ !!process.getuid &&
9
+ !!process.getgid
10
+ ? `${process.getuid()}:${process.getgid()}`
11
+ : null;
12
+ }
13
+ exports.getContainerUser = getContainerUser;
14
+ //# sourceMappingURL=get-container-user.js.map
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ vi.mock('os', async () => ({ ...(await vi.importActual('os')), platform: vi.fn() }));
4
+ const os_1 = require("os");
5
+ const get_container_user_1 = require("./get-container-user");
6
+ const mockedPlatform = os_1.platform;
7
+ describe('getContainerUser', () => {
8
+ const originalGetuid = process.getuid;
9
+ const originalGetgid = process.getgid;
10
+ beforeEach(() => {
11
+ Object.assign(process, { getuid: () => 1234, getgid: () => 4321 });
12
+ });
13
+ afterEach(() => {
14
+ Object.assign(process, { getuid: originalGetuid, getgid: originalGetgid });
15
+ });
16
+ it.each(['linux', 'freebsd', 'openbsd', 'sunos'])('returns uid:gid on %s', (p) => {
17
+ mockedPlatform.mockReturnValue(p);
18
+ expect((0, get_container_user_1.getContainerUser)()).toBe('1234:4321');
19
+ });
20
+ it.each(['darwin', 'win32'])('returns null on %s', (p) => {
21
+ mockedPlatform.mockReturnValue(p);
22
+ expect((0, get_container_user_1.getContainerUser)()).toBeNull();
23
+ });
24
+ it('returns null on a unix platform when process.getuid is unavailable', () => {
25
+ mockedPlatform.mockReturnValue('linux');
26
+ process.getuid = undefined;
27
+ expect((0, get_container_user_1.getContainerUser)()).toBeNull();
28
+ });
29
+ });
30
+ //# sourceMappingURL=get-container-user.spec.js.map
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDefaultKubeConfig = void 0;
4
+ const path_1 = require("path");
5
+ const os_1 = require("os");
6
+ function getDefaultKubeConfig() {
7
+ return (0, path_1.join)((0, os_1.homedir)(), '.kube/config');
8
+ }
9
+ exports.getDefaultKubeConfig = getDefaultKubeConfig;
10
+ //# sourceMappingURL=get-default-kube-config.js.map
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const os_1 = require("os");
4
+ const path_1 = require("path");
5
+ const get_default_kube_config_1 = require("./get-default-kube-config");
6
+ describe('getDefaultKubeConfig', () => {
7
+ it('returns ~/.kube/config', () => {
8
+ expect((0, get_default_kube_config_1.getDefaultKubeConfig)()).toBe((0, path_1.join)((0, os_1.homedir)(), '.kube/config'));
9
+ });
10
+ });
11
+ //# sourceMappingURL=get-default-kube-config.spec.js.map
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWorkTaskRuntime = exports.getWorkServiceRuntime = void 0;
4
+ const work_runtime_docker_1 = require("../work-runtime-docker");
5
+ const work_runtime_kubernetes_1 = require("../work-runtime-kubernetes");
6
+ const work_runtime_local_1 = require("../work-runtime-local");
7
+ const work_item_1 = require("../work-item");
8
+ function getWorkServiceRuntime(workTree, service) {
9
+ if ((0, work_item_1.isContainerWorkServiceItem)(service)) {
10
+ if (workTree.environment.type === 'kubernetes') {
11
+ return (0, work_runtime_kubernetes_1.kubernetesServiceRuntime)(service, workTree.environment);
12
+ }
13
+ else {
14
+ return (0, work_runtime_docker_1.dockerServiceRuntime)(service, workTree.environment);
15
+ }
16
+ }
17
+ else if ((0, work_item_1.isKubernetesWorkServiceItem)(service)) {
18
+ return (0, work_runtime_kubernetes_1.kubernetesForwardRuntime)(service);
19
+ }
20
+ else {
21
+ // TODO ensure else case is type safe
22
+ throw new Error(`unknown service runtime`);
23
+ }
24
+ }
25
+ exports.getWorkServiceRuntime = getWorkServiceRuntime;
26
+ function getWorkTaskRuntime(workTree, task) {
27
+ if ((0, work_item_1.isLocalWorkTaskItem)(task)) {
28
+ return (0, work_runtime_local_1.getLocalWorkRuntime)(task);
29
+ }
30
+ else if ((0, work_item_1.isContainerWorkTaskItem)(task)) {
31
+ if (workTree.environment.type === 'kubernetes') {
32
+ return (0, work_runtime_kubernetes_1.kubernetesTaskRuntime)(task, workTree.environment);
33
+ }
34
+ else {
35
+ return (0, work_runtime_docker_1.dockerTaskRuntime)(task, workTree.environment);
36
+ }
37
+ }
38
+ else {
39
+ // TODO ensure else case is type safe
40
+ throw new Error(`unknown service runtime`);
41
+ }
42
+ }
43
+ exports.getWorkTaskRuntime = getWorkTaskRuntime;
44
+ //# sourceMappingURL=get-work-runtime.js.map
@@ -7,7 +7,7 @@ function normalizePath(cwd, pwd, path) {
7
7
  return path;
8
8
  }
9
9
  else if (path.startsWith('$PWD')) {
10
- return (0, path_1.join)(pwd, path.substr('$PWD'.length));
10
+ return (0, path_1.join)(pwd, path.substring('$PWD'.length));
11
11
  }
12
12
  else {
13
13
  return (0, path_1.join)(cwd, path);
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const normalize_path_1 = require("./normalize-path");
4
+ const path_1 = require("path");
5
+ // normalizePath uses the platform-native path.join, so expectations must use
6
+ // the native separator too. Mirrors the helper in parse-work-mount.spec.ts.
7
+ function toNative(val) {
8
+ return val.split(path_1.posix.sep).join(path_1.sep);
9
+ }
10
+ describe('normalize-path', () => {
11
+ it('should append src to cwd', () => {
12
+ const result = (0, normalize_path_1.normalizePath)('/home/user/proj', '/home/user', 'src');
13
+ expect(result).toEqual(toNative('/home/user/proj/src'));
14
+ });
15
+ it('should append .kube to pwd', () => {
16
+ const result = (0, normalize_path_1.normalizePath)('/home/user/proj', '/home/user', '$PWD/.kube');
17
+ expect(result).toEqual(toNative('/home/user/.kube'));
18
+ });
19
+ it('should append nothing to /usr/bin', () => {
20
+ const result = (0, normalize_path_1.normalizePath)('/home/user/proj', '/home/user', '/usr/bin');
21
+ expect(result).toEqual('/usr/bin');
22
+ });
23
+ });
24
+ //# sourceMappingURL=normalize-path.spec.js.map
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tokenizeCommand = exports.parseWorkCommand = exports.parseWorkCommands = void 0;
4
+ const path_1 = require("path");
5
+ const template_value_1 = require("./template-value");
6
+ function parseWorkCommands(cwd, cmds, envs) {
7
+ return cmds.map((cmd) => parseWorkCommand(cwd, cmd, envs));
8
+ }
9
+ exports.parseWorkCommands = parseWorkCommands;
10
+ function parseWorkCommand(cwd, cmd, envs) {
11
+ if (typeof cmd === 'string') {
12
+ return {
13
+ cwd,
14
+ ...parseCommand(cmd),
15
+ };
16
+ }
17
+ else {
18
+ return {
19
+ cwd: cmd.path ? (0, path_1.join)(cwd, (0, template_value_1.templateValue)(cmd.path, envs)) : cwd,
20
+ ...parseCommand(cmd.cmd),
21
+ };
22
+ }
23
+ }
24
+ exports.parseWorkCommand = parseWorkCommand;
25
+ function parseCommand(cmd) {
26
+ const tokens = tokenizeCommand(cmd);
27
+ return {
28
+ parsed: {
29
+ command: tokens[0] ?? '',
30
+ args: tokens.slice(1),
31
+ },
32
+ cmd: cmd.trim(),
33
+ };
34
+ }
35
+ /**
36
+ * Split a command line into tokens the way a shell roughly would: whitespace
37
+ * separates arguments, but single/double quotes group one argument and are
38
+ * stripped. Needed because the parsed command/args feed exec-form targets
39
+ * (docker `Cmd`, k8s job args, the packaged image's `CMD [...]`), where a naive
40
+ * `split(' ')` turns `sh -c "echo hi && sleep 1"` into broken tokens like
41
+ * `"echo`, `hi`, `1"`. The raw `cmd` string is kept untouched for shell-form
42
+ * use (e.g. Dockerfile `RUN`).
43
+ */
44
+ function tokenizeCommand(cmd) {
45
+ const tokens = [];
46
+ let current = '';
47
+ let inToken = false;
48
+ let quote = null;
49
+ for (const ch of cmd.trim()) {
50
+ if (quote) {
51
+ if (ch === quote) {
52
+ quote = null;
53
+ }
54
+ else {
55
+ current += ch;
56
+ }
57
+ }
58
+ else if (ch === '"' || ch === "'") {
59
+ quote = ch;
60
+ inToken = true;
61
+ }
62
+ else if (ch === ' ' || ch === '\t') {
63
+ if (inToken) {
64
+ tokens.push(current);
65
+ current = '';
66
+ inToken = false;
67
+ }
68
+ }
69
+ else {
70
+ current += ch;
71
+ inToken = true;
72
+ }
73
+ }
74
+ if (inToken) {
75
+ tokens.push(current);
76
+ }
77
+ return tokens;
78
+ }
79
+ exports.tokenizeCommand = tokenizeCommand;
80
+ //# sourceMappingURL=parse-work-command.js.map
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const parse_work_command_1 = require("./parse-work-command");
4
+ describe('tokenizeCommand', () => {
5
+ it('splits a plain command on whitespace', () => {
6
+ expect((0, parse_work_command_1.tokenizeCommand)('node server.js')).toEqual(['node', 'server.js']);
7
+ });
8
+ it('keeps a double-quoted argument as one token and strips the quotes', () => {
9
+ expect((0, parse_work_command_1.tokenizeCommand)('sh -c "echo hi && sleep 3600"')).toEqual(['sh', '-c', 'echo hi && sleep 3600']);
10
+ });
11
+ it('handles single quotes', () => {
12
+ expect((0, parse_work_command_1.tokenizeCommand)("sh -c 'echo hi'")).toEqual(['sh', '-c', 'echo hi']);
13
+ });
14
+ it('collapses repeated whitespace instead of emitting empty tokens', () => {
15
+ expect((0, parse_work_command_1.tokenizeCommand)('a b\tc')).toEqual(['a', 'b', 'c']);
16
+ });
17
+ it('returns an empty list for a blank command', () => {
18
+ expect((0, parse_work_command_1.tokenizeCommand)(' ')).toEqual([]);
19
+ });
20
+ });
21
+ //# sourceMappingURL=parse-work-command.spec.js.map
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapGenerate = exports.parseWorkGenerate = void 0;
4
+ const path_1 = require("path");
5
+ const template_value_1 = require("./template-value");
6
+ const plan_work_volume_1 = require("./plan-work-volume");
7
+ function parseWorkGenerate(cwd, schema, envs) {
8
+ if (!schema.generates) {
9
+ return [];
10
+ }
11
+ return schema.generates.map((g) => {
12
+ const generate = mapGenerate(g);
13
+ const filePath = (0, path_1.join)(cwd, (0, template_value_1.templateValue)(generate.path, envs));
14
+ return {
15
+ path: filePath,
16
+ volumeName: (0, plan_work_volume_1.getVolumeName)(filePath),
17
+ resetOnChange: generate.resetOnChange,
18
+ export: generate.export,
19
+ isFile: (0, path_1.extname)(generate.path).length > 1,
20
+ inherited: null,
21
+ };
22
+ });
23
+ }
24
+ exports.parseWorkGenerate = parseWorkGenerate;
25
+ function mapGenerate(generate) {
26
+ if (typeof generate === 'string') {
27
+ return { path: generate, resetOnChange: false, export: false };
28
+ }
29
+ else {
30
+ return {
31
+ path: generate.path,
32
+ resetOnChange: generate.resetOnChange ?? false,
33
+ export: generate.export ?? false,
34
+ };
35
+ }
36
+ }
37
+ exports.mapGenerate = mapGenerate;
38
+ //# sourceMappingURL=parse-work-generate.js.map
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const path_1 = require("path");
4
+ const parse_work_generate_1 = require("./parse-work-generate");
5
+ const plan_work_volume_1 = require("./plan-work-volume");
6
+ const noEnvs = { variables: {}, replacements: [] };
7
+ describe('mapGenerate', () => {
8
+ it('treats a bare string as path with defaults', () => {
9
+ expect((0, parse_work_generate_1.mapGenerate)('dist')).toEqual({ path: 'dist', resetOnChange: false, export: false });
10
+ });
11
+ it('preserves resetOnChange and export from an object', () => {
12
+ expect((0, parse_work_generate_1.mapGenerate)({ path: 'out', resetOnChange: true, export: true })).toEqual({
13
+ path: 'out',
14
+ resetOnChange: true,
15
+ export: true,
16
+ });
17
+ });
18
+ it('defaults resetOnChange and export to false when omitted', () => {
19
+ expect((0, parse_work_generate_1.mapGenerate)({ path: 'out' })).toEqual({ path: 'out', resetOnChange: false, export: false });
20
+ });
21
+ });
22
+ describe('parseWorkGenerate', () => {
23
+ it('returns [] when the task has no generates', () => {
24
+ expect((0, parse_work_generate_1.parseWorkGenerate)('/work', {}, noEnvs)).toEqual([]);
25
+ });
26
+ it('joins paths against cwd, templates env vars and marks files with an extension', () => {
27
+ const result = (0, parse_work_generate_1.parseWorkGenerate)('/work', { generates: ['dist', { path: 'out/$NAME.json' }] }, {
28
+ variables: { NAME: 'pkg' },
29
+ replacements: [],
30
+ });
31
+ expect(result[0]).toMatchObject({
32
+ path: (0, path_1.join)('/work', 'dist'),
33
+ isFile: false,
34
+ resetOnChange: false,
35
+ export: false,
36
+ inherited: null,
37
+ });
38
+ expect(result[0].volumeName).toBe((0, plan_work_volume_1.getVolumeName)((0, path_1.join)('/work', 'dist')));
39
+ expect(result[1]).toMatchObject({
40
+ path: (0, path_1.join)('/work', 'out/pkg.json'),
41
+ isFile: true,
42
+ });
43
+ });
44
+ });
45
+ //# sourceMappingURL=parse-work-generate.spec.js.map
@@ -1,25 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseWorkNodeMount = void 0;
3
+ exports.parseWorkMount = void 0;
4
4
  const os_1 = require("os");
5
5
  const normalize_path_1 = require("./normalize-path");
6
- function parseWorkNodeMount(cwd, dir) {
6
+ const path_1 = require("path");
7
+ function parseWorkMount(cwd, dir) {
7
8
  const parts = dir.split(':');
8
9
  if (parts.length === 1) {
9
- return parseLocalMount(cwd, dir, dir);
10
+ return parseLocalMount(cwd, dir, dir, dir);
10
11
  }
11
12
  else if (parts.length === 2) {
12
- return parseLocalMount(cwd, parts[0], parts[1]);
13
+ return parseLocalMount(cwd, parts[0], parts[1], dir);
13
14
  }
14
15
  else {
15
16
  throw new Error(`invalid mount ${dir}`);
16
17
  }
17
18
  }
18
- exports.parseWorkNodeMount = parseWorkNodeMount;
19
- function parseLocalMount(cwd, localPath, containerPath) {
19
+ exports.parseWorkMount = parseWorkMount;
20
+ function parseLocalMount(cwd, localPath, containerPath, mount) {
20
21
  return {
21
22
  localPath: (0, normalize_path_1.normalizePath)(cwd, (0, os_1.homedir)(), localPath),
22
23
  containerPath: (0, normalize_path_1.normalizePath)(cwd, cwd, containerPath),
24
+ isFile: (0, path_1.extname)(localPath).length > 1,
25
+ mount,
23
26
  };
24
27
  }
25
- //# sourceMappingURL=parse-work-node-mount.js.map
28
+ //# sourceMappingURL=parse-work-mount.js.map