hammerkit 1.5.1 → 1.6.0-alpha.2

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
package/dist/program.js CHANGED
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.getProgram = exports.createCli = void 0;
4
7
  const commander_1 = require("commander");
@@ -6,20 +9,25 @@ const path_1 = require("path");
6
9
  const ci_1 = require("./utils/ci");
7
10
  const parse_label_arguments_1 = require("./parser/parse-label-arguments");
8
11
  const cli_1 = require("./cli");
9
- const get_build_file_1 = require("./parser/get-build-file");
10
- const work_scope_1 = require("./executer/work-scope");
11
- const get_work_context_1 = require("./get-work-context");
12
12
  const log_1 = require("./log");
13
13
  const label_values_1 = require("./executer/label-values");
14
14
  const default_build_file_1 = require("./parser/default-build-file");
15
+ const schema_parser_1 = require("./schema/schema-parser");
16
+ const work_scope_parser_1 = require("./schema/work-scope-parser");
17
+ const reference_parser_1 = require("./schema/reference-parser");
18
+ const colors_1 = __importDefault(require("colors"));
19
+ const version_1 = require("./version");
15
20
  async function createCli(fileName, environment, workScope) {
16
- const buildFile = await (0, get_build_file_1.getBuildFile)(fileName, environment);
17
- const workTree = (0, get_work_context_1.getWorkScope)(buildFile, workScope, environment);
21
+ const { ctx, scope } = await (0, schema_parser_1.createParseContext)(fileName, environment);
22
+ const referencedScope = await (0, reference_parser_1.parseReferences)(ctx, scope, environment);
23
+ const workTree = (0, work_scope_parser_1.getWorkContext)(referencedScope, workScope, environment);
18
24
  return (0, cli_1.getCli)(workTree, environment);
19
25
  }
20
26
  exports.createCli = createCli;
21
- function parseWorkScope(options) {
22
- const scope = (0, work_scope_1.emptyWorkLabelScope)();
27
+ function parseWorkLabelScope(options) {
28
+ const scope = {
29
+ environmentName: null,
30
+ };
23
31
  if (typeof options !== 'object') {
24
32
  return scope;
25
33
  }
@@ -33,6 +41,9 @@ function parseWorkScope(options) {
33
41
  else if (key === 'exclude' && value instanceof Array) {
34
42
  scope.excludeLabels = (0, parse_label_arguments_1.parseLabelArguments)(value);
35
43
  }
44
+ else if (key === 'env') {
45
+ scope.environmentName = `${value}`;
46
+ }
36
47
  }
37
48
  return scope;
38
49
  }
@@ -40,7 +51,7 @@ async function getProgram(environment, argv) {
40
51
  const program = new commander_1.Command();
41
52
  const args = [...argv];
42
53
  const fileIndex = args.indexOf('--file');
43
- const fileName = (0, path_1.join)(environment.cwd, fileIndex >= 0 ? args[fileIndex + 1] : await (0, default_build_file_1.getDefaultBuildFilename)(environment.cwd, environment));
54
+ const fileName = fileIndex >= 0 ? (0, path_1.join)(environment.cwd, args[fileIndex + 1]) : await (0, default_build_file_1.getBuildFilename)(environment.cwd, environment);
44
55
  if (fileIndex >= 0) {
45
56
  args.splice(fileIndex, 2);
46
57
  }
@@ -51,21 +62,21 @@ async function getProgram(environment, argv) {
51
62
  .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
52
63
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
53
64
  .action(async (options) => {
54
- const cli = await createCli(fileName, environment, parseWorkScope(options));
65
+ const cli = await createCli(fileName, environment, parseWorkLabelScope(options));
55
66
  const items = cli.ls();
56
67
  const tasks = items.filter(cli_1.isCliTask);
57
68
  const services = items.filter(cli_1.isCliService);
58
69
  if (services.length > 0) {
59
70
  (0, log_1.printTitle)(environment, 'Services');
60
- for (const node of services) {
61
- (0, log_1.printItem)(environment, node.item);
62
- (0, log_1.printProperty)(environment, 'ports', node.item.ports.map((p) => `127.0.0.1:${p.hostPort} -> ${p.containerPort}`).join(', '));
63
- if (node.item.type === 'kubernetes-service') {
64
- (0, log_1.printProperty)(environment, 'context', node.item.context);
65
- (0, log_1.printProperty)(environment, 'selector', `${node.item.selector.type}/${node.item.selector.name}`);
71
+ for (const service of services) {
72
+ (0, log_1.printItem)(environment, service.item.data);
73
+ (0, log_1.printProperty)(environment, 'ports', service.item.data.ports.map((p) => `127.0.0.1:${p.hostPort} -> ${p.containerPort}`).join(', '));
74
+ if (service.item.data.type === 'kubernetes-service') {
75
+ (0, log_1.printProperty)(environment, 'context', service.item.data.context);
76
+ (0, log_1.printProperty)(environment, 'selector', `${service.item.data.selector.type}/${service.item.data.selector.name}`);
66
77
  }
67
78
  else {
68
- (0, log_1.printProperty)(environment, 'image', node.item.image);
79
+ (0, log_1.printProperty)(environment, 'image', service.item.data.image);
69
80
  }
70
81
  }
71
82
  }
@@ -74,30 +85,31 @@ async function getProgram(environment, argv) {
74
85
  }
75
86
  if (tasks.length > 0) {
76
87
  (0, log_1.printTitle)(environment, 'Tasks');
77
- for (const node of tasks) {
78
- (0, log_1.printItem)(environment, node.item);
79
- if (node.item.needs.length > 0) {
80
- (0, log_1.printProperty)(environment, 'needs', node.item.needs.map((d) => d.name).join(', '));
88
+ for (const task of tasks) {
89
+ (0, log_1.printItem)(environment, task.item.data);
90
+ if (task.item.needs.length > 0) {
91
+ (0, log_1.printProperty)(environment, 'needs', task.item.needs.map((d) => d.name).join(', '));
81
92
  }
82
- if (node.item.deps.length > 0) {
83
- (0, log_1.printProperty)(environment, 'deps', node.item.deps.map((d) => d.name).join(', '));
93
+ if (task.item.deps.length > 0) {
94
+ (0, log_1.printProperty)(environment, 'deps', task.item.deps.map((d) => d.name).join(', '));
84
95
  }
85
- if (node.item.type === 'container') {
86
- (0, log_1.printProperty)(environment, 'image', node.item.image);
96
+ if (task.item.data.type === 'container-task') {
97
+ (0, log_1.printProperty)(environment, 'image', task.item.data.image);
87
98
  }
88
- if (node.item.caching) {
89
- (0, log_1.printProperty)(environment, 'caching', node.item.caching);
99
+ if (task.item.data.caching) {
100
+ const c = task.item.data.caching;
101
+ (0, log_1.printProperty)(environment, 'caching', `${c.name} (${c.method}, ${c.backend.type})`);
90
102
  }
91
- if ((0, label_values_1.hasLabels)(node.item.labels)) {
92
- (0, log_1.printProperty)(environment, 'labels', `${Object.keys(node.item.labels)
93
- .map((key) => `${key}=${node.item.labels[key].join(',')}`)
103
+ if ((0, label_values_1.hasLabels)(task.item.data.labels)) {
104
+ (0, log_1.printProperty)(environment, 'labels', `${Object.keys(task.item.data.labels)
105
+ .map((key) => `${key}=${task.item.data.labels[key].join(',')}`)
94
106
  .join(' ')}`);
95
107
  }
96
- if (node.item.src.length > 0) {
97
- (0, log_1.printProperty)(environment, 'src', node.item.src.map((d) => (0, path_1.relative)(node.item.cwd, d.absolutePath)).join(' '));
108
+ if (task.item.data.src.length > 0) {
109
+ (0, log_1.printProperty)(environment, 'src', task.item.data.src.map((d) => (0, path_1.relative)(task.item.data.cwd, d.absolutePath)).join(' '));
98
110
  }
99
- if (node.item.generates.length > 0) {
100
- (0, log_1.printProperty)(environment, 'generates', node.item.generates.map((d) => (0, path_1.relative)(node.item.cwd, d.path)).join(' '));
111
+ if (task.item.data.generates.length > 0) {
112
+ (0, log_1.printProperty)(environment, 'generates', task.item.data.generates.map((d) => (0, path_1.relative)(task.item.data.cwd, d.path)).join(' '));
101
113
  }
102
114
  }
103
115
  }
@@ -105,33 +117,90 @@ async function getProgram(environment, argv) {
105
117
  });
106
118
  program
107
119
  .command('clean')
108
- .description('clear task cache')
109
- .addOption(new commander_1.Option('--service', 'clean data volumes of services'))
120
+ .description('clear cache and generated')
110
121
  .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
111
122
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
123
+ .addOption(new commander_1.Option('--cache', 'also clear stored cache results from the backend (e.g. the local ~/.hammerkit/remote-cache or a configured remote bucket)'))
112
124
  .action(async (options) => {
113
- const cli = await createCli(fileName, environment, parseWorkScope(options));
114
- await cli.clean({
115
- service: options.service,
116
- });
125
+ try {
126
+ const cli = await createCli(fileName, environment, parseWorkLabelScope(options));
127
+ await cli.clean({ cache: !!options.cache });
128
+ }
129
+ catch (e) {
130
+ if (e instanceof commander_1.CommanderError) {
131
+ throw e;
132
+ }
133
+ environment.console.error((0, log_1.getErrorMessage)(e));
134
+ program.error('Clean was not successful', { exitCode: 1 });
135
+ }
117
136
  });
118
137
  program
119
- .command('store <path>')
120
- .description('save task outputs into <path>')
138
+ .command('store <directory>')
139
+ .description('save task outputs into <directory>')
121
140
  .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
122
141
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
123
142
  .action(async (path, options) => {
124
- const cli = await createCli(fileName, environment, parseWorkScope(options));
125
- await cli.store((0, path_1.resolve)(path));
143
+ try {
144
+ const cli = await createCli(fileName, environment, parseWorkLabelScope(options));
145
+ await cli.store((0, path_1.resolve)(path));
146
+ }
147
+ catch (e) {
148
+ if (e instanceof commander_1.CommanderError) {
149
+ throw e;
150
+ }
151
+ environment.console.error((0, log_1.getErrorMessage)(e));
152
+ program.error('Store was not successful', { exitCode: 1 });
153
+ }
126
154
  });
127
155
  program
128
- .command('restore <path>')
129
- .description('restore task outputs from <path>')
156
+ .command('restore <directory>')
157
+ .description('restore task outputs from <directory>')
130
158
  .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
131
159
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
132
160
  .action(async (path, options) => {
133
- const cli = await createCli(fileName, environment, parseWorkScope(options));
134
- await cli.restore((0, path_1.resolve)(path));
161
+ try {
162
+ const cli = await createCli(fileName, environment, parseWorkLabelScope(options));
163
+ await cli.restore((0, path_1.resolve)(path));
164
+ }
165
+ catch (e) {
166
+ if (e instanceof commander_1.CommanderError) {
167
+ throw e;
168
+ }
169
+ environment.console.error((0, log_1.getErrorMessage)(e));
170
+ program.error('Restore was not successful', { exitCode: 1 });
171
+ }
172
+ });
173
+ program
174
+ .command('package <registry>')
175
+ .description('package services into a docker image')
176
+ .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
177
+ .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
178
+ .addOption(new commander_1.Option('--push', 'push image to registry').default(false))
179
+ .addOption(new commander_1.Option('--build-override-user', 'set a dedicated user (uid/gid)').default(false))
180
+ .addOption(new commander_1.Option('-t, --tag <tag>', 'image tag').default('latest'))
181
+ .addOption(new commander_1.Option('--platform <platform>', 'target build platform, e.g. linux/amd64'))
182
+ .addOption(new commander_1.Option('-u, --user, --username', 'registry username'))
183
+ .addOption(new commander_1.Option('-p, --password', 'registry password'))
184
+ .action(async (registry, options) => {
185
+ try {
186
+ const cli = await createCli(fileName, environment, parseWorkLabelScope(options));
187
+ await cli.package({
188
+ registry,
189
+ push: options.push,
190
+ overrideUser: !!options.overrideUser,
191
+ username: options.username,
192
+ password: options.password,
193
+ tag: options.tag,
194
+ platform: options.platform,
195
+ });
196
+ }
197
+ catch (e) {
198
+ if (e instanceof commander_1.CommanderError) {
199
+ throw e;
200
+ }
201
+ environment.console.error((0, log_1.getErrorMessage)(e));
202
+ program.error('Package was not successful', { exitCode: 1 });
203
+ }
135
204
  });
136
205
  program
137
206
  .command('validate')
@@ -140,14 +209,24 @@ async function getProgram(environment, argv) {
140
209
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
141
210
  .action(async (options) => {
142
211
  let errors = 0;
143
- const cli = await createCli(fileName, environment, parseWorkScope(options));
212
+ const cli = await createCli(fileName, environment, parseWorkLabelScope(options));
213
+ const fileErrors = {};
144
214
  for await (const validation of cli.validate()) {
215
+ if (!fileErrors[validation.item.scope.fileName]) {
216
+ fileErrors[validation.item.scope.fileName] = [validation];
217
+ }
218
+ else {
219
+ fileErrors[validation.item.scope.fileName].push(validation);
220
+ }
145
221
  if (validation.type === 'error') {
146
222
  errors++;
147
- environment.console.error(validation.message);
148
223
  }
149
- else {
150
- environment.console.warn(validation.message);
224
+ for (const [buildFilename, errors] of Object.entries(fileErrors)) {
225
+ environment.stdout.write(`${colors_1.default.underline(colors_1.default.gray(buildFilename))}\n`);
226
+ for (const error of errors) {
227
+ environment.stdout.write(` ${colors_1.default.underline(colors_1.default.blue(error.type))} at ${colors_1.default.gray(error.item.name)} ${error.message}\n`);
228
+ }
229
+ environment.stdout.write('\n');
151
230
  }
152
231
  }
153
232
  if (errors !== 0) {
@@ -155,39 +234,105 @@ async function getProgram(environment, argv) {
155
234
  }
156
235
  });
157
236
  program
158
- .command('shutdown')
159
- .description('end all container tasks/services')
160
- .arguments('[task]')
237
+ .command('up')
238
+ .description('start services(s)')
161
239
  .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
162
240
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
163
- .action(async (task, options) => {
164
- const cli = await createCli(fileName, environment, task ? { taskName: task } : parseWorkScope(options));
165
- cli.shutdown();
241
+ .addOption(new commander_1.Option('-c, --concurrency <number>', 'parallel worker count').argParser(parseInt).default(4))
242
+ .addOption(new commander_1.Option('-w, --watch', 'watch tasks').default(false))
243
+ .addOption(new commander_1.Option('-d, --daemon', 'run services in background').default(false))
244
+ .addOption(new commander_1.Option('--env <name>', 'environment'))
245
+ .addOption(new commander_1.Option('-l, --log <mode>', 'log mode')
246
+ .default(ci_1.isCI ? 'live' : 'interactive')
247
+ .choices(['interactive', 'live', 'grouped']))
248
+ .addOption(new commander_1.Option('--cache <method>', 'caching method to compare')
249
+ .default('checksum')
250
+ .choices(['checksum', 'modify-date', 'none']))
251
+ .action(async (options) => {
252
+ try {
253
+ const scope = parseWorkLabelScope(options);
254
+ const cli = await createCli(fileName, environment, scope);
255
+ const result = await cli.runUp({
256
+ cacheDefault: options.cache,
257
+ watch: options.watch,
258
+ workers: options.concurrency,
259
+ logMode: options.log,
260
+ daemon: options.daemon,
261
+ });
262
+ if (!result.success) {
263
+ program.error('Up was not successful', { exitCode: 1 });
264
+ }
265
+ else {
266
+ process.exit();
267
+ }
268
+ }
269
+ catch (e) {
270
+ if (e instanceof commander_1.CommanderError) {
271
+ throw e;
272
+ }
273
+ environment.console.error((0, log_1.getErrorMessage)(e));
274
+ program.error('Up was not successful', { exitCode: 1 });
275
+ }
166
276
  });
167
277
  program
168
- .command('exec', { isDefault: true })
169
- .description('execute task(s)')
170
- .arguments('[task]')
278
+ .command('down')
279
+ .description('stop services(s)')
280
+ .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
281
+ .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
282
+ .addOption(new commander_1.Option('--env <name>', 'environment'))
283
+ .action(async (options) => {
284
+ try {
285
+ const scope = parseWorkLabelScope(options);
286
+ const cli = await createCli(fileName, environment, scope);
287
+ const result = await cli.runDown();
288
+ if (!result.success) {
289
+ program.error('Shutdown was not successful', { exitCode: 1 });
290
+ }
291
+ }
292
+ catch (e) {
293
+ if (e instanceof commander_1.CommanderError) {
294
+ throw e;
295
+ }
296
+ environment.console.error((0, log_1.getErrorMessage)(e));
297
+ program.error('Shutdown was not successful', { exitCode: 1 });
298
+ }
299
+ });
300
+ program
301
+ .command('run [task]', { isDefault: true })
302
+ .description('execute task')
171
303
  .addOption(new commander_1.Option('-f, --filter <labels...>', 'filter task and services with labels'))
172
304
  .addOption(new commander_1.Option('-e, --exclude <labels...>', 'exclude task and services with labels'))
173
305
  .addOption(new commander_1.Option('-c, --concurrency <number>', 'parallel worker count').argParser(parseInt).default(4))
174
306
  .addOption(new commander_1.Option('-w, --watch', 'watch tasks').default(false))
307
+ .addOption(new commander_1.Option('--env <name>', 'environment'))
175
308
  .addOption(new commander_1.Option('-l, --log <mode>', 'log mode')
176
309
  .default(ci_1.isCI ? 'live' : 'interactive')
177
310
  .choices(['interactive', 'live', 'grouped']))
178
311
  .addOption(new commander_1.Option('--cache <method>', 'caching method to compare')
179
- .default(ci_1.isCI ? 'checksum' : 'modify-date')
312
+ .default('checksum')
180
313
  .choices(['checksum', 'modify-date', 'none']))
181
314
  .action(async (task, options) => {
182
- const cli = await createCli(fileName, environment, task ? { taskName: task } : parseWorkScope(options));
183
- const result = await cli.exec({
184
- cacheDefault: options.cache,
185
- watch: options.watch,
186
- workers: options.concurrency,
187
- logMode: options.log,
188
- });
189
- if (!result.success) {
190
- program.error('Execution was not successful', { exitCode: 1 });
315
+ try {
316
+ const cli = await createCli(fileName, environment, task ? { taskName: task, environmentName: options.env } : parseWorkLabelScope(options));
317
+ if (cli.tasks().length === 0) {
318
+ program.error('No tasks found', { exitCode: 127 });
319
+ return;
320
+ }
321
+ const result = await cli.runExec({
322
+ cacheDefault: options.cache,
323
+ watch: options.watch,
324
+ workers: options.concurrency,
325
+ logMode: options.log,
326
+ });
327
+ if (!result.success) {
328
+ program.error('Execution was not successful', { exitCode: 1 });
329
+ }
330
+ }
331
+ catch (e) {
332
+ if (e instanceof commander_1.CommanderError) {
333
+ throw e;
334
+ }
335
+ program.error((0, log_1.getErrorMessage)(e), { exitCode: 1 });
191
336
  }
192
337
  });
193
338
  }
@@ -211,13 +356,14 @@ tasks:
211
356
  environment.console.info(`created ${fileName}`);
212
357
  });
213
358
  }
214
- // eslint-disable-next-line @typescript-eslint/no-var-requires
215
- program.version(require('../package.json').version);
359
+ program.version((0, version_1.getVersion)());
216
360
  program.option('--verbose', 'log debugging information', false);
217
361
  program.option('--file', 'set build file', '.hammerkit.yaml');
218
362
  program.configureOutput({
219
363
  writeOut: (str) => environment.console.info(str),
220
- writeErr: (str) => environment.console.error(str),
364
+ writeErr: (str) => {
365
+ environment.console.error(str);
366
+ },
221
367
  });
222
368
  return { program, args };
223
369
  }
@@ -1,20 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const path_1 = require("path");
4
- const program_1 = require("./program");
5
- const environment_mock_1 = require("./executer/environment-mock");
3
+ const test_case_1 = require("./testing/test-case");
6
4
  describe('program', () => {
7
- async function testCommand(commandArgs) {
8
- const fileName = (0, path_1.join)(__dirname, '../examples/program');
9
- const context = (0, environment_mock_1.environmentMock)(fileName);
10
- const { program, args } = await (0, program_1.getProgram)(context, [process.argv[0], fileName, ...commandArgs]);
11
- return program.exitOverride().parseAsync(args);
12
- }
13
5
  it('should run when cache is up to date and --no-cache arg is passed', async () => {
14
- await testCommand(['example', '--cache', 'none']);
6
+ const testCase = (0, test_case_1.createTestCase)('no-cache', {
7
+ 'package.json': '{ "dependencies": { "hammerkit": "^1.5.0" } }',
8
+ '.hammerkit.yaml': {
9
+ tasks: {
10
+ example: {
11
+ description: 'install npm packages',
12
+ image: 'node:16.6.0-alpine',
13
+ // On linux hammerkit runs the container as the host uid:gid (see
14
+ // get-container-user) so generated files aren't root-owned. That uid
15
+ // has no home dir in the image, so npm falls back to the unwritable
16
+ // /.npm and fails with EACCES. Point HOME at a writable dir — what a
17
+ // real non-root user would do — so the task works regardless of uid
18
+ // (it only "passed" elsewhere because those ran the container as root).
19
+ envs: { HOME: '/tmp' },
20
+ src: ['package.json'],
21
+ generates: ['node_modules'],
22
+ cmds: ['npm install'],
23
+ },
24
+ },
25
+ },
26
+ });
27
+ await testCase.shell(['run', 'example', '--cache', 'none']);
15
28
  }, 120000);
16
29
  it('should warn about invalid task name', async () => {
17
- await expect(testCommand(['example2'])).rejects.toThrow();
30
+ const testCase = (0, test_case_1.createTestCase)('wrong-name', {
31
+ '.hammerkit.yaml': {
32
+ tasks: {
33
+ example: {
34
+ image: 'node:16.6.0-alpine',
35
+ cmds: ['npm ci'],
36
+ },
37
+ },
38
+ },
39
+ });
40
+ await expect(testCase.shell(['run', 'example2'])).rejects.toThrow('No tasks found');
18
41
  });
19
42
  });
20
43
  //# sourceMappingURL=program.spec.js.map
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runProgram = void 0;
7
+ const program_1 = require("./program");
8
+ const parse_error_1 = require("./schema/parse-error");
9
+ const colors_1 = __importDefault(require("colors"));
10
+ function runProgram(env, argv, exitOverride) {
11
+ return (0, program_1.getProgram)(env, argv)
12
+ .then(({ program, args }) => {
13
+ return exitOverride ? program.exitOverride().parseAsync([env.cwd, ...args]) : program.parseAsync(args);
14
+ })
15
+ .catch((err) => {
16
+ if (err instanceof parse_error_1.ParseError) {
17
+ env.stderr.write(`${colors_1.default.underline(colors_1.default.gray(err.buildFilePath))}\n`);
18
+ for (const error of err.zod.errors) {
19
+ env.stderr.write(` ${colors_1.default.underline(colors_1.default.blue(`error`))} at ${colors_1.default.gray(error.path.join('.'))} ${error.message} ${colors_1.default.gray(error.code)}\n`);
20
+ }
21
+ }
22
+ else {
23
+ throw err;
24
+ }
25
+ });
26
+ }
27
+ exports.runProgram = runProgram;
28
+ //# sourceMappingURL=run-program.js.map
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=process.js.map
3
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileBaseTaskSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const build_file_need_schema_1 = require("./build-file-need-schema");
6
+ const envs_schema_1 = require("./envs-schema");
7
+ const labels_schema_1 = require("./labels-schema");
8
+ const cache_schema_1 = require("./cache-schema");
9
+ const build_file_task_command_schema_1 = require("./build-file-task-command-schema");
10
+ const build_file_volume_schema_1 = require("./build-file-volume-schema");
11
+ exports.buildFileBaseTaskSchema = (0, zod_1.object)({
12
+ deps: (0, zod_1.array)((0, zod_1.string)()).optional(),
13
+ needs: (0, zod_1.array)(build_file_need_schema_1.buildFileNeedSchema).optional(),
14
+ description: (0, zod_1.string)().optional(),
15
+ extend: (0, zod_1.string)().optional(),
16
+ envs: envs_schema_1.envsSchema.optional(),
17
+ labels: labels_schema_1.labelsSchema.optional(),
18
+ cache: cache_schema_1.cacheSchema.optional(),
19
+ cmds: (0, zod_1.array)(build_file_task_command_schema_1.buildFileTaskCommandSchema).optional(),
20
+ src: (0, zod_1.array)((0, zod_1.string)()).optional(),
21
+ generates: (0, zod_1.array)(build_file_volume_schema_1.buildFileVolumeSchema).optional(),
22
+ shell: (0, zod_1.string)().optional(),
23
+ // A task that watches its own sources and restarts itself (e.g. `ng serve`,
24
+ // `tsc -w`). In watch mode hammerkit then does not watch/restart it itself.
25
+ continuous: (0, zod_1.boolean)().optional(),
26
+ });
27
+ //# sourceMappingURL=build-file-base-task-schema.js.map
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileContainerServiceSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const envs_schema_1 = require("./envs-schema");
6
+ const build_file_need_schema_1 = require("./build-file-need-schema");
7
+ const labels_schema_1 = require("./labels-schema");
8
+ const build_file_service_container_healthcheck_1 = require("./build-file-service-container-healthcheck");
9
+ exports.buildFileContainerServiceSchema = (0, zod_1.object)({
10
+ image: (0, zod_1.string)(),
11
+ description: (0, zod_1.string)().optional(),
12
+ // Optional: a service reached only via `needs`/service-DNS (e.g. postgres:5432
13
+ // from another container) does not need a published host port.
14
+ ports: (0, zod_1.array)((0, zod_1.union)([(0, zod_1.string)(), (0, zod_1.number)()])).optional(),
15
+ envs: envs_schema_1.envsSchema.optional(),
16
+ mounts: (0, zod_1.array)((0, zod_1.string)()).optional(),
17
+ deps: (0, zod_1.array)((0, zod_1.string)()).optional(),
18
+ src: (0, zod_1.array)((0, zod_1.string)()).optional(),
19
+ needs: (0, zod_1.array)(build_file_need_schema_1.buildFileNeedSchema).optional(),
20
+ cmd: (0, zod_1.string)().optional(),
21
+ volumes: (0, zod_1.array)((0, zod_1.string)()).optional(),
22
+ labels: labels_schema_1.labelsSchema.optional(),
23
+ continuous: (0, zod_1.boolean)().optional(),
24
+ healthcheck: build_file_service_container_healthcheck_1.buildFileServiceContainerHealthcheck.optional(),
25
+ })
26
+ .strict()
27
+ .describe('container service');
28
+ //# sourceMappingURL=build-file-container-service-schema.js.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileContainerTaskSchema = void 0;
4
+ const build_file_base_task_schema_1 = require("./build-file-base-task-schema");
5
+ const zod_1 = require("zod");
6
+ exports.buildFileContainerTaskSchema = build_file_base_task_schema_1.buildFileBaseTaskSchema
7
+ .extend({
8
+ image: (0, zod_1.string)(),
9
+ mounts: (0, zod_1.array)((0, zod_1.string)()).optional(),
10
+ })
11
+ .strict()
12
+ .describe('container task');
13
+ //# sourceMappingURL=build-file-container-task-schema.js.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileEnvironmentSchemaIngress = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileEnvironmentSchemaIngress = (0, zod_1.object)({
6
+ kind: zod_1.z.enum(['ingress', 'httproute']).optional(),
7
+ host: (0, zod_1.string)(),
8
+ service: (0, zod_1.string)(),
9
+ servicePort: (0, zod_1.number)().optional(),
10
+ path: (0, zod_1.string)().optional(),
11
+ gateway: (0, zod_1.string)().optional(),
12
+ gatewayNamespace: (0, zod_1.string)().optional(),
13
+ }).strict();
14
+ //# sourceMappingURL=build-file-environment-schema-ingress.js.map
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileEnvironmentSchema = exports.buildFileDockerEnvironmentSchema = exports.buildFileKubernetesEnvironmentSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const build_file_environment_schema_ingress_1 = require("./build-file-environment-schema-ingress");
6
+ exports.buildFileKubernetesEnvironmentSchema = (0, zod_1.object)({
7
+ namespace: (0, zod_1.string)().optional(),
8
+ context: (0, zod_1.string)(),
9
+ kubeconfig: (0, zod_1.string)().optional(),
10
+ ingresses: (0, zod_1.array)(build_file_environment_schema_ingress_1.buildFileEnvironmentSchemaIngress).optional(),
11
+ });
12
+ exports.buildFileDockerEnvironmentSchema = (0, zod_1.object)({
13
+ host: (0, zod_1.string)().optional(),
14
+ }).strict();
15
+ exports.buildFileEnvironmentSchema = (0, zod_1.union)([
16
+ (0, zod_1.object)({
17
+ kubernetes: exports.buildFileKubernetesEnvironmentSchema,
18
+ }).strict(),
19
+ (0, zod_1.object)({
20
+ docker: exports.buildFileDockerEnvironmentSchema,
21
+ }).strict(),
22
+ ]);
23
+ //# sourceMappingURL=build-file-environment-schema.js.map
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileKubernetesServiceSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const build_file_kubernetes_service_selector_schema_1 = require("./build-file-kubernetes-service-selector-schema");
6
+ const labels_schema_1 = require("./labels-schema");
7
+ exports.buildFileKubernetesServiceSchema = (0, zod_1.object)({
8
+ kubeconfig: (0, zod_1.string)().optional(),
9
+ deps: (0, zod_1.array)((0, zod_1.string)()).optional(),
10
+ description: (0, zod_1.string)().optional(),
11
+ context: (0, zod_1.string)().optional(),
12
+ namespace: (0, zod_1.string)().optional(),
13
+ selector: build_file_kubernetes_service_selector_schema_1.buildFileKubernetesServiceSelectorSchema,
14
+ labels: labels_schema_1.labelsSchema.optional(),
15
+ ports: (0, zod_1.array)((0, zod_1.union)([(0, zod_1.string)(), (0, zod_1.number)()])),
16
+ }).strict();
17
+ //# sourceMappingURL=build-file-kubernetes-service-schema.js.map