hammerkit 1.5.1 → 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.
- package/.agents/FEEDBACK.md +74 -0
- package/.agents/skills/before-commit/SKILL.md +101 -0
- package/.agents/skills/do-the-work/SKILL.md +64 -0
- package/.agents/skills/fix-ci/SKILL.md +98 -0
- package/.agents/skills/speckit-git-commit/SKILL.md +53 -0
- package/.agents/skills/speckit-git-feature/SKILL.md +72 -0
- package/.agents/skills/speckit-git-initialize/SKILL.md +54 -0
- package/.agents/skills/speckit-git-remote/SKILL.md +50 -0
- package/.agents/skills/speckit-git-validate/SKILL.md +54 -0
- package/.gitbook.yaml +5 -0
- package/.specify/extensions/.registry +37 -0
- package/.specify/extensions/git/README.md +100 -0
- package/.specify/extensions/git/commands/speckit.git.commit.md +48 -0
- package/.specify/extensions/git/commands/speckit.git.feature.md +67 -0
- package/.specify/extensions/git/commands/speckit.git.initialize.md +49 -0
- package/.specify/extensions/git/commands/speckit.git.remote.md +45 -0
- package/.specify/extensions/git/commands/speckit.git.validate.md +49 -0
- package/.specify/extensions/git/config-template.yml +62 -0
- package/.specify/extensions/git/extension.yml +140 -0
- package/.specify/extensions/git/git-config.yml +62 -0
- package/.specify/extensions.yml +149 -0
- package/.specify/feature.json +3 -0
- package/.specify/init-options.json +10 -0
- package/.specify/integration.json +15 -0
- package/.specify/integrations/claude.manifest.json +16 -0
- package/.specify/integrations/speckit.manifest.json +17 -0
- package/.specify/memory/constitution.md +162 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/constitution-template.md +50 -0
- package/.specify/templates/plan-template.md +113 -0
- package/.specify/templates/spec-template.md +131 -0
- package/.specify/templates/tasks-template.md +252 -0
- package/.specify/workflows/speckit/workflow.yml +77 -0
- package/.specify/workflows/workflow-registry.json +13 -0
- package/AGENTS.md +94 -0
- package/Dockerfile +3 -3
- package/FOLLOWUPS.md +34 -0
- package/README.md +9 -7
- package/SUMMARY.md +30 -5
- package/VALUES.md +53 -0
- package/build.schema.json +542 -408
- package/dist/cache/auto-pull.spec.js +123 -0
- package/dist/cache/backends/local-cache-backend.js +56 -0
- package/dist/cache/backends/local-cache-backend.spec.js +72 -0
- package/dist/cache/backends/s3-cache-backend.js +124 -0
- package/dist/cache/backends/s3-cache-backend.spec.js +118 -0
- package/dist/cache/cache-backend-registry.js +21 -0
- package/dist/cache/cache-backend-registry.spec.js +22 -0
- package/dist/cache/cache-backend.js +3 -0
- package/dist/cache/resolve-cache.js +60 -0
- package/dist/cache/resolve-cache.spec.js +52 -0
- package/dist/cli.js +112 -82
- package/dist/cli.spec.js +20 -2
- package/dist/console/get-logger.spec.js +23 -0
- package/dist/docker/get-default-platform.spec.js +29 -0
- package/dist/docker/longest-common-prefix.spec.js +26 -0
- package/dist/docker/package.js +283 -0
- package/dist/docker/package.spec.js +145 -0
- package/dist/docker/pull.js +4 -4
- package/dist/docker/remove-container.spec.js +32 -0
- package/dist/docker/stream.js +3 -3
- package/dist/docker/using-container.js +29 -11
- package/dist/docker/using-container.spec.js +90 -0
- package/dist/environment/merge-environment-variables.js +21 -0
- package/dist/environment/merge-environment-variables.spec.js +24 -0
- package/dist/environment/replace-env-variables.js +43 -10
- package/dist/environment/replace-env-variables.spec.js +47 -0
- package/dist/executer/abort.spec.js +18 -0
- package/dist/executer/await-completed-dependencies.js +56 -0
- package/dist/executer/cache-metadata.js +11 -0
- package/dist/executer/check-readiness.js +1 -1
- package/dist/{planner/work-node-port.js → executer/container-bind.js} +1 -1
- package/dist/executer/docker-service.js +110 -86
- package/dist/executer/docker-task.js +132 -0
- package/dist/executer/environment-mock.js +3 -4
- package/dist/executer/environment-mock.spec.js +22 -0
- package/dist/executer/event-cache.js +60 -127
- package/dist/executer/execute-command.js +4 -3
- package/dist/executer/execute-docker.js +32 -14
- package/dist/executer/execute-work-service.js +61 -0
- package/dist/executer/execute-work-task.js +107 -0
- package/dist/executer/execute-work-tree.js +27 -0
- package/dist/executer/execute.spec.js +14 -10
- package/dist/executer/execution-steps.js +47 -31
- package/dist/executer/get-container-binds.js +19 -0
- package/dist/executer/get-docker-executor.js +12 -12
- package/dist/executer/get-scheduler-down-result.js +12 -0
- package/dist/executer/get-scheduler-execute-result.js +28 -0
- package/dist/executer/get-scheduler-up-result.js +12 -0
- package/dist/executer/get-service-containers.js +14 -0
- package/dist/executer/get-service-containers.spec.js +59 -0
- package/dist/executer/get-service-env-hints.js +35 -0
- package/dist/executer/get-service-env-hints.spec.js +65 -0
- package/dist/executer/kubernetes-service.js +116 -48
- package/dist/executer/label-values.js +29 -46
- package/dist/executer/label-values.spec.js +61 -0
- package/dist/executer/lazy-resolver.js +16 -0
- package/dist/executer/lazy-resolver.spec.js +20 -0
- package/dist/executer/local-task.js +44 -0
- package/dist/executer/process-manager.js +16 -70
- package/dist/executer/process-manager.spec.js +39 -76
- package/dist/executer/reset-work-tree.js +30 -0
- package/dist/executer/scheduler/check-for-loop.js +17 -7
- package/dist/executer/scheduler/{scheduler-state.js → dependency-state.js} +1 -1
- package/dist/executer/scheduler/enqueue-next.js +83 -19
- package/dist/executer/scheduler/enqueue-next.spec.js +136 -0
- package/dist/executer/scheduler/{node-state.js → need-state.js} +1 -1
- package/dist/{parser/build-file.js → executer/scheduler/task-state.js} +1 -1
- package/dist/executer/set-user-permission.js +1 -1
- package/dist/executer/state-resolver.js +61 -0
- package/dist/executer/state-resolver.spec.js +37 -0
- package/dist/executer/state.js +37 -31
- package/dist/executer/state.spec.js +66 -0
- package/dist/executer/states.spec.js +14 -0
- package/dist/executer/watch-loop.js +68 -0
- package/dist/executer/watch-state-key.js +44 -0
- package/dist/executer/work-scope.js +1 -5
- package/dist/file/get-file-context.js +24 -3
- package/dist/file/get-file-context.spec.js +178 -0
- package/dist/file/move-files.js +2 -2
- package/dist/file/move-files.spec.js +48 -0
- package/dist/index.js +7 -8
- package/dist/json-schema.js +12 -0
- package/dist/kubernetes/apply.js +34 -0
- package/dist/kubernetes/await-running-state.js +71 -0
- package/dist/kubernetes/ensure-http-route.js +53 -0
- package/dist/kubernetes/ensure-http-route.spec.js +70 -0
- package/dist/kubernetes/ensure-ingress.js +54 -0
- package/dist/kubernetes/ensure-kubernetes-deployment-exists.js +105 -0
- package/dist/kubernetes/ensure-kubernetes-persistent-volume-claim-exists.js +40 -0
- package/dist/kubernetes/ensure-kubernetes-service-exists.js +36 -0
- package/dist/kubernetes/ensure-namespace.js +43 -0
- package/dist/kubernetes/ensure-namespace.spec.js +39 -0
- package/dist/kubernetes/ensure-persistent-data.js +158 -0
- package/dist/kubernetes/get-service-ip.js +11 -0
- package/dist/kubernetes/kubernetes-instance.js +48 -0
- package/dist/kubernetes/remove-persistent-data.js +19 -0
- package/dist/kubernetes/resolve-pod-name.js +42 -0
- package/dist/kubernetes/resolve-pod-name.spec.js +81 -0
- package/dist/kubernetes/resources.js +12 -0
- package/dist/kubernetes/restore-kubernetes-data.js +42 -0
- package/dist/kubernetes/store-kubernetes-data.js +39 -0
- package/dist/kubernetes/volumes.js +64 -0
- package/dist/log.js +69 -69
- package/dist/log.spec.js +131 -0
- package/dist/logging/grouped-logger.js +17 -15
- package/dist/logging/grouped-logger.spec.js +84 -0
- package/dist/logging/interactive-logger.js +1 -1
- package/dist/logging/interactive-logger.spec.js +57 -0
- package/dist/logging/live-logger.js +2 -2
- package/dist/logging/live-logger.spec.js +37 -0
- package/dist/logging/loggers.spec.js +154 -0
- package/dist/optimizer/calculate-checksum.spec.js +34 -0
- package/dist/optimizer/get-cache-directory.js +6 -6
- package/dist/optimizer/get-cache-directory.spec.js +59 -0
- package/dist/optimizer/get-work-cache-stats.js +53 -0
- package/dist/optimizer/get-work-cache-stats.spec.js +79 -0
- package/dist/{parser/build-file-task.js → optimizer/work-cache-stats.js} +1 -1
- package/dist/optimizer/work-task-cache-description.js +25 -0
- package/dist/optimizer/work-task-cache-description.spec.js +45 -0
- package/dist/parser/default-build-file.js +14 -7
- package/dist/parser/default-build-file.spec.js +48 -0
- package/dist/parser/parse-label-arguments.spec.js +27 -0
- package/dist/parser/read-build-file.js +2 -13
- package/dist/parser/read-build-file.spec.js +89 -0
- package/dist/parser/read-env-file.js +4 -5
- package/dist/parser/read-env-file.spec.js +42 -0
- package/dist/planner/utils/append-work-dependencies.js +55 -0
- package/dist/planner/utils/append-work-environment.js +22 -0
- package/dist/planner/utils/append-work-needs.js +18 -0
- package/dist/planner/utils/append-work-service.js +107 -0
- package/dist/planner/utils/append-work-service.spec.js +71 -0
- package/dist/planner/utils/append-work-task.js +81 -0
- package/dist/planner/utils/get-container-user.js +14 -0
- package/dist/planner/utils/get-container-user.spec.js +30 -0
- package/dist/planner/utils/get-default-kube-config.js +10 -0
- package/dist/planner/utils/get-default-kube-config.spec.js +11 -0
- package/dist/planner/utils/get-work-runtime.js +44 -0
- package/dist/planner/utils/normalize-path.js +1 -1
- package/dist/planner/utils/normalize-path.spec.js +24 -0
- package/dist/planner/utils/parse-work-command.js +80 -0
- package/dist/planner/utils/parse-work-command.spec.js +21 -0
- package/dist/planner/utils/parse-work-generate.js +38 -0
- package/dist/planner/utils/parse-work-generate.spec.js +45 -0
- package/dist/planner/utils/{parse-work-node-mount.js → parse-work-mount.js} +10 -7
- package/dist/planner/utils/{parse-work-node-mount.spec.js → parse-work-mount.spec.js} +14 -11
- package/dist/planner/utils/parse-work-mounts.js +13 -0
- package/dist/planner/utils/parse-work-mounts.spec.js +19 -0
- package/dist/planner/utils/{parse-work-node-port.js → parse-work-port.js} +11 -8
- package/dist/planner/utils/parse-work-port.spec.js +24 -0
- package/dist/planner/utils/parse-work-ports.js +10 -0
- package/dist/planner/utils/parse-work-ports.spec.js +24 -0
- package/dist/planner/utils/parse-work-source.js +72 -0
- package/dist/planner/utils/parse-work-source.spec.js +58 -0
- package/dist/planner/utils/parse-work-volume.js +45 -0
- package/dist/planner/utils/parse-work-volume.spec.js +18 -0
- package/dist/planner/utils/plan-work-tasks.js +41 -0
- package/dist/planner/utils/plan-work-tasks.spec.js +30 -0
- package/dist/planner/utils/plan-work-volume.js +1 -0
- package/dist/planner/utils/plan-work-volume.spec.js +33 -0
- package/dist/planner/utils/split-name.js +2 -2
- package/dist/planner/utils/split-name.spec.js +16 -0
- package/dist/planner/utils/template-value.js +1 -2
- package/dist/planner/utils/template-value.spec.js +14 -0
- package/dist/planner/validate.js +71 -38
- package/dist/planner/validate.spec.js +251 -0
- package/dist/planner/work-cache-id.js +12 -0
- package/dist/planner/work-cache-id.spec.js +173 -0
- package/dist/planner/work-command.js +3 -0
- package/dist/planner/work-environment.js +3 -0
- package/dist/planner/work-healthcheck.js +3 -0
- package/dist/planner/{work-node-status.js → work-item-status.js} +16 -62
- package/dist/{parser/build-file-service.js → planner/work-item-validation.js} +1 -1
- package/dist/planner/work-item.js +16 -0
- package/dist/{optimizer/work-node-cache-stats.js → planner/work-kubernetes-selector.js} +1 -1
- package/dist/planner/{work-nodes.js → work-port.js} +1 -1
- package/dist/planner/work-runtime-docker.js +224 -0
- package/dist/planner/work-runtime-kubernetes.js +264 -0
- package/dist/planner/work-runtime-local.js +109 -0
- package/dist/planner/work-runtime-local.spec.js +193 -0
- package/dist/planner/work-service-id.js +15 -5
- package/dist/planner/work-source.js +3 -0
- package/dist/planner/work-task.js +8 -0
- package/dist/program-commands.spec.js +84 -0
- package/dist/program.js +219 -73
- package/dist/program.spec.js +34 -11
- package/dist/run-program.js +28 -0
- package/dist/{executer/process.js → runtime/runtime.js} +1 -1
- package/dist/schema/build-file-base-task-schema.js +27 -0
- package/dist/schema/build-file-container-service-schema.js +28 -0
- package/dist/schema/build-file-container-task-schema.js +13 -0
- package/dist/schema/build-file-environment-schema-ingress.js +14 -0
- package/dist/schema/build-file-environment-schema.js +23 -0
- package/dist/schema/build-file-kubernetes-service-schema.js +17 -0
- package/dist/schema/build-file-kubernetes-service-selector-schema.js +9 -0
- package/dist/schema/build-file-local-platform-schema.js +9 -0
- package/dist/schema/build-file-local-task-schema.js +12 -0
- package/dist/schema/build-file-need-schema.js +12 -0
- package/dist/schema/build-file-schema.js +23 -0
- package/dist/schema/build-file-schema.spec.js +61 -0
- package/dist/schema/build-file-service-container-healthcheck.js +8 -0
- package/dist/schema/build-file-service-schema.js +15 -0
- package/dist/schema/build-file-task-command-schema.js +12 -0
- package/dist/schema/build-file-task-schema.js +12 -0
- package/dist/schema/build-file-volume-schema.js +14 -0
- package/dist/schema/cache-schema.js +31 -0
- package/dist/schema/doc-build-files.spec.js +223 -0
- package/dist/schema/envs-schema.js +6 -0
- package/dist/schema/labels-schema.js +6 -0
- package/dist/schema/parse-context.js +3 -0
- package/dist/schema/parse-error.js +12 -0
- package/dist/schema/parse-error.spec.js +18 -0
- package/dist/schema/reference-parser.js +209 -0
- package/dist/schema/reference-parser.spec.js +83 -0
- package/dist/schema/schema-parser.js +66 -0
- package/dist/schema/schema-parser.spec.js +80 -0
- package/dist/schema/type-guards.spec.js +23 -0
- package/dist/schema/work-scope-parser.js +77 -0
- package/dist/schema/work-scope-parser.spec.js +66 -0
- package/dist/service/update-service-status.js +11 -0
- package/dist/service/update-service-status.spec.js +27 -0
- package/dist/testing/ensure-local-registry.js +134 -0
- package/dist/testing/example-test-suite.js +16 -18
- package/dist/testing/expect.js +46 -22
- package/dist/testing/http-get.js +21 -0
- package/dist/testing/integration/cache.spec.js +13 -14
- package/dist/testing/integration/cancellation.spec.js +14 -9
- package/dist/testing/integration/clean.spec.js +14 -11
- package/dist/testing/integration/cmd.spec.js +1 -1
- package/dist/testing/integration/concurrency.spec.js +3 -3
- package/dist/testing/integration/docker-package-registry.spec.js +44 -0
- package/dist/testing/integration/docker-service-crash.spec.js +36 -0
- package/dist/testing/integration/docker.spec.js +4 -3
- package/dist/testing/integration/env.spec.js +9 -8
- package/dist/testing/integration/environment.spec.js +97 -0
- package/dist/testing/integration/error.spec.js +5 -4
- package/dist/testing/integration/export.spec.js +22 -0
- package/dist/testing/integration/extend.spec.js +9 -12
- package/dist/testing/integration/glob.spec.js +12 -20
- package/dist/testing/integration/include.spec.js +3 -3
- package/dist/testing/integration/invalid.spec.js +2 -3
- package/dist/testing/integration/invalid_loop.spec.js +49 -6
- package/dist/testing/integration/k8s-state-cache.spec.js +41 -0
- package/dist/testing/integration/kubernetes-service.spec.js +148 -0
- package/dist/testing/integration/kubernetes.spec.js +93 -9
- package/dist/testing/integration/labels.spec.js +6 -11
- package/dist/testing/integration/local.spec.js +1 -1
- package/dist/testing/integration/monorepo.spec.js +4 -4
- package/dist/testing/integration/multi-line.spec.js +3 -3
- package/dist/testing/integration/reference.spec.js +4 -5
- package/dist/testing/integration/services.spec.js +22 -4
- package/dist/testing/integration/store.spec.js +15 -16
- package/dist/testing/integration/unknown.spec.js +20 -18
- package/dist/testing/integration/validate.spec.js +143 -26
- package/dist/testing/integration/watch-dependency.spec.js +11 -8
- package/dist/testing/integration/watch.spec.js +15 -16
- package/dist/testing/requires-kubernetes.js +18 -0
- package/dist/testing/requires-linux-containers.js +18 -0
- package/dist/testing/requires-windows-containers.js +18 -0
- package/dist/testing/test-case.js +75 -0
- package/dist/testing/test-streams.js +28 -0
- package/dist/testing/testing-timeout.js +32 -0
- package/dist/utils/abort-event.js +10 -4
- package/dist/utils/abort-event.spec.js +46 -0
- package/dist/utils/buffer-context.js +44 -0
- package/dist/utils/buffer-context.spec.js +38 -0
- package/dist/utils/ci.spec.js +53 -0
- package/dist/utils/emitter.spec.js +34 -0
- package/dist/utils/empty-writable.spec.js +18 -0
- package/dist/utils/environment-config.js +4 -1
- package/dist/utils/environment-config.spec.js +26 -0
- package/dist/utils/fail-never.spec.js +9 -0
- package/dist/version.js +9 -0
- package/dist/version.spec.js +12 -0
- package/package.json +41 -23
- package/specs/build-file/caches/spec.md +114 -0
- package/specs/build-file/environment-variables/spec.md +82 -0
- package/specs/build-file/includes/spec.md +60 -0
- package/specs/build-file/references/spec.md +56 -0
- package/specs/build-file/spec.md +62 -0
- package/specs/cli/clean/spec.md +85 -0
- package/specs/cli/down/spec.md +85 -0
- package/specs/cli/execute/spec.md +101 -0
- package/specs/cli/init/spec.md +64 -0
- package/specs/cli/ls/spec.md +66 -0
- package/specs/cli/package/spec.md +110 -0
- package/specs/cli/spec.md +73 -0
- package/specs/cli/store-restore/spec.md +74 -0
- package/specs/cli/up/spec.md +80 -0
- package/specs/cli/validate/spec.md +70 -0
- package/specs/labels/spec.md +91 -0
- package/specs/service/container/spec.md +120 -0
- package/specs/service/kubernetes/spec.md +97 -0
- package/specs/service/spec.md +105 -0
- package/specs/task/caching/spec.md +107 -0
- package/specs/task/container/spec.md +118 -0
- package/specs/task/dependencies/spec.md +70 -0
- package/specs/task/extending/spec.md +74 -0
- package/specs/task/kubernetes/spec.md +125 -0
- package/specs/task/needs/spec.md +59 -0
- package/specs/task/spec.md +87 -0
- package/specs/task/watching/spec.md +69 -0
- package/dist/console/console-context-mock.js +0 -14
- package/dist/environment/get-process-env.js +0 -15
- package/dist/executer/create-scheduler-state.js +0 -32
- package/dist/executer/docker-node.js +0 -123
- package/dist/executer/hierarchy-scheduler.js +0 -94
- package/dist/executer/local-node.js +0 -57
- package/dist/executer/schedule.js +0 -137
- package/dist/executer/start-node.js +0 -67
- package/dist/executer/watch-node.js +0 -56
- package/dist/executer/watch-service.js +0 -54
- package/dist/file/get-file-context-mock.js +0 -187
- package/dist/file/get-file-context-mock.spec.js +0 -56
- package/dist/get-work-context.js +0 -29
- package/dist/optimizer/get-work-node-cache-stats.js +0 -104
- package/dist/optimizer/read-work-node-cache.js +0 -19
- package/dist/optimizer/work-node-cache-description.js +0 -32
- package/dist/optimizer/write-work-node-cache.js +0 -21
- package/dist/parser/build-file-task-command.js +0 -3
- package/dist/parser/build-file-task-platform.js +0 -3
- package/dist/parser/build-file-task-source.js +0 -3
- package/dist/parser/get-build-file.js +0 -9
- package/dist/parser/parse-boolean.js +0 -29
- package/dist/parser/parse-boolean.spec.js +0 -48
- package/dist/parser/parse-build-file-references.js +0 -35
- package/dist/parser/parse-build-file-services.js +0 -58
- package/dist/parser/parse-build-file-task-command.js +0 -36
- package/dist/parser/parse-build-file-task-source.js +0 -63
- package/dist/parser/parse-build-file.js +0 -125
- package/dist/parser/parse-context.js +0 -13
- package/dist/parser/parse-envs.js +0 -29
- package/dist/parser/parse-healthcheck.js +0 -28
- package/dist/parser/parse-service-selector.js +0 -39
- package/dist/parser/parse-string-array.js +0 -20
- package/dist/parser/parse-string-map.js +0 -30
- package/dist/parser/parse-string.js +0 -20
- package/dist/planner/utils/get-container-mounts.js +0 -24
- package/dist/planner/utils/parse-work-service-volume.js +0 -23
- package/dist/planner/utils/plan-work-command.js +0 -21
- package/dist/planner/utils/plan-work-dependency.js +0 -36
- package/dist/planner/utils/plan-work-node.js +0 -293
- package/dist/planner/utils/plan-work-nodes.js +0 -78
- package/dist/planner/utils/plan-work-tree.js +0 -15
- package/dist/planner/work-context.js +0 -23
- package/dist/planner/work-node-command.js +0 -3
- package/dist/planner/work-node-id.js +0 -12
- package/dist/planner/work-node-id.spec.js +0 -106
- package/dist/planner/work-node-path.js +0 -2
- package/dist/planner/work-node-source.js +0 -3
- package/dist/planner/work-node-validation.js +0 -3
- package/dist/planner/work-node.js +0 -8
- package/dist/planner/work-service-volume.js +0 -3
- package/dist/planner/work-services.js +0 -3
- package/dist/start-watch-processes.js +0 -28
- package/dist/testing/cli.js +0 -73
- package/dist/testing/create-build-file.js +0 -9
- package/dist/testing/get-logger.js +0 -23
- package/dist/testing/get-node.js +0 -12
- package/dist/testing/get-test-context.js +0 -19
- package/dist/testing/integration/program.spec.js +0 -25
- package/dist/testing/lazy.js +0 -17
- package/dist/testing/start-watch-processes.js +0 -29
- package/dist/testing/test-suite-options.js +0 -3
- package/dist/utils/abortable-function.js +0 -71
- package/logs/cache-console.log +0 -0
- package/logs/cache-status.log +0 -6
- package/logs/cache-stout.log +0 -0
- package/logs/cancellation-console.log +0 -0
- package/logs/cancellation-status.log +0 -3
- package/logs/cancellation-stout.log +0 -3
- package/logs/clean-console.log +0 -0
- package/logs/clean-status.log +0 -37
- package/logs/clean-stout.log +0 -95
- package/logs/cmd-console.log +0 -0
- package/logs/cmd-status.log +0 -8
- package/logs/cmd-stout.log +0 -9
- package/logs/concurrency-console.log +0 -0
- package/logs/concurrency-status.log +0 -14
- package/logs/concurrency-stout.log +0 -88
- package/logs/docker-console.log +0 -0
- package/logs/docker-status.log +0 -14
- package/logs/docker-stout.log +0 -39
- package/logs/env-console.log +0 -1
- package/logs/env-status.log +0 -1
- package/logs/env-stout.log +0 -0
- package/logs/error-console.log +0 -0
- package/logs/error-status.log +0 -10
- package/logs/error-stout.log +0 -36
- package/logs/extend-console.log +0 -0
- package/logs/extend-status.log +0 -1
- package/logs/extend-stout.log +0 -0
- package/logs/glob-console.log +0 -28
- package/logs/glob-status.log +0 -23
- package/logs/glob-stout.log +0 -52
- package/logs/hello-world-node-console.log +0 -0
- package/logs/hello-world-node-status.log +0 -37
- package/logs/hello-world-node-stout.log +0 -41
- package/logs/include-console.log +0 -0
- package/logs/include-status.log +0 -3
- package/logs/include-stout.log +0 -0
- package/logs/invalid-console.log +0 -0
- package/logs/invalid-status.log +0 -1
- package/logs/invalid-stout.log +0 -0
- package/logs/invalid_loop-console.log +0 -0
- package/logs/invalid_loop-status.log +0 -1
- package/logs/invalid_loop-stout.log +0 -11
- package/logs/labels-console.log +0 -0
- package/logs/labels-status.log +0 -1
- package/logs/labels-stout.log +0 -0
- package/logs/local-console.log +0 -0
- package/logs/local-status.log +0 -7
- package/logs/local-stout.log +0 -8
- package/logs/monorepo-console.log +0 -0
- package/logs/monorepo-status.log +0 -152
- package/logs/monorepo-stout.log +0 -2354
- package/logs/multi-line-console.log +0 -0
- package/logs/multi-line-status.log +0 -1
- package/logs/multi-line-stout.log +0 -0
- package/logs/reference-console.log +0 -0
- package/logs/reference-status.log +0 -5
- package/logs/reference-stout.log +0 -0
- package/logs/services-console.log +0 -0
- package/logs/services-status.log +0 -129
- package/logs/services-stout.log +0 -639
- package/logs/store-restore-console.log +0 -0
- package/logs/store-restore-status.log +0 -40
- package/logs/store-restore-stout.log +0 -97
- package/logs/unknown-console.log +0 -3
- package/logs/unknown-status.log +0 -1
- package/logs/unknown-stout.log +0 -0
- package/logs/validate-console.log +0 -0
- package/logs/validate-status.log +0 -2
- package/logs/validate-stout.log +0 -0
- package/logs/watch-console.log +0 -0
- package/logs/watch-dependency-console.log +0 -0
- package/logs/watch-dependency-status.log +0 -176
- package/logs/watch-dependency-stout.log +0 -779
- package/logs/watch-status.log +0 -100
- package/logs/watch-stout.log +0 -349
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileKubernetesServiceSelectorSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.buildFileKubernetesServiceSelectorSchema = (0, zod_1.object)({
|
|
6
|
+
type: (0, zod_1.string)(),
|
|
7
|
+
name: (0, zod_1.string)(),
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=build-file-kubernetes-service-selector-schema.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileLocalPlatformSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.buildFileLocalPlatformSchema = (0, zod_1.object)({
|
|
6
|
+
os: (0, zod_1.union)([(0, zod_1.literal)('win'), (0, zod_1.literal)('macos'), (0, zod_1.literal)('linux')]).optional(),
|
|
7
|
+
arch: (0, zod_1.union)([(0, zod_1.literal)('arm64'), (0, zod_1.literal)('arm')]).optional(),
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=build-file-local-platform-schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileLocalTaskSchema = void 0;
|
|
4
|
+
const build_file_base_task_schema_1 = require("./build-file-base-task-schema");
|
|
5
|
+
const build_file_local_platform_schema_1 = require("./build-file-local-platform-schema");
|
|
6
|
+
exports.buildFileLocalTaskSchema = build_file_base_task_schema_1.buildFileBaseTaskSchema
|
|
7
|
+
.extend({
|
|
8
|
+
platform: build_file_local_platform_schema_1.buildFileLocalPlatformSchema.optional(),
|
|
9
|
+
})
|
|
10
|
+
.strict()
|
|
11
|
+
.describe('local task');
|
|
12
|
+
//# sourceMappingURL=build-file-local-task-schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileNeedSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.buildFileNeedSchema = (0, zod_1.union)([
|
|
6
|
+
(0, zod_1.string)(),
|
|
7
|
+
(0, zod_1.object)({
|
|
8
|
+
service: (0, zod_1.string)(),
|
|
9
|
+
name: (0, zod_1.string)(),
|
|
10
|
+
}),
|
|
11
|
+
]);
|
|
12
|
+
//# sourceMappingURL=build-file-need-schema.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const envs_schema_1 = require("./envs-schema");
|
|
6
|
+
const build_file_service_schema_1 = require("./build-file-service-schema");
|
|
7
|
+
const build_file_environment_schema_1 = require("./build-file-environment-schema");
|
|
8
|
+
const build_file_task_schema_1 = require("./build-file-task-schema");
|
|
9
|
+
const labels_schema_1 = require("./labels-schema");
|
|
10
|
+
const cache_schema_1 = require("./cache-schema");
|
|
11
|
+
exports.buildFileSchema = (0, zod_1.object)({
|
|
12
|
+
envs: envs_schema_1.envsSchema.optional(),
|
|
13
|
+
tasks: (0, zod_1.record)(build_file_task_schema_1.buildFileTaskSchema).optional(),
|
|
14
|
+
services: (0, zod_1.record)(build_file_service_schema_1.buildFileServiceSchema).optional(),
|
|
15
|
+
references: (0, zod_1.record)((0, zod_1.string)()).optional(),
|
|
16
|
+
includes: (0, zod_1.record)((0, zod_1.string)()).optional(),
|
|
17
|
+
environments: (0, zod_1.record)(build_file_environment_schema_1.buildFileEnvironmentSchema).optional(),
|
|
18
|
+
caches: (0, zod_1.record)(cache_schema_1.buildFileCacheSchema).optional(),
|
|
19
|
+
labels: labels_schema_1.labelsSchema.optional(),
|
|
20
|
+
})
|
|
21
|
+
.strict()
|
|
22
|
+
.describe('Build file with support for containerization\nhttps://no0dles.gitbook.io/hammerkit/build-file');
|
|
23
|
+
//# sourceMappingURL=build-file-schema.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const build_file_schema_1 = require("./build-file-schema");
|
|
4
|
+
function parse(input) {
|
|
5
|
+
return build_file_schema_1.buildFileSchema.safeParseAsync(input);
|
|
6
|
+
}
|
|
7
|
+
describe('buildFileSchema', () => {
|
|
8
|
+
describe('container services', () => {
|
|
9
|
+
it('accepts a service without ports (reachable via needs/DNS)', async () => {
|
|
10
|
+
const result = await parse({
|
|
11
|
+
services: { postgres: { image: 'postgres:12-alpine', healthcheck: { cmd: 'pg_isready -U postgres' } } },
|
|
12
|
+
});
|
|
13
|
+
expect(result.success).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it('accepts a service with numeric and string ports', async () => {
|
|
16
|
+
const result = await parse({ services: { api: { image: 'node:alpine', ports: [':3000', 8080] } } });
|
|
17
|
+
expect(result.success).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('rejects a service that is neither a container nor a kubernetes service', async () => {
|
|
20
|
+
const result = await parse({ services: { broken: { ports: [80] } } });
|
|
21
|
+
expect(result.success).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('kubernetes services', () => {
|
|
25
|
+
it('accepts a service with a selector', async () => {
|
|
26
|
+
const result = await parse({
|
|
27
|
+
services: { db: { selector: { type: 'deployment', name: 'db' }, ports: [5432] } },
|
|
28
|
+
});
|
|
29
|
+
expect(result.success).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe('continuous tasks', () => {
|
|
33
|
+
it('accepts a container task marked continuous', async () => {
|
|
34
|
+
const result = await parse({ tasks: { serve: { image: 'node:16', continuous: true, cmds: ['ng serve'] } } });
|
|
35
|
+
expect(result.success).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it('accepts a local task marked continuous', async () => {
|
|
38
|
+
const result = await parse({ tasks: { serve: { continuous: true, cmds: ['ng serve'] } } });
|
|
39
|
+
expect(result.success).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
it('rejects a non-boolean continuous', async () => {
|
|
42
|
+
const result = await parse({ tasks: { serve: { continuous: 'yes', cmds: ['x'] } } });
|
|
43
|
+
expect(result.success).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe('strictness', () => {
|
|
47
|
+
it('rejects unknown top-level keys', async () => {
|
|
48
|
+
const result = await parse({ bogus: true });
|
|
49
|
+
expect(result.success).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
it('rejects unknown task keys', async () => {
|
|
52
|
+
const result = await parse({ tasks: { build: { cmds: ['x'], bogus: 1 } } });
|
|
53
|
+
expect(result.success).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
it('accepts an empty build file', async () => {
|
|
56
|
+
const result = await parse({});
|
|
57
|
+
expect(result.success).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=build-file-schema.spec.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileServiceContainerHealthcheck = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.buildFileServiceContainerHealthcheck = (0, zod_1.object)({
|
|
6
|
+
cmd: (0, zod_1.string)(),
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=build-file-service-container-healthcheck.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isBuildFileContainerSchema = exports.isBuildFileKubernetesServiceSchema = exports.buildFileServiceSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const build_file_container_service_schema_1 = require("./build-file-container-service-schema");
|
|
6
|
+
const build_file_kubernetes_service_schema_1 = require("./build-file-kubernetes-service-schema");
|
|
7
|
+
exports.buildFileServiceSchema = (0, zod_1.union)([
|
|
8
|
+
build_file_container_service_schema_1.buildFileContainerServiceSchema,
|
|
9
|
+
build_file_kubernetes_service_schema_1.buildFileKubernetesServiceSchema,
|
|
10
|
+
]).describe('service');
|
|
11
|
+
const isBuildFileKubernetesServiceSchema = (val) => 'selector' in val;
|
|
12
|
+
exports.isBuildFileKubernetesServiceSchema = isBuildFileKubernetesServiceSchema;
|
|
13
|
+
const isBuildFileContainerSchema = (val) => 'image' in val;
|
|
14
|
+
exports.isBuildFileContainerSchema = isBuildFileContainerSchema;
|
|
15
|
+
//# sourceMappingURL=build-file-service-schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileTaskCommandSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.buildFileTaskCommandSchema = (0, zod_1.union)([
|
|
6
|
+
(0, zod_1.string)(),
|
|
7
|
+
(0, zod_1.object)({
|
|
8
|
+
cmd: (0, zod_1.string)(),
|
|
9
|
+
path: (0, zod_1.string)().optional(),
|
|
10
|
+
}),
|
|
11
|
+
]);
|
|
12
|
+
//# sourceMappingURL=build-file-task-command-schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isBuildFileLocalTaskSchema = exports.isBuildFileContainerTaskSchema = exports.buildFileTaskSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const build_file_container_task_schema_1 = require("./build-file-container-task-schema");
|
|
6
|
+
const build_file_local_task_schema_1 = require("./build-file-local-task-schema");
|
|
7
|
+
exports.buildFileTaskSchema = (0, zod_1.union)([build_file_container_task_schema_1.buildFileContainerTaskSchema, build_file_local_task_schema_1.buildFileLocalTaskSchema]);
|
|
8
|
+
const isBuildFileContainerTaskSchema = (val) => 'image' in val;
|
|
9
|
+
exports.isBuildFileContainerTaskSchema = isBuildFileContainerTaskSchema;
|
|
10
|
+
const isBuildFileLocalTaskSchema = (val) => !('image' in val);
|
|
11
|
+
exports.isBuildFileLocalTaskSchema = isBuildFileLocalTaskSchema;
|
|
12
|
+
//# sourceMappingURL=build-file-task-schema.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFileVolumeSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.buildFileVolumeSchema = (0, zod_1.union)([
|
|
6
|
+
(0, zod_1.string)(),
|
|
7
|
+
(0, zod_1.object)({
|
|
8
|
+
export: (0, zod_1.boolean)().optional(),
|
|
9
|
+
resetOnChange: (0, zod_1.boolean)().optional(),
|
|
10
|
+
path: (0, zod_1.string)(),
|
|
11
|
+
name: (0, zod_1.string)().optional(),
|
|
12
|
+
}),
|
|
13
|
+
]);
|
|
14
|
+
//# sourceMappingURL=build-file-volume-schema.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cacheSchema = exports.taskCacheRefSchema = exports.buildFileCacheSchema = exports.cacheBackendSchema = exports.cacheBackendS3Schema = exports.cacheBackendLocalSchema = exports.cacheMethodSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.cacheMethodSchema = (0, zod_1.union)([(0, zod_1.literal)('checksum'), (0, zod_1.literal)('modify-date'), (0, zod_1.literal)('none')]);
|
|
6
|
+
exports.cacheBackendLocalSchema = (0, zod_1.object)({
|
|
7
|
+
type: (0, zod_1.literal)('local'),
|
|
8
|
+
path: (0, zod_1.string)().optional(),
|
|
9
|
+
}).strict();
|
|
10
|
+
exports.cacheBackendS3Schema = (0, zod_1.object)({
|
|
11
|
+
type: (0, zod_1.literal)('s3'),
|
|
12
|
+
bucket: (0, zod_1.string)(),
|
|
13
|
+
region: (0, zod_1.string)().optional(),
|
|
14
|
+
endpoint: (0, zod_1.string)().optional(),
|
|
15
|
+
prefix: (0, zod_1.string)().optional(),
|
|
16
|
+
forcePathStyle: zod_1.z.boolean().optional(),
|
|
17
|
+
}).strict();
|
|
18
|
+
exports.cacheBackendSchema = (0, zod_1.union)([exports.cacheBackendLocalSchema, exports.cacheBackendS3Schema]);
|
|
19
|
+
exports.buildFileCacheSchema = (0, zod_1.object)({
|
|
20
|
+
method: exports.cacheMethodSchema,
|
|
21
|
+
backend: exports.cacheBackendSchema,
|
|
22
|
+
}).strict();
|
|
23
|
+
exports.taskCacheRefSchema = (0, zod_1.union)([
|
|
24
|
+
exports.cacheMethodSchema,
|
|
25
|
+
(0, zod_1.object)({
|
|
26
|
+
name: (0, zod_1.string)(),
|
|
27
|
+
method: exports.cacheMethodSchema.optional(),
|
|
28
|
+
}).strict(),
|
|
29
|
+
]);
|
|
30
|
+
exports.cacheSchema = exports.taskCacheRefSchema;
|
|
31
|
+
//# sourceMappingURL=cache-schema.js.map
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fs_1 = require("fs");
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
const yaml_1 = require("yaml");
|
|
6
|
+
const build_file_schema_1 = require("./build-file-schema");
|
|
7
|
+
/*
|
|
8
|
+
* Documentation coverage: every hammerkit build-file example that ships in the
|
|
9
|
+
* docs must stay valid against the real schema, so the docs cannot silently
|
|
10
|
+
* drift to config the tool would reject.
|
|
11
|
+
*
|
|
12
|
+
* The harness is self-discovering: it walks docs/ at collection time and turns
|
|
13
|
+
* every fenced ```yaml block into its own assertion. A block is treated as a
|
|
14
|
+
* hammerkit build file when it parses to an object whose top-level keys are all
|
|
15
|
+
* part of the schema (envs/tasks/services/...). Anything else (a GitLab/GitHub
|
|
16
|
+
* CI snippet, a design-doc proposal) is "foreign" and must be listed in
|
|
17
|
+
* FOREIGN_BLOCKS with a reason — a foreign block that is NOT listed fails the
|
|
18
|
+
* audit, so a new build-file example is validated rather than quietly ignored,
|
|
19
|
+
* and a typo'd example (unknown key) is surfaced instead of skipped.
|
|
20
|
+
*/
|
|
21
|
+
const repoRoot = (0, path_1.join)(__dirname, '..', '..');
|
|
22
|
+
const docsDir = (0, path_1.join)(repoRoot, 'docs');
|
|
23
|
+
const bestPracticesDir = (0, path_1.join)(repoRoot, 'best-practices');
|
|
24
|
+
// Top-level keys the build-file schema understands. Mirrors buildFileSchema's
|
|
25
|
+
// shape; kept here only to classify "is this block a hammerkit build file at all".
|
|
26
|
+
const KNOWN_TOP_KEYS = new Set([
|
|
27
|
+
'envs',
|
|
28
|
+
'tasks',
|
|
29
|
+
'services',
|
|
30
|
+
'references',
|
|
31
|
+
'includes',
|
|
32
|
+
'environments',
|
|
33
|
+
'caches',
|
|
34
|
+
'labels',
|
|
35
|
+
]);
|
|
36
|
+
// A doc block can declare itself intentionally invalid by putting this comment
|
|
37
|
+
// on its first line; the harness then asserts the schema REJECTS it.
|
|
38
|
+
const EXPECT_INVALID = '# hammerkit:expect-invalid';
|
|
39
|
+
// Directories that document a specific past version, not the current build-file
|
|
40
|
+
// reference. Their snippets are expected to use the syntax of their release and
|
|
41
|
+
// must not be validated against today's schema.
|
|
42
|
+
const HISTORICAL_DIRS = ['release-blog', 'change-log'];
|
|
43
|
+
// yaml blocks in docs/ that are deliberately NOT hammerkit build files. Each is
|
|
44
|
+
// matched by a unique snippet of its body. Keep the reason — these are the only
|
|
45
|
+
// blocks allowed to be unrecognized.
|
|
46
|
+
const FOREIGN_BLOCKS = [
|
|
47
|
+
{
|
|
48
|
+
file: (0, path_1.join)('installation.md'),
|
|
49
|
+
snippet: 'DOCKER_DRIVER',
|
|
50
|
+
reason: 'GitLab CI (.gitlab-ci.yml) example, not a hammerkit build file',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
file: (0, path_1.join)('installation.md'),
|
|
54
|
+
snippet: 'no0dles/hammerkit-github-action',
|
|
55
|
+
reason: 'GitHub Actions workflow example, not a hammerkit build file',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
file: (0, path_1.join)('cli', 'store-restore.md'),
|
|
59
|
+
snippet: 'before_script',
|
|
60
|
+
reason: 'GitLab CI (gitlab-ci.yml) caching example, not a hammerkit build file',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
file: (0, path_1.join)('guides', 'ci-caching.md'),
|
|
64
|
+
snippet: 'actions/cache@v4',
|
|
65
|
+
reason: 'GitHub Actions workflow example, not a hammerkit build file',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
file: (0, path_1.join)('contribution', 'secret-managers.md'),
|
|
69
|
+
snippet: 'secret://vault',
|
|
70
|
+
reason: 'design-doc proposal for an unimplemented secrets: provider; not valid against the current schema',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
function walkMarkdown(dir) {
|
|
74
|
+
const out = [];
|
|
75
|
+
for (const entry of (0, fs_1.readdirSync)(dir, { withFileTypes: true })) {
|
|
76
|
+
const full = (0, path_1.join)(dir, entry.name);
|
|
77
|
+
if (entry.isDirectory()) {
|
|
78
|
+
out.push(...walkMarkdown(full));
|
|
79
|
+
}
|
|
80
|
+
else if (entry.name.endsWith('.md')) {
|
|
81
|
+
out.push(full);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
// Extract the body of every fenced ```yaml / ```yml block. GitBook's
|
|
87
|
+
// `{% code %}` wrappers and `{% hint %}`/`{% tabs %}` around a block are
|
|
88
|
+
// irrelevant — only the fence matters.
|
|
89
|
+
function extractYamlBlocks(content) {
|
|
90
|
+
const lines = content.split(/\r?\n/);
|
|
91
|
+
const blocks = [];
|
|
92
|
+
for (let i = 0; i < lines.length; i++) {
|
|
93
|
+
if (!/^\s*```ya?ml\s*$/.test(lines[i])) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const start = i + 1;
|
|
97
|
+
const body = [];
|
|
98
|
+
let j = start;
|
|
99
|
+
while (j < lines.length && !/^\s*```\s*$/.test(lines[j])) {
|
|
100
|
+
body.push(lines[j]);
|
|
101
|
+
j++;
|
|
102
|
+
}
|
|
103
|
+
blocks.push({ body: body.join('\n'), startLine: start + 1 });
|
|
104
|
+
i = j;
|
|
105
|
+
}
|
|
106
|
+
return blocks;
|
|
107
|
+
}
|
|
108
|
+
function firstNonEmptyLine(body) {
|
|
109
|
+
for (const line of body.split(/\r?\n/)) {
|
|
110
|
+
if (line.trim() !== '') {
|
|
111
|
+
return line.trim();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return '';
|
|
115
|
+
}
|
|
116
|
+
// A block is a hammerkit build file when it parses to a non-empty object whose
|
|
117
|
+
// top-level keys are all part of the schema.
|
|
118
|
+
function isBuildFileShaped(parsed) {
|
|
119
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
const keys = Object.keys(parsed);
|
|
123
|
+
return keys.length > 0 && keys.every((k) => KNOWN_TOP_KEYS.has(k));
|
|
124
|
+
}
|
|
125
|
+
const docFiles = walkMarkdown(docsDir).sort();
|
|
126
|
+
const allBlocks = [];
|
|
127
|
+
for (const file of docFiles) {
|
|
128
|
+
const relFile = (0, path_1.relative)(docsDir, file);
|
|
129
|
+
const topDir = relFile.split(/[\\/]/)[0];
|
|
130
|
+
if (HISTORICAL_DIRS.includes(topDir)) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
extractYamlBlocks((0, fs_1.readFileSync)(file, 'utf8')).forEach((block, index) => {
|
|
134
|
+
allBlocks.push({ ...block, relFile, index });
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const foreignMatches = new Set();
|
|
138
|
+
let buildFileBlockCount = 0;
|
|
139
|
+
describe('docs build-file examples', () => {
|
|
140
|
+
// Group assertions per doc file for readable failures.
|
|
141
|
+
const byFile = new Map();
|
|
142
|
+
for (const block of allBlocks) {
|
|
143
|
+
const list = byFile.get(block.relFile) ?? [];
|
|
144
|
+
list.push(block);
|
|
145
|
+
byFile.set(block.relFile, list);
|
|
146
|
+
}
|
|
147
|
+
for (const [relFile, blocks] of byFile) {
|
|
148
|
+
describe(relFile, () => {
|
|
149
|
+
blocks.forEach((block) => {
|
|
150
|
+
const label = `yaml block at line ${block.startLine}`;
|
|
151
|
+
const foreignIndex = FOREIGN_BLOCKS.findIndex((f) => f.file === relFile && block.body.includes(f.snippet));
|
|
152
|
+
if (foreignIndex >= 0) {
|
|
153
|
+
foreignMatches.add(foreignIndex);
|
|
154
|
+
it(`${label} is a documented non-hammerkit block`, () => {
|
|
155
|
+
// Listed in FOREIGN_BLOCKS with a reason — nothing to validate.
|
|
156
|
+
expect(FOREIGN_BLOCKS[foreignIndex].reason).toBeTruthy();
|
|
157
|
+
});
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (firstNonEmptyLine(block.body) === EXPECT_INVALID) {
|
|
161
|
+
it(`${label} is rejected by the schema (marked expect-invalid)`, async () => {
|
|
162
|
+
const parsed = (0, yaml_1.parse)(block.body);
|
|
163
|
+
const result = await build_file_schema_1.buildFileSchema.safeParseAsync(parsed);
|
|
164
|
+
expect(result.success).toBe(false);
|
|
165
|
+
});
|
|
166
|
+
buildFileBlockCount++;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
it(`${label} is a valid build file`, async () => {
|
|
170
|
+
let parsed;
|
|
171
|
+
try {
|
|
172
|
+
parsed = (0, yaml_1.parse)(block.body);
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
throw new Error(`${relFile}:${block.startLine} is not valid YAML: ${e.message}`);
|
|
176
|
+
}
|
|
177
|
+
if (!isBuildFileShaped(parsed)) {
|
|
178
|
+
const keys = parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
179
|
+
? Object.keys(parsed).join(', ')
|
|
180
|
+
: typeof parsed;
|
|
181
|
+
throw new Error(`${relFile}:${block.startLine} is not a recognized hammerkit build file (top-level: ${keys}).\n` +
|
|
182
|
+
`If this is intentionally foreign yaml (a CI config, a proposal), add it to FOREIGN_BLOCKS with a reason.\n` +
|
|
183
|
+
`Otherwise fix the example so its top-level keys are one of: ${[...KNOWN_TOP_KEYS].join(', ')}.`);
|
|
184
|
+
}
|
|
185
|
+
const result = await build_file_schema_1.buildFileSchema.safeParseAsync(parsed);
|
|
186
|
+
if (!result.success) {
|
|
187
|
+
throw new Error(`${relFile}:${block.startLine} fails the build-file schema:\n` +
|
|
188
|
+
result.error.issues.map((iss) => ` - ${iss.path.join('.')}: ${iss.message}`).join('\n'));
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
buildFileBlockCount++;
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// Guard against a regex/discovery regression silently matching nothing, and
|
|
196
|
+
// against a build-file example dropping out of validation unnoticed.
|
|
197
|
+
it('discovers the documented build-file examples', () => {
|
|
198
|
+
expect(buildFileBlockCount).toBeGreaterThanOrEqual(60);
|
|
199
|
+
});
|
|
200
|
+
// Every documented exclusion must still match a real block, so stale entries
|
|
201
|
+
// are removed when the doc changes.
|
|
202
|
+
it('has no stale FOREIGN_BLOCKS entries', () => {
|
|
203
|
+
const unmatched = FOREIGN_BLOCKS.filter((_, i) => !foreignMatches.has(i)).map((f) => `${f.file} (${f.snippet})`);
|
|
204
|
+
expect(unmatched).toEqual([]);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
describe('best-practices build configs', () => {
|
|
208
|
+
const files = (0, fs_1.readdirSync)(bestPracticesDir)
|
|
209
|
+
.filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))
|
|
210
|
+
.sort();
|
|
211
|
+
it('finds the best-practices templates', () => {
|
|
212
|
+
expect(files.length).toBeGreaterThanOrEqual(10);
|
|
213
|
+
});
|
|
214
|
+
it.each(files)('%s is a valid build file', async (name) => {
|
|
215
|
+
const parsed = (0, yaml_1.parse)((0, fs_1.readFileSync)((0, path_1.join)(bestPracticesDir, name), 'utf8'));
|
|
216
|
+
const result = await build_file_schema_1.buildFileSchema.safeParseAsync(parsed);
|
|
217
|
+
if (!result.success) {
|
|
218
|
+
throw new Error(`best-practices/${name} fails the build-file schema:\n` +
|
|
219
|
+
result.error.issues.map((iss) => ` - ${iss.path.join('.')}: ${iss.message}`).join('\n'));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
//# sourceMappingURL=doc-build-files.spec.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.envsSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.envsSchema = (0, zod_1.record)((0, zod_1.union)([(0, zod_1.string)(), (0, zod_1.number)()])).describe('Environment values for the current build task\nhttps://no0dles.gitbook.io/hammerkit/build-file/environment-variables');
|
|
6
|
+
//# sourceMappingURL=envs-schema.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.labelsSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
exports.labelsSchema = (0, zod_1.record)((0, zod_1.union)([(0, zod_1.string)(), (0, zod_1.number)()]));
|
|
6
|
+
//# sourceMappingURL=labels-schema.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ParseError = void 0;
|
|
4
|
+
class ParseError extends Error {
|
|
5
|
+
constructor(zod, buildFilePath) {
|
|
6
|
+
super('parse error');
|
|
7
|
+
this.zod = zod;
|
|
8
|
+
this.buildFilePath = buildFilePath;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.ParseError = ParseError;
|
|
12
|
+
//# sourceMappingURL=parse-error.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const zod_1 = require("zod");
|
|
4
|
+
const parse_error_1 = require("./parse-error");
|
|
5
|
+
describe('ParseError', () => {
|
|
6
|
+
it('wraps a ZodError with the offending build-file path', () => {
|
|
7
|
+
const result = zod_1.z.object({ name: zod_1.z.string() }).safeParse({});
|
|
8
|
+
if (result.success) {
|
|
9
|
+
throw new Error('precondition: expected the safeParse to fail');
|
|
10
|
+
}
|
|
11
|
+
const err = new parse_error_1.ParseError(result.error, '/work/.hammerkit.yaml');
|
|
12
|
+
expect(err).toBeInstanceOf(Error);
|
|
13
|
+
expect(err.zod).toBe(result.error);
|
|
14
|
+
expect(err.buildFilePath).toBe('/work/.hammerkit.yaml');
|
|
15
|
+
expect(err.message).toBe('parse error');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=parse-error.spec.js.map
|