hammerkit 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/build.schema.json +49 -2
- package/dist/cache/backends/local-cache-backend.js +58 -1
- package/dist/cache/backends/registry/registry-client.js +264 -0
- package/dist/cache/backends/registry/registry-credentials.js +81 -0
- package/dist/cache/backends/registry/registry-reference.js +36 -0
- package/dist/cache/backends/registry-cache-backend.js +145 -0
- package/dist/cache/backends/s3-cache-backend.js +99 -46
- package/dist/cache/cache-backend-registry.js +2 -0
- package/dist/cache/cache-inventory.js +84 -0
- package/dist/cache/cache-sync.js +77 -0
- package/dist/cache/explain.js +214 -0
- package/dist/cache/last-resolved.js +48 -0
- package/dist/cache/read-only.js +15 -0
- package/dist/cache/retention.js +61 -0
- package/dist/cli.js +43 -0
- package/dist/docker/using-container.js +5 -1
- package/dist/executer/archive-task-entry.js +21 -0
- package/dist/executer/await-completed-dependencies.js +32 -14
- package/dist/executer/cache-metadata.js +9 -2
- package/dist/executer/docker-service.js +2 -1
- package/dist/executer/docker-task.js +2 -1
- package/dist/executer/dry-run.js +73 -0
- package/dist/executer/event-cache.js +6 -5
- package/dist/executer/execute-command.js +21 -3
- package/dist/executer/execute-work-service.js +10 -1
- package/dist/executer/execute-work-task.js +95 -25
- package/dist/executer/execute-work-tree.js +26 -1
- package/dist/executer/get-scheduler-execute-result.js +4 -1
- package/dist/executer/lazy-resolver.js +15 -3
- package/dist/executer/reset-work-tree.js +2 -0
- package/dist/executer/run-summary.js +102 -0
- package/dist/executer/scheduler/enqueue-next.js +15 -60
- package/dist/executer/scheduler/state-key.js +78 -0
- package/dist/kubernetes/await-running-state.js +73 -19
- package/dist/log.js +16 -6
- package/dist/logging/live-logger.js +2 -1
- package/dist/optimizer/calculate-checksum.js +8 -2
- package/dist/optimizer/get-work-cache-stats.js +66 -16
- package/dist/optimizer/work-task-cache-description.js +34 -5
- package/dist/planner/project-root.js +26 -0
- package/dist/planner/utils/append-work-service.js +2 -1
- package/dist/planner/utils/append-work-task.js +7 -1
- package/dist/planner/utils/parse-work-source.js +35 -30
- package/dist/planner/utils/portable-path.js +30 -0
- package/dist/planner/work-cache-id.js +2 -2
- package/dist/planner/work-graph-serializer.js +103 -0
- package/dist/planner/work-instance-id.js +15 -0
- package/dist/planner/work-runtime-docker.js +53 -15
- package/dist/planner/work-runtime-kubernetes.js +35 -3
- package/dist/planner/work-runtime-local.js +9 -3
- package/dist/planner/work-service-id.js +16 -4
- package/dist/program.js +235 -1
- package/dist/schema/build-file-base-task-schema.js +4 -0
- package/dist/schema/cache-schema.js +21 -2
- package/dist/schema/duration-schema.js +18 -0
- package/dist/schema/reference-parser.js +3 -0
- package/dist/schema/size-schema.js +18 -0
- package/dist/schema/work-scope-parser.js +15 -2
- package/dist/utils/units.js +87 -0
- package/package.json +12 -1
- package/.agents/FEEDBACK.md +0 -74
- package/.agents/skills/before-commit/SKILL.md +0 -101
- package/.agents/skills/do-the-work/SKILL.md +0 -64
- package/.agents/skills/fix-ci/SKILL.md +0 -98
- package/.agents/skills/speckit-git-commit/SKILL.md +0 -53
- package/.agents/skills/speckit-git-feature/SKILL.md +0 -72
- package/.agents/skills/speckit-git-initialize/SKILL.md +0 -54
- package/.agents/skills/speckit-git-remote/SKILL.md +0 -50
- package/.agents/skills/speckit-git-validate/SKILL.md +0 -54
- package/.devcontainer/Dockerfile +0 -5
- package/.devcontainer/devcontainer.json +0 -40
- package/.gitbook.yaml +0 -5
- package/.specify/extensions/.registry +0 -37
- package/.specify/extensions/git/README.md +0 -100
- package/.specify/extensions/git/commands/speckit.git.commit.md +0 -48
- package/.specify/extensions/git/commands/speckit.git.feature.md +0 -67
- package/.specify/extensions/git/commands/speckit.git.initialize.md +0 -49
- package/.specify/extensions/git/commands/speckit.git.remote.md +0 -45
- package/.specify/extensions/git/commands/speckit.git.validate.md +0 -49
- package/.specify/extensions/git/config-template.yml +0 -62
- package/.specify/extensions/git/extension.yml +0 -140
- package/.specify/extensions/git/git-config.yml +0 -62
- package/.specify/extensions.yml +0 -149
- package/.specify/feature.json +0 -3
- package/.specify/init-options.json +0 -10
- package/.specify/integration.json +0 -15
- package/.specify/integrations/claude.manifest.json +0 -16
- package/.specify/integrations/speckit.manifest.json +0 -17
- package/.specify/memory/constitution.md +0 -162
- package/.specify/templates/checklist-template.md +0 -40
- package/.specify/templates/constitution-template.md +0 -50
- package/.specify/templates/plan-template.md +0 -113
- package/.specify/templates/spec-template.md +0 -131
- package/.specify/templates/tasks-template.md +0 -252
- package/.specify/workflows/speckit/workflow.yml +0 -77
- package/.specify/workflows/workflow-registry.json +0 -13
- package/AGENTS.md +0 -94
- package/Dockerfile +0 -32
- package/FOLLOWUPS.md +0 -34
- package/SUMMARY.md +0 -68
- package/VALUES.md +0 -53
- package/dist/cache/auto-pull.spec.js +0 -123
- package/dist/cache/backends/local-cache-backend.spec.js +0 -72
- package/dist/cache/backends/s3-cache-backend.spec.js +0 -118
- package/dist/cache/cache-backend-registry.spec.js +0 -22
- package/dist/cache/resolve-cache.spec.js +0 -52
- package/dist/cli.spec.js +0 -23
- package/dist/console/get-logger.spec.js +0 -23
- package/dist/docker/get-default-platform.spec.js +0 -29
- package/dist/docker/longest-common-prefix.spec.js +0 -26
- package/dist/docker/package.spec.js +0 -145
- package/dist/docker/remove-container.spec.js +0 -32
- package/dist/docker/using-container.spec.js +0 -90
- package/dist/environment/merge-environment-variables.spec.js +0 -24
- package/dist/environment/replace-env-variables.spec.js +0 -47
- package/dist/executer/abort.spec.js +0 -18
- package/dist/executer/environment-mock.spec.js +0 -22
- package/dist/executer/execute.spec.js +0 -51
- package/dist/executer/get-service-containers.spec.js +0 -59
- package/dist/executer/get-service-env-hints.spec.js +0 -65
- package/dist/executer/label-values.spec.js +0 -61
- package/dist/executer/lazy-resolver.spec.js +0 -20
- package/dist/executer/process-manager.spec.js +0 -54
- package/dist/executer/scheduler/enqueue-next.spec.js +0 -136
- package/dist/executer/state-resolver.spec.js +0 -37
- package/dist/executer/state.spec.js +0 -66
- package/dist/executer/states.spec.js +0 -14
- package/dist/file/get-file-context.spec.js +0 -178
- package/dist/file/move-files.spec.js +0 -48
- package/dist/kubernetes/ensure-http-route.spec.js +0 -70
- package/dist/kubernetes/ensure-namespace.spec.js +0 -39
- package/dist/kubernetes/resolve-pod-name.spec.js +0 -81
- package/dist/log.spec.js +0 -131
- package/dist/logging/grouped-logger.spec.js +0 -84
- package/dist/logging/interactive-logger.spec.js +0 -57
- package/dist/logging/live-logger.spec.js +0 -37
- package/dist/logging/loggers.spec.js +0 -154
- package/dist/optimizer/calculate-checksum.spec.js +0 -34
- package/dist/optimizer/get-cache-directory.spec.js +0 -59
- package/dist/optimizer/get-work-cache-stats.spec.js +0 -79
- package/dist/optimizer/work-task-cache-description.spec.js +0 -45
- package/dist/parser/default-build-file.spec.js +0 -48
- package/dist/parser/parse-label-arguments.spec.js +0 -27
- package/dist/parser/read-build-file.spec.js +0 -89
- package/dist/parser/read-env-file.spec.js +0 -42
- package/dist/planner/utils/append-work-service.spec.js +0 -71
- package/dist/planner/utils/get-container-user.spec.js +0 -30
- package/dist/planner/utils/get-default-kube-config.spec.js +0 -11
- package/dist/planner/utils/normalize-path.spec.js +0 -24
- package/dist/planner/utils/parse-work-command.spec.js +0 -21
- package/dist/planner/utils/parse-work-generate.spec.js +0 -45
- package/dist/planner/utils/parse-work-mount.spec.js +0 -62
- package/dist/planner/utils/parse-work-mounts.spec.js +0 -19
- package/dist/planner/utils/parse-work-port.spec.js +0 -24
- package/dist/planner/utils/parse-work-ports.spec.js +0 -24
- package/dist/planner/utils/parse-work-source.spec.js +0 -58
- package/dist/planner/utils/parse-work-volume.spec.js +0 -18
- package/dist/planner/utils/plan-work-tasks.spec.js +0 -30
- package/dist/planner/utils/plan-work-volume.spec.js +0 -33
- package/dist/planner/utils/split-name.spec.js +0 -16
- package/dist/planner/utils/template-value.spec.js +0 -14
- package/dist/planner/validate.spec.js +0 -251
- package/dist/planner/work-cache-id.spec.js +0 -173
- package/dist/planner/work-runtime-local.spec.js +0 -193
- package/dist/program-commands.spec.js +0 -84
- package/dist/program.spec.js +0 -43
- package/dist/schema/build-file-schema.spec.js +0 -61
- package/dist/schema/doc-build-files.spec.js +0 -223
- package/dist/schema/parse-error.spec.js +0 -18
- package/dist/schema/reference-parser.spec.js +0 -83
- package/dist/schema/schema-parser.spec.js +0 -80
- package/dist/schema/type-guards.spec.js +0 -23
- package/dist/schema/work-scope-parser.spec.js +0 -66
- package/dist/service/update-service-status.spec.js +0 -27
- package/dist/testing/ensure-local-registry.js +0 -134
- package/dist/testing/example-test-suite.js +0 -63
- package/dist/testing/expect.js +0 -82
- package/dist/testing/get-test-suite.js +0 -9
- package/dist/testing/http-get.js +0 -21
- package/dist/testing/integration/cache.spec.js +0 -49
- package/dist/testing/integration/cancellation.spec.js +0 -45
- package/dist/testing/integration/clean.spec.js +0 -43
- package/dist/testing/integration/cmd.spec.js +0 -15
- package/dist/testing/integration/concurrency.spec.js +0 -19
- package/dist/testing/integration/docker-package-registry.spec.js +0 -44
- package/dist/testing/integration/docker-service-crash.spec.js +0 -36
- package/dist/testing/integration/docker.spec.js +0 -18
- package/dist/testing/integration/env.spec.js +0 -48
- package/dist/testing/integration/environment.spec.js +0 -97
- package/dist/testing/integration/error.spec.js +0 -19
- package/dist/testing/integration/export.spec.js +0 -22
- package/dist/testing/integration/extend.spec.js +0 -29
- package/dist/testing/integration/glob.spec.js +0 -40
- package/dist/testing/integration/include.spec.js +0 -31
- package/dist/testing/integration/invalid.spec.js +0 -17
- package/dist/testing/integration/invalid_loop.spec.js +0 -56
- package/dist/testing/integration/k8s-state-cache.spec.js +0 -41
- package/dist/testing/integration/kubernetes-service.spec.js +0 -148
- package/dist/testing/integration/kubernetes.spec.js +0 -99
- package/dist/testing/integration/labels.spec.js +0 -42
- package/dist/testing/integration/local.spec.js +0 -14
- package/dist/testing/integration/monorepo.spec.js +0 -15
- package/dist/testing/integration/multi-line.spec.js +0 -17
- package/dist/testing/integration/reference.spec.js +0 -21
- package/dist/testing/integration/services.spec.js +0 -38
- package/dist/testing/integration/store.spec.js +0 -52
- package/dist/testing/integration/unknown.spec.js +0 -28
- package/dist/testing/integration/validate.spec.js +0 -160
- package/dist/testing/integration/watch-dependency.spec.js +0 -33
- package/dist/testing/integration/watch.spec.js +0 -45
- package/dist/testing/requires-kubernetes.js +0 -18
- package/dist/testing/requires-linux-containers.js +0 -18
- package/dist/testing/requires-windows-containers.js +0 -18
- package/dist/testing/test-case.js +0 -75
- package/dist/testing/test-streams.js +0 -28
- package/dist/testing/test-suite-setup.js +0 -3
- package/dist/testing/test-suite.js +0 -3
- package/dist/testing/testing-timeout.js +0 -32
- package/dist/utils/abort-event.spec.js +0 -46
- package/dist/utils/buffer-context.spec.js +0 -38
- package/dist/utils/ci.spec.js +0 -53
- package/dist/utils/debouncer.spec.js +0 -58
- package/dist/utils/emitter.spec.js +0 -34
- package/dist/utils/empty-writable.spec.js +0 -18
- package/dist/utils/environment-config.spec.js +0 -26
- package/dist/utils/fail-never.spec.js +0 -9
- package/dist/utils/sleep.spec.js +0 -22
- package/dist/version.spec.js +0 -12
- package/specs/build-file/caches/spec.md +0 -114
- package/specs/build-file/environment-variables/spec.md +0 -82
- package/specs/build-file/includes/spec.md +0 -60
- package/specs/build-file/references/spec.md +0 -56
- package/specs/build-file/spec.md +0 -62
- package/specs/cli/clean/spec.md +0 -85
- package/specs/cli/down/spec.md +0 -85
- package/specs/cli/execute/spec.md +0 -101
- package/specs/cli/init/spec.md +0 -64
- package/specs/cli/ls/spec.md +0 -66
- package/specs/cli/package/spec.md +0 -110
- package/specs/cli/spec.md +0 -73
- package/specs/cli/store-restore/spec.md +0 -74
- package/specs/cli/up/spec.md +0 -80
- package/specs/cli/validate/spec.md +0 -70
- package/specs/labels/spec.md +0 -91
- package/specs/service/container/spec.md +0 -120
- package/specs/service/kubernetes/spec.md +0 -97
- package/specs/service/spec.md +0 -105
- package/specs/task/caching/spec.md +0 -107
- package/specs/task/container/spec.md +0 -118
- package/specs/task/dependencies/spec.md +0 -70
- package/specs/task/extending/spec.md +0 -74
- package/specs/task/kubernetes/spec.md +0 -125
- package/specs/task/needs/spec.md +0 -59
- package/specs/task/spec.md +0 -87
- package/specs/task/watching/spec.md +0 -69
package/SUMMARY.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Table of contents
|
|
2
|
-
|
|
3
|
-
* [About](README.md)
|
|
4
|
-
* [Why hammerkit](docs/why-hammerkit.md)
|
|
5
|
-
* [Installation](docs/installation.md)
|
|
6
|
-
* [Getting started](docs/getting-started.md)
|
|
7
|
-
* [Tutorial](docs/tutorial.md)
|
|
8
|
-
* [Concepts](docs/concepts.md)
|
|
9
|
-
* [Build file](docs/build-file/README.md)
|
|
10
|
-
* [Environment Variables](docs/build-file/environment-variables.md)
|
|
11
|
-
* [References](docs/build-file/references.md)
|
|
12
|
-
* [Includes](docs/build-file/includes.md)
|
|
13
|
-
* [Caches](docs/build-file/caches.md)
|
|
14
|
-
* [Reference](docs/build-file/reference.md)
|
|
15
|
-
* [Task](docs/task/README.md)
|
|
16
|
-
* [Dependencies](docs/task/dependencies.md)
|
|
17
|
-
* [Needs](docs/task/needs.md)
|
|
18
|
-
* [Caching](docs/task/caching.md)
|
|
19
|
-
* [Run task in a container](docs/task/container.md)
|
|
20
|
-
* [Run task on Kubernetes](docs/task/kubernetes.md)
|
|
21
|
-
* [Watching](docs/task/watching.md)
|
|
22
|
-
* [Extending](docs/task/extending.md)
|
|
23
|
-
* [Service](docs/service/README.md)
|
|
24
|
-
* [Container service](docs/service/container.md)
|
|
25
|
-
* [Kubernetes service](docs/service/kubernetes.md)
|
|
26
|
-
* [Labels](docs/labels/README.md)
|
|
27
|
-
* [Guides](docs/guides/local-vs-container.md)
|
|
28
|
-
* [Local vs container tasks](docs/guides/local-vs-container.md)
|
|
29
|
-
* [Caching strategy in CI](docs/guides/ci-caching.md)
|
|
30
|
-
* [Services & networking](docs/guides/services-networking.md)
|
|
31
|
-
* [Monorepo layout](docs/guides/monorepo.md)
|
|
32
|
-
* [Development workflow](docs/guides/development-workflow.md)
|
|
33
|
-
* [CLI](docs/cli/README.md)
|
|
34
|
-
* [Init](docs/cli/init.md)
|
|
35
|
-
* [ls](docs/cli/ls.md)
|
|
36
|
-
* [Execute](docs/cli/execute.md)
|
|
37
|
-
* [Up](docs/cli/up.md)
|
|
38
|
-
* [Down](docs/cli/down.md)
|
|
39
|
-
* [Store / Restore](docs/cli/store-restore.md)
|
|
40
|
-
* [Package](docs/cli/package.md)
|
|
41
|
-
* [Clean](docs/cli/clean.md)
|
|
42
|
-
* [Validate](docs/cli/validate.md)
|
|
43
|
-
* [Recipes](docs/recipes.md)
|
|
44
|
-
* [FAQ & Troubleshooting](docs/faq.md)
|
|
45
|
-
|
|
46
|
-
## External Links
|
|
47
|
-
|
|
48
|
-
* [Docker Hub](https://hub.docker.com/r/no0dles/hammerkit)
|
|
49
|
-
* [Homebrew Repository](https://github.com/no0dles/homebrew-hammerkit)
|
|
50
|
-
|
|
51
|
-
## Release Blog
|
|
52
|
-
|
|
53
|
-
* [Release 1.4.0](docs/release-blog/release-1.4.0.md)
|
|
54
|
-
* [Release 1.5.0](docs/release-blog/release-1.5.0.md)
|
|
55
|
-
* [Release 1.6.0](docs/release-blog/release-1.6.0.md)
|
|
56
|
-
|
|
57
|
-
## Change Log
|
|
58
|
-
|
|
59
|
-
* [Changelog 1.4.0](docs/change-log/change-log-1.4.0.md)
|
|
60
|
-
* [Changelog 1.5.0](docs/change-log/change-log-1.5.0.md)
|
|
61
|
-
* [Changelog 1.6.0](docs/change-log/change-log-1.6.0.md)
|
|
62
|
-
|
|
63
|
-
## Contribution
|
|
64
|
-
|
|
65
|
-
* [Roadmap](docs/contribution/roadmap.md)
|
|
66
|
-
* [Secret managers (planned)](docs/contribution/secret-managers.md)
|
|
67
|
-
* [Publishing](docs/contribution/publish.md)
|
|
68
|
-
* [Self-hosted runner](docs/contribution/self-hosted-runner.md)
|
package/VALUES.md
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Values
|
|
2
|
-
|
|
3
|
-
This file is the canonical statement of what hammerkit optimizes for and the conventions that follow from it. Contributors and AI agents should read it before non-trivial work. Day-to-day agent operating rules live in [AGENTS.md](AGENTS.md); durable corrections live in [.agents/FEEDBACK.md](.agents/FEEDBACK.md).
|
|
4
|
-
|
|
5
|
-
## Product values
|
|
6
|
-
|
|
7
|
-
### Local-first
|
|
8
|
-
|
|
9
|
-
Hammerkit must be usable on a developer's laptop, not only in CI. A build tool that only runs on CI is broken.
|
|
10
|
-
|
|
11
|
-
### Platform-agnostic
|
|
12
|
-
|
|
13
|
-
No coupling to GitHub Actions, GitLab CI, or any single provider. The same build runs anywhere a container does.
|
|
14
|
-
|
|
15
|
-
### One config, many tools
|
|
16
|
-
|
|
17
|
-
A single hammerkit build file replaces N tool-specific configs. Reducing config sprawl is a feature, not a side effect.
|
|
18
|
-
|
|
19
|
-
### Caching reduces waste, not just time
|
|
20
|
-
|
|
21
|
-
Smart, distributed caching saves compute — that matters for cost and footprint, not only build speed.
|
|
22
|
-
|
|
23
|
-
## Engineering values
|
|
24
|
-
|
|
25
|
-
### Stable foundation
|
|
26
|
-
|
|
27
|
-
The CLI and build-file schema are contracts. Breaking them is a deliberate, versioned decision — never a refactor side effect.
|
|
28
|
-
|
|
29
|
-
### Simplicity & composability
|
|
30
|
-
|
|
31
|
-
Prefer small, composable pieces over clever abstractions. If two features can be one, make them one.
|
|
32
|
-
|
|
33
|
-
### Pragmatic typing
|
|
34
|
-
|
|
35
|
-
TS strict is on; `any` is permitted where it pulls its weight. Type purity is a means, not the goal.
|
|
36
|
-
|
|
37
|
-
### Tests carry their weight
|
|
38
|
-
|
|
39
|
-
Quality and coverage are non-negotiable. Slow integration tests are accepted because they buy real confidence.
|
|
40
|
-
|
|
41
|
-
## Decision heuristics
|
|
42
|
-
|
|
43
|
-
### Fix root causes, not symptoms
|
|
44
|
-
|
|
45
|
-
A red check is fixed by repairing what's broken — not by removing, muting, or weakening the check.
|
|
46
|
-
|
|
47
|
-
### Real integrations over mocks
|
|
48
|
-
|
|
49
|
-
Where feasible, exercise real Docker / real registries / real Kubernetes. Mocks are a last resort, not a default.
|
|
50
|
-
|
|
51
|
-
### Add nothing speculative
|
|
52
|
-
|
|
53
|
-
Features, abstractions, and config knobs land when a concrete need exists — not for hypothetical futures.
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const path_1 = require("path");
|
|
4
|
-
const os_1 = require("os");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const environment_mock_1 = require("../executer/environment-mock");
|
|
7
|
-
const enqueue_next_1 = require("../executer/scheduler/enqueue-next");
|
|
8
|
-
const local_cache_backend_1 = require("./backends/local-cache-backend");
|
|
9
|
-
const state_1 = require("../executer/state");
|
|
10
|
-
const cache_metadata_1 = require("../executer/cache-metadata");
|
|
11
|
-
const get_cache_directory_1 = require("../optimizer/get-cache-directory");
|
|
12
|
-
const get_work_cache_stats_1 = require("../optimizer/get-work-cache-stats");
|
|
13
|
-
const work_task_cache_description_1 = require("../optimizer/work-task-cache-description");
|
|
14
|
-
describe('checkCacheState auto-pull', () => {
|
|
15
|
-
let remoteDir;
|
|
16
|
-
let machineHome;
|
|
17
|
-
let originalHome;
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
remoteDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-remote-'));
|
|
20
|
-
machineHome = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-home-'));
|
|
21
|
-
originalHome = process.env.HOME;
|
|
22
|
-
if (process.platform === 'darwin') {
|
|
23
|
-
// getHammerkitDirectory uses Library/Application Support on macOS
|
|
24
|
-
process.env.HOME = machineHome;
|
|
25
|
-
}
|
|
26
|
-
else if (process.platform === 'win32') {
|
|
27
|
-
process.env.APPDATA = machineHome;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
process.env.HOME = machineHome;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
afterEach(() => {
|
|
34
|
-
(0, fs_1.rmSync)(remoteDir, { recursive: true, force: true });
|
|
35
|
-
(0, fs_1.rmSync)(machineHome, { recursive: true, force: true });
|
|
36
|
-
if (originalHome !== undefined) {
|
|
37
|
-
process.env.HOME = originalHome;
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
delete process.env.HOME;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
function makeBackend() {
|
|
44
|
-
return (0, local_cache_backend_1.createLocalCacheBackend)({ type: 'local', path: remoteDir });
|
|
45
|
-
}
|
|
46
|
-
function makeWorkItem(cwd, resolved) {
|
|
47
|
-
const storedStateKey = null;
|
|
48
|
-
return {
|
|
49
|
-
id: () => 'demo-task',
|
|
50
|
-
name: 'demo-task',
|
|
51
|
-
status: { write: vi.fn() },
|
|
52
|
-
data: {
|
|
53
|
-
type: 'local-task',
|
|
54
|
-
name: 'demo-task',
|
|
55
|
-
cwd,
|
|
56
|
-
cmds: [],
|
|
57
|
-
generates: [],
|
|
58
|
-
src: [],
|
|
59
|
-
envs: { variables: {}, replacements: [] },
|
|
60
|
-
labels: {},
|
|
61
|
-
shell: '/bin/sh',
|
|
62
|
-
continuous: false,
|
|
63
|
-
caching: resolved,
|
|
64
|
-
description: null,
|
|
65
|
-
scope: {},
|
|
66
|
-
},
|
|
67
|
-
needs: [],
|
|
68
|
-
deps: [],
|
|
69
|
-
requiredBy: [],
|
|
70
|
-
state: new state_1.State({ type: 'pending', stateKey: null }),
|
|
71
|
-
runtime: {
|
|
72
|
-
async initialize() { },
|
|
73
|
-
async remove() { },
|
|
74
|
-
async execute() { },
|
|
75
|
-
async stop() { },
|
|
76
|
-
async archive() { },
|
|
77
|
-
async restore() {
|
|
78
|
-
// simulate a successful artifact restore
|
|
79
|
-
},
|
|
80
|
-
async currentStateKey() {
|
|
81
|
-
return storedStateKey;
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
it('reports cached:true on the second machine after the first pushed', async () => {
|
|
87
|
-
// Machine A: produce cache + push to remote
|
|
88
|
-
const machineAScratch = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-machine-a-'));
|
|
89
|
-
const envA = (0, environment_mock_1.environmentMock)(machineAScratch);
|
|
90
|
-
const backend = makeBackend();
|
|
91
|
-
const resolved = { name: 'remote', method: 'checksum', backend, implicit: false };
|
|
92
|
-
const itemA = makeWorkItem(machineAScratch, resolved);
|
|
93
|
-
const stats = await (0, get_work_cache_stats_1.getWorkCacheStats)(itemA.data, envA);
|
|
94
|
-
const stateKey = (0, get_work_cache_stats_1.getStateKey)(stats, 'checksum');
|
|
95
|
-
await (0, cache_metadata_1.writeCacheMetadata)(envA, itemA.id(), stats, (0, work_task_cache_description_1.getWorkTaskCacheDescription)(itemA.data));
|
|
96
|
-
const cacheDir = (0, get_cache_directory_1.getCacheDirectory)(itemA.id());
|
|
97
|
-
await backend.push(itemA.id(), stateKey, cacheDir, envA);
|
|
98
|
-
(0, fs_1.rmSync)(machineAScratch, { recursive: true, force: true });
|
|
99
|
-
// Machine B (different HOME = fresh local cache): same task, same sources → same stateKey
|
|
100
|
-
const machineBScratch = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-machine-b-'));
|
|
101
|
-
const envB = (0, environment_mock_1.environmentMock)(machineBScratch);
|
|
102
|
-
// simulate a *different* machine: reset the HOME again
|
|
103
|
-
const machineBHome = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-home-b-'));
|
|
104
|
-
process.env.HOME = machineBHome;
|
|
105
|
-
const itemB = makeWorkItem(machineBScratch, resolved);
|
|
106
|
-
const cacheState = await (0, enqueue_next_1.checkCacheState)(itemB, 'checksum', envB);
|
|
107
|
-
expect(cacheState.stateKey).toBe(stateKey);
|
|
108
|
-
expect(cacheState.cached).toBe(true);
|
|
109
|
-
(0, fs_1.rmSync)(machineBScratch, { recursive: true, force: true });
|
|
110
|
-
(0, fs_1.rmSync)(machineBHome, { recursive: true, force: true });
|
|
111
|
-
});
|
|
112
|
-
it('reports cached:false when remote has nothing', async () => {
|
|
113
|
-
const scratch = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-machine-c-'));
|
|
114
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
115
|
-
const backend = makeBackend();
|
|
116
|
-
const resolved = { name: 'remote', method: 'checksum', backend, implicit: false };
|
|
117
|
-
const item = makeWorkItem(scratch, resolved);
|
|
118
|
-
const cacheState = await (0, enqueue_next_1.checkCacheState)(item, 'checksum', env);
|
|
119
|
-
expect(cacheState.cached).toBe(false);
|
|
120
|
-
(0, fs_1.rmSync)(scratch, { recursive: true, force: true });
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
//# sourceMappingURL=auto-pull.spec.js.map
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const path_1 = require("path");
|
|
4
|
-
const os_1 = require("os");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const local_cache_backend_1 = require("./local-cache-backend");
|
|
7
|
-
const environment_mock_1 = require("../../executer/environment-mock");
|
|
8
|
-
describe('local cache backend', () => {
|
|
9
|
-
let root;
|
|
10
|
-
let scratch;
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
root = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-local-cache-'));
|
|
13
|
-
scratch = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-local-cache-scratch-'));
|
|
14
|
-
});
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
(0, fs_1.rmSync)(root, { recursive: true, force: true });
|
|
17
|
-
(0, fs_1.rmSync)(scratch, { recursive: true, force: true });
|
|
18
|
-
});
|
|
19
|
-
it('reports no hit when nothing pushed yet', async () => {
|
|
20
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
21
|
-
const backend = (0, local_cache_backend_1.createLocalCacheBackend)({ type: 'local', path: root });
|
|
22
|
-
expect(await backend.has('taskA', 'key1', env)).toBe(false);
|
|
23
|
-
expect(await backend.pull('taskA', 'key1', (0, path_1.join)(scratch, 'pull'), env)).toBe(false);
|
|
24
|
-
});
|
|
25
|
-
it('round-trips a task through push and pull', async () => {
|
|
26
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
27
|
-
const backend = (0, local_cache_backend_1.createLocalCacheBackend)({ type: 'local', path: root });
|
|
28
|
-
const sourceDir = (0, path_1.join)(scratch, 'src');
|
|
29
|
-
await env.file.createDirectory(sourceDir);
|
|
30
|
-
await env.file.writeFile((0, path_1.join)(sourceDir, 'stats.json'), '{"files":{}}');
|
|
31
|
-
await env.file.writeFile((0, path_1.join)(sourceDir, 'description.json'), '{}');
|
|
32
|
-
await env.file.writeFile((0, path_1.join)(sourceDir, 'dist-generates.tgz'), 'tarball-bytes');
|
|
33
|
-
await backend.push('taskA', 'key1', sourceDir, env);
|
|
34
|
-
expect(await backend.has('taskA', 'key1', env)).toBe(true);
|
|
35
|
-
const into = (0, path_1.join)(scratch, 'pull');
|
|
36
|
-
const ok = await backend.pull('taskA', 'key1', into, env);
|
|
37
|
-
expect(ok).toBe(true);
|
|
38
|
-
expect(await env.file.exists((0, path_1.join)(into, 'stats.json'))).toBe(true);
|
|
39
|
-
expect(await env.file.exists((0, path_1.join)(into, 'description.json'))).toBe(true);
|
|
40
|
-
expect(await env.file.exists((0, path_1.join)(into, 'dist-generates.tgz'))).toBe(true);
|
|
41
|
-
expect(await env.file.read((0, path_1.join)(into, 'dist-generates.tgz'))).toBe('tarball-bytes');
|
|
42
|
-
});
|
|
43
|
-
it('isolates entries by stateKey', async () => {
|
|
44
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
45
|
-
const backend = (0, local_cache_backend_1.createLocalCacheBackend)({ type: 'local', path: root });
|
|
46
|
-
const sourceDir = (0, path_1.join)(scratch, 'src');
|
|
47
|
-
await env.file.createDirectory(sourceDir);
|
|
48
|
-
await env.file.writeFile((0, path_1.join)(sourceDir, 'stats.json'), '{}');
|
|
49
|
-
await backend.push('taskA', 'key1', sourceDir, env);
|
|
50
|
-
expect(await backend.has('taskA', 'key2', env)).toBe(false);
|
|
51
|
-
});
|
|
52
|
-
it('clear removes every state key of a task without touching others', async () => {
|
|
53
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
54
|
-
const backend = (0, local_cache_backend_1.createLocalCacheBackend)({ type: 'local', path: root });
|
|
55
|
-
const sourceDir = (0, path_1.join)(scratch, 'src');
|
|
56
|
-
await env.file.createDirectory(sourceDir);
|
|
57
|
-
await env.file.writeFile((0, path_1.join)(sourceDir, 'stats.json'), '{}');
|
|
58
|
-
await backend.push('taskA', 'key1', sourceDir, env);
|
|
59
|
-
await backend.push('taskA', 'key2', sourceDir, env);
|
|
60
|
-
await backend.push('taskB', 'key1', sourceDir, env);
|
|
61
|
-
await backend.clear('taskA', env);
|
|
62
|
-
expect(await backend.has('taskA', 'key1', env)).toBe(false);
|
|
63
|
-
expect(await backend.has('taskA', 'key2', env)).toBe(false);
|
|
64
|
-
expect(await backend.has('taskB', 'key1', env)).toBe(true);
|
|
65
|
-
});
|
|
66
|
-
it('clear is a no-op when the task has nothing cached', async () => {
|
|
67
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
68
|
-
const backend = (0, local_cache_backend_1.createLocalCacheBackend)({ type: 'local', path: root });
|
|
69
|
-
await expect(backend.clear('missing', env)).resolves.toBeUndefined();
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
//# sourceMappingURL=local-cache-backend.spec.js.map
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const stream_1 = require("stream");
|
|
4
|
-
// vi.hoisted: vi.mock is hoisted above this file's top-level code, so the factory
|
|
5
|
-
// below can only reference variables that are themselves hoisted.
|
|
6
|
-
const { sendMock } = vi.hoisted(() => ({ sendMock: vi.fn() }));
|
|
7
|
-
vi.mock('@aws-sdk/client-s3', () => {
|
|
8
|
-
class S3ClientMock {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.send = sendMock;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
class GetObjectCommand {
|
|
14
|
-
constructor(input) {
|
|
15
|
-
this.input = input;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
class PutObjectCommand {
|
|
19
|
-
constructor(input) {
|
|
20
|
-
this.input = input;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
class HeadObjectCommand {
|
|
24
|
-
constructor(input) {
|
|
25
|
-
this.input = input;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
class ListObjectsV2Command {
|
|
29
|
-
constructor(input) {
|
|
30
|
-
this.input = input;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
S3Client: S3ClientMock,
|
|
35
|
-
GetObjectCommand,
|
|
36
|
-
PutObjectCommand,
|
|
37
|
-
HeadObjectCommand,
|
|
38
|
-
ListObjectsV2Command,
|
|
39
|
-
};
|
|
40
|
-
});
|
|
41
|
-
const s3_cache_backend_1 = require("./s3-cache-backend");
|
|
42
|
-
const fs_1 = require("fs");
|
|
43
|
-
const os_1 = require("os");
|
|
44
|
-
const path_1 = require("path");
|
|
45
|
-
const environment_mock_1 = require("../../executer/environment-mock");
|
|
46
|
-
describe('s3 cache backend', () => {
|
|
47
|
-
let scratch;
|
|
48
|
-
beforeEach(() => {
|
|
49
|
-
sendMock.mockReset();
|
|
50
|
-
scratch = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'hammerkit-s3-spec-'));
|
|
51
|
-
});
|
|
52
|
-
afterEach(() => {
|
|
53
|
-
(0, fs_1.rmSync)(scratch, { recursive: true, force: true });
|
|
54
|
-
});
|
|
55
|
-
it('returns false from has() when HeadObject rejects', async () => {
|
|
56
|
-
sendMock.mockRejectedValueOnce(new Error('not found'));
|
|
57
|
-
const backend = (0, s3_cache_backend_1.createS3CacheBackend)({ type: 's3', bucket: 'b', region: 'us-east-1' });
|
|
58
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
59
|
-
expect(await backend.has('task', 'state', env)).toBe(false);
|
|
60
|
-
});
|
|
61
|
-
it('returns true when HeadObject resolves', async () => {
|
|
62
|
-
sendMock.mockResolvedValueOnce({});
|
|
63
|
-
const backend = (0, s3_cache_backend_1.createS3CacheBackend)({ type: 's3', bucket: 'b', region: 'us-east-1' });
|
|
64
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
65
|
-
expect(await backend.has('task', 'state', env)).toBe(true);
|
|
66
|
-
});
|
|
67
|
-
it('uploads files via PutObject with prefix + task + stateKey path', async () => {
|
|
68
|
-
sendMock.mockResolvedValue({});
|
|
69
|
-
const backend = (0, s3_cache_backend_1.createS3CacheBackend)({ type: 's3', bucket: 'b', prefix: 'p/', region: 'us-east-1' });
|
|
70
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
71
|
-
await env.file.writeFile((0, path_1.join)(scratch, 'stats.json'), '{}');
|
|
72
|
-
await env.file.writeFile((0, path_1.join)(scratch, 'description.json'), '{}');
|
|
73
|
-
await env.file.writeFile((0, path_1.join)(scratch, 'a-generates.tgz'), 'bytes');
|
|
74
|
-
await backend.push('task1', 'key1', scratch, env);
|
|
75
|
-
const keys = sendMock.mock.calls.map(([cmd]) => cmd.input.Key);
|
|
76
|
-
expect(keys).toContain('p/task1/key1/a-generates.tgz');
|
|
77
|
-
expect(keys).toContain('p/task1/key1/description.json');
|
|
78
|
-
expect(keys).toContain('p/task1/key1/stats.json');
|
|
79
|
-
// stats.json must be uploaded last so a partial push is invisible to has()/pull()
|
|
80
|
-
expect(keys[keys.length - 1]).toBe('p/task1/key1/stats.json');
|
|
81
|
-
});
|
|
82
|
-
it('downloads files into the local cache dir on pull', async () => {
|
|
83
|
-
const backend = (0, s3_cache_backend_1.createS3CacheBackend)({ type: 's3', bucket: 'b', region: 'us-east-1' });
|
|
84
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
85
|
-
// Order: Head, then List, then a Get per object
|
|
86
|
-
sendMock.mockResolvedValueOnce({}); // head
|
|
87
|
-
sendMock.mockResolvedValueOnce({
|
|
88
|
-
Contents: [{ Key: 'task/state/stats.json' }, { Key: 'task/state/dist.tgz' }],
|
|
89
|
-
});
|
|
90
|
-
sendMock.mockResolvedValueOnce({ Body: stream_1.Readable.from(['{}']) });
|
|
91
|
-
sendMock.mockResolvedValueOnce({ Body: stream_1.Readable.from(['tarball']) });
|
|
92
|
-
const into = (0, path_1.join)(scratch, 'pulled');
|
|
93
|
-
const ok = await backend.pull('task', 'state', into, env);
|
|
94
|
-
expect(ok).toBe(true);
|
|
95
|
-
expect(await env.file.exists((0, path_1.join)(into, 'stats.json'))).toBe(true);
|
|
96
|
-
expect(await env.file.exists((0, path_1.join)(into, 'dist.tgz'))).toBe(true);
|
|
97
|
-
});
|
|
98
|
-
it('does not write objects whose key escapes the restore dir on pull', async () => {
|
|
99
|
-
const backend = (0, s3_cache_backend_1.createS3CacheBackend)({ type: 's3', bucket: 'b', region: 'us-east-1' });
|
|
100
|
-
const env = (0, environment_mock_1.environmentMock)(scratch);
|
|
101
|
-
sendMock.mockResolvedValueOnce({}); // head
|
|
102
|
-
sendMock.mockResolvedValueOnce({
|
|
103
|
-
// a poisoned bucket can list a key whose suffix traverses out of the dir
|
|
104
|
-
Contents: [{ Key: 'task/state/../escape.txt' }, { Key: 'task/state/safe.txt' }],
|
|
105
|
-
});
|
|
106
|
-
// only the safe object should be fetched; the traversal entry is skipped before Get
|
|
107
|
-
sendMock.mockResolvedValueOnce({ Body: stream_1.Readable.from(['ok']) });
|
|
108
|
-
const into = (0, path_1.join)(scratch, 'pulled');
|
|
109
|
-
const ok = await backend.pull('task', 'state', into, env);
|
|
110
|
-
expect(ok).toBe(true);
|
|
111
|
-
expect(await env.file.exists((0, path_1.join)(into, 'safe.txt'))).toBe(true);
|
|
112
|
-
// ../escape.txt would resolve to scratch/escape.txt, outside `into`
|
|
113
|
-
expect(await env.file.exists((0, path_1.join)(scratch, 'escape.txt'))).toBe(false);
|
|
114
|
-
// the traversal entry must not trigger a GetObject (head + list + 1 get = 3)
|
|
115
|
-
expect(sendMock).toHaveBeenCalledTimes(3);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
//# sourceMappingURL=s3-cache-backend.spec.js.map
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// The factory registry registers `local` and `s3` at import time. We can
|
|
3
|
-
// exercise createCacheBackend for both registered types and the unknown-type
|
|
4
|
-
// failure without needing the AWS SDK at runtime (`local` is real; for `s3`
|
|
5
|
-
// we register a fake under a fresh type name).
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const cache_backend_registry_1 = require("./cache-backend-registry");
|
|
8
|
-
describe('createCacheBackend', () => {
|
|
9
|
-
it('builds a local backend from a {type:"local"} spec', () => {
|
|
10
|
-
const backend = (0, cache_backend_registry_1.createCacheBackend)({ type: 'local' });
|
|
11
|
-
expect(backend.type).toBe('local');
|
|
12
|
-
});
|
|
13
|
-
it('throws on an unknown backend type', () => {
|
|
14
|
-
expect(() => (0, cache_backend_registry_1.createCacheBackend)({ type: 'unknown-backend-xyz' })).toThrow(/unknown cache backend type: unknown-backend-xyz/);
|
|
15
|
-
});
|
|
16
|
-
it('dispatches to a registered custom factory', () => {
|
|
17
|
-
const fakeBackend = { type: 'fake' };
|
|
18
|
-
(0, cache_backend_registry_1.registerCacheBackend)('fake-backend', () => fakeBackend);
|
|
19
|
-
expect((0, cache_backend_registry_1.createCacheBackend)({ type: 'fake-backend' })).toBe(fakeBackend);
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
//# sourceMappingURL=cache-backend-registry.spec.js.map
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const resolve_cache_1 = require("./resolve-cache");
|
|
4
|
-
describe('resolveCache', () => {
|
|
5
|
-
const catalog = (0, resolve_cache_1.withBuiltinCaches)({
|
|
6
|
-
s3: { method: 'modify-date', backend: { type: 'local', path: '/tmp/fake' } },
|
|
7
|
-
});
|
|
8
|
-
it('uses the default cache when no ref is given', () => {
|
|
9
|
-
const r = (0, resolve_cache_1.resolveCache)(undefined, catalog, 'taskA');
|
|
10
|
-
expect(r.name).toBe('default');
|
|
11
|
-
expect(r.method).toBe('checksum');
|
|
12
|
-
expect(r.backend.type).toBe('local');
|
|
13
|
-
expect(r.implicit).toBe(true);
|
|
14
|
-
});
|
|
15
|
-
it('treats a string ref as a method override on default', () => {
|
|
16
|
-
const r = (0, resolve_cache_1.resolveCache)('modify-date', catalog, 'taskA');
|
|
17
|
-
expect(r.name).toBe('default');
|
|
18
|
-
expect(r.method).toBe('modify-date');
|
|
19
|
-
expect(r.backend.type).toBe('local');
|
|
20
|
-
expect(r.implicit).toBe(false);
|
|
21
|
-
});
|
|
22
|
-
it('uses none method when "none" string shorthand is used', () => {
|
|
23
|
-
const r = (0, resolve_cache_1.resolveCache)('none', catalog, 'taskA');
|
|
24
|
-
expect(r.method).toBe('none');
|
|
25
|
-
});
|
|
26
|
-
it('resolves a named reference and keeps its declared method', () => {
|
|
27
|
-
const r = (0, resolve_cache_1.resolveCache)({ name: 's3' }, catalog, 'taskA');
|
|
28
|
-
expect(r.name).toBe('s3');
|
|
29
|
-
expect(r.method).toBe('modify-date');
|
|
30
|
-
});
|
|
31
|
-
it('overrides the named cache method when the task sets one', () => {
|
|
32
|
-
const r = (0, resolve_cache_1.resolveCache)({ name: 's3', method: 'checksum' }, catalog, 'taskA');
|
|
33
|
-
expect(r.name).toBe('s3');
|
|
34
|
-
expect(r.method).toBe('checksum');
|
|
35
|
-
});
|
|
36
|
-
it('throws when an unknown name is referenced', () => {
|
|
37
|
-
expect(() => (0, resolve_cache_1.resolveCache)({ name: 'missing' }, catalog, 'taskA')).toThrow(/cache "missing" referenced by task "taskA"/);
|
|
38
|
-
});
|
|
39
|
-
it('seeds default and none even when nothing is declared', () => {
|
|
40
|
-
const empty = (0, resolve_cache_1.withBuiltinCaches)(undefined);
|
|
41
|
-
expect(empty.default.backend.type).toBe('local');
|
|
42
|
-
expect(empty.none.backend.type).toBe('local');
|
|
43
|
-
});
|
|
44
|
-
it('lets the user override the built-in default', () => {
|
|
45
|
-
const cat = (0, resolve_cache_1.withBuiltinCaches)({
|
|
46
|
-
default: { method: 'modify-date', backend: { type: 'local', path: '/tmp/x' } },
|
|
47
|
-
});
|
|
48
|
-
const r = (0, resolve_cache_1.resolveCache)(undefined, cat, 'taskA');
|
|
49
|
-
expect(r.method).toBe('modify-date');
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
//# sourceMappingURL=resolve-cache.spec.js.map
|
package/dist/cli.spec.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const path_1 = require("path");
|
|
4
|
-
const test_case_1 = require("./testing/test-case");
|
|
5
|
-
const program_1 = require("./program");
|
|
6
|
-
// Drives the real parse pipeline (createCli) over an in-memory build file and
|
|
7
|
-
// then exercises Cli lookups against the resulting work tree — a real "not
|
|
8
|
-
// found" situation, no mocking.
|
|
9
|
-
describe('Cli', () => {
|
|
10
|
-
it('service() throws for an unknown service name', async () => {
|
|
11
|
-
const testCase = (0, test_case_1.createTestCase)('cli-service', {
|
|
12
|
-
'.hammerkit.yaml': {
|
|
13
|
-
services: { api: { image: 'nginx', ports: [] } },
|
|
14
|
-
tasks: { build: { cmds: ['tsc'], needs: ['api'] } },
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
await testCase.setup(async (cwd, environment) => {
|
|
18
|
-
const cli = await (0, program_1.createCli)((0, path_1.join)(cwd, '.hammerkit.yaml'), environment, { taskName: 'build' });
|
|
19
|
-
expect(() => cli.service('missing')).toThrow('unable to find service missing');
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
//# sourceMappingURL=cli.spec.js.map
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Verifies getLogger dispatches to the right logger by name and rejects an
|
|
3
|
-
// unknown mode via failNever — the actual loggers are tested elsewhere.
|
|
4
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
vi.mock('../logging/grouped-logger', () => ({ groupedLogger: vi.fn(() => 'grouped-instance') }));
|
|
6
|
-
vi.mock('../logging/live-logger', () => ({ liveLogger: vi.fn(() => 'live-instance') }));
|
|
7
|
-
vi.mock('../logging/interactive-logger', () => ({ interactiveLogger: vi.fn(() => 'interactive-instance') }));
|
|
8
|
-
const get_logger_1 = require("./get-logger");
|
|
9
|
-
describe('getLogger', () => {
|
|
10
|
-
it('returns the grouped logger for mode "grouped"', () => {
|
|
11
|
-
expect((0, get_logger_1.getLogger)('grouped', {}, {})).toBe('grouped-instance');
|
|
12
|
-
});
|
|
13
|
-
it('returns the live logger for mode "live"', () => {
|
|
14
|
-
expect((0, get_logger_1.getLogger)('live', {}, {})).toBe('live-instance');
|
|
15
|
-
});
|
|
16
|
-
it('returns the interactive logger for mode "interactive"', () => {
|
|
17
|
-
expect((0, get_logger_1.getLogger)('interactive', {}, {})).toBe('interactive-instance');
|
|
18
|
-
});
|
|
19
|
-
it('throws on an unknown mode (failNever)', () => {
|
|
20
|
-
expect(() => (0, get_logger_1.getLogger)('bogus', {}, {})).toThrow();
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
//# sourceMappingURL=get-logger.spec.js.map
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const package_1 = require("./package");
|
|
4
|
-
describe('docker/getDefaultPlatform', () => {
|
|
5
|
-
const realArch = process.arch;
|
|
6
|
-
function setArch(arch) {
|
|
7
|
-
Object.defineProperty(process, 'arch', { value: arch, configurable: true });
|
|
8
|
-
}
|
|
9
|
-
afterEach(() => {
|
|
10
|
-
Object.defineProperty(process, 'arch', { value: realArch, configurable: true });
|
|
11
|
-
});
|
|
12
|
-
it('maps x64 to linux/amd64', () => {
|
|
13
|
-
setArch('x64');
|
|
14
|
-
expect((0, package_1.getDefaultPlatform)()).toBe('linux/amd64');
|
|
15
|
-
});
|
|
16
|
-
it('maps arm64 to linux/arm64', () => {
|
|
17
|
-
setArch('arm64');
|
|
18
|
-
expect((0, package_1.getDefaultPlatform)()).toBe('linux/arm64');
|
|
19
|
-
});
|
|
20
|
-
it('maps arm to linux/arm', () => {
|
|
21
|
-
setArch('arm');
|
|
22
|
-
expect((0, package_1.getDefaultPlatform)()).toBe('linux/arm');
|
|
23
|
-
});
|
|
24
|
-
it('falls back to linux/amd64 for unknown architectures', () => {
|
|
25
|
-
setArch('mips');
|
|
26
|
-
expect((0, package_1.getDefaultPlatform)()).toBe('linux/amd64');
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
//# sourceMappingURL=get-default-platform.spec.js.map
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const path_1 = require("path");
|
|
4
|
-
const package_1 = require("./package");
|
|
5
|
-
// helper to build OS-correct absolute-ish paths
|
|
6
|
-
const p = (...segs) => path_1.sep + segs.join(path_1.sep);
|
|
7
|
-
describe('longestCommonPrefix (package build context root)', () => {
|
|
8
|
-
it('returns the directory of a single source, not the file itself', () => {
|
|
9
|
-
// regression: a single source used to yield the full file path, so the
|
|
10
|
-
// build-context copy targeted a directory and failed with EISDIR.
|
|
11
|
-
expect((0, package_1.longestCommonPrefix)([p('a', 'b', 'hello.txt')])).toBe(p('a', 'b'));
|
|
12
|
-
});
|
|
13
|
-
it('returns the common parent of files in the same directory', () => {
|
|
14
|
-
expect((0, package_1.longestCommonPrefix)([p('a', 'x.txt'), p('a', 'y.txt')])).toBe(p('a'));
|
|
15
|
-
});
|
|
16
|
-
it('returns the common ancestor across nested directories', () => {
|
|
17
|
-
expect((0, package_1.longestCommonPrefix)([p('a', 'x.txt'), p('a', 'b', 'y.txt')])).toBe(p('a'));
|
|
18
|
-
});
|
|
19
|
-
it('compares per path segment, not per character', () => {
|
|
20
|
-
expect((0, package_1.longestCommonPrefix)([p('a', 'foo'), p('a', 'foobar')])).toBe(p('a'));
|
|
21
|
-
});
|
|
22
|
-
it('returns empty for no sources', () => {
|
|
23
|
-
expect((0, package_1.longestCommonPrefix)([])).toBe('');
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
//# sourceMappingURL=longest-common-prefix.spec.js.map
|