hammerkit 1.4.0-beta.6 → 1.5.0-alpha.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/.devcontainer/Dockerfile +5 -0
- package/.devcontainer/devcontainer.json +40 -0
- package/Dockerfile +1 -1
- package/README.md +13 -86
- package/SUMMARY.md +43 -0
- package/build.schema.json +56 -2
- package/dist/cli.js +97 -0
- package/dist/cli.spec.js +5 -0
- package/dist/console/console-context-mock.js +11 -0
- package/dist/console/get-logger.js +23 -0
- package/dist/docker/pull.js +5 -5
- package/dist/docker/remove-container.js +21 -0
- package/dist/docker/stream.js +19 -21
- package/dist/docker/using-container.js +28 -0
- package/dist/environment/get-process-env.js +4 -4
- package/dist/environment/replace-env-variables.js +2 -3
- package/dist/executer/abort.js +13 -0
- package/dist/executer/check-readiness.js +25 -0
- package/dist/executer/create-scheduler-state.js +32 -0
- package/dist/executer/docker-node.js +123 -0
- package/dist/executer/docker-service.js +113 -0
- package/dist/executer/environment-mock.js +17 -0
- package/dist/executer/event-cache.js +165 -0
- package/dist/executer/execute-command.js +42 -0
- package/dist/executer/execute-docker.js +73 -223
- package/dist/executer/execute.spec.js +37 -37
- package/dist/executer/execution-steps.js +57 -0
- package/dist/executer/get-docker-executor.js +21 -20
- package/dist/executer/hierarchy-scheduler.js +94 -0
- package/dist/executer/kubernetes-service.js +64 -0
- package/dist/executer/label-values.js +65 -0
- package/dist/executer/local-node.js +57 -0
- package/dist/executer/print-container-options.js +17 -0
- package/dist/{logging/log-strategy.js → executer/process-item.js} +1 -1
- package/dist/executer/process-listener.js +3 -0
- package/dist/executer/process-manager.js +111 -0
- package/dist/executer/process-manager.spec.js +91 -0
- package/dist/executer/{executor.js → process.js} +1 -1
- package/dist/executer/{execute-result.js → readonly-state.js} +1 -1
- package/dist/executer/schedule.js +139 -0
- package/dist/executer/scheduler/check-for-loop.js +21 -0
- package/dist/executer/scheduler/enqueue-next.js +27 -0
- package/dist/{testing/test-context.js → executer/scheduler/node-state.js} +1 -1
- package/dist/executer/scheduler/scheduler-result.js +3 -0
- package/dist/executer/scheduler/scheduler-state.js +3 -0
- package/dist/executer/scheduler/service-state.js +3 -0
- package/dist/executer/service-dns.js +6 -0
- package/dist/executer/set-user-permission.js +16 -0
- package/dist/executer/start-node.js +59 -0
- package/dist/executer/state-listener.js +3 -0
- package/dist/executer/state.js +49 -0
- package/dist/executer/states.js +4 -129
- package/dist/executer/watch-node.js +57 -0
- package/dist/executer/watch-service.js +54 -0
- package/dist/executer/work-scope.js +10 -0
- package/dist/file/get-file-context-mock.js +1 -0
- package/dist/file/get-file-context-mock.spec.js +28 -27
- package/dist/file/get-file-context.js +73 -63
- package/dist/file/move-files.js +1 -1
- package/dist/get-work-context.js +29 -0
- package/dist/index.js +11 -10
- package/dist/log.js +209 -52
- package/dist/logging/grouped-logger.js +31 -19
- package/dist/logging/interactive-logger.js +20 -23
- package/dist/logging/live-logger.js +7 -17
- package/dist/optimizer/calculate-checksum.js +1 -1
- package/dist/optimizer/get-cache-directory.js +8 -13
- package/dist/optimizer/get-work-node-cache-stats.js +68 -21
- package/dist/optimizer/read-work-node-cache.js +2 -2
- package/dist/optimizer/work-node-cache-description.js +12 -11
- package/dist/optimizer/write-work-node-cache.js +9 -8
- package/dist/{executer/execution-context.js → parser/build-file-service.js} +1 -1
- package/dist/{optimizer → parser}/cache-method.js +0 -0
- package/dist/parser/get-build-file.js +1 -1
- package/dist/parser/parse-boolean.js +29 -0
- package/dist/parser/parse-boolean.spec.js +48 -0
- package/dist/parser/parse-build-file-references.js +2 -2
- package/dist/parser/parse-build-file-services.js +58 -0
- package/dist/parser/parse-build-file-task-command.js +6 -5
- package/dist/parser/parse-build-file-task-source.js +5 -5
- package/dist/parser/parse-build-file.js +29 -17
- package/dist/parser/parse-context.js +13 -0
- package/dist/parser/parse-envs.js +4 -3
- package/dist/parser/parse-healthcheck.js +28 -0
- package/dist/parser/parse-label-arguments.js +23 -0
- package/dist/parser/parse-service-selector.js +39 -0
- package/dist/parser/parse-string-array.js +6 -5
- package/dist/parser/parse-string-map.js +30 -0
- package/dist/parser/parse-string.js +20 -0
- package/dist/parser/read-build-file.js +16 -5
- package/dist/parser/read-env-file.js +7 -7
- package/dist/planner/utils/get-container-mounts.js +24 -0
- package/dist/planner/utils/normalize-path.js +17 -0
- package/dist/planner/utils/parse-work-node-mount.js +3 -14
- package/dist/planner/utils/parse-work-node-mount.spec.js +10 -10
- package/dist/planner/utils/parse-work-service-volume.js +21 -0
- package/dist/planner/utils/plan-work-command.js +1 -1
- package/dist/planner/utils/plan-work-dependency.js +29 -24
- package/dist/planner/utils/plan-work-node.js +203 -120
- package/dist/planner/utils/plan-work-nodes.js +60 -12
- package/dist/planner/utils/plan-work-tree.js +8 -4
- package/dist/planner/utils/plan-work-volume.js +25 -0
- package/dist/planner/validate.js +56 -8
- package/dist/planner/work-context.js +20 -0
- package/dist/planner/work-mount.js +3 -0
- package/dist/planner/work-node-id.js +4 -4
- package/dist/planner/work-node-id.spec.js +11 -8
- package/dist/planner/work-node-path.js +0 -1
- package/dist/planner/work-node-status.js +121 -18
- package/dist/planner/work-node.js +3 -3
- package/dist/planner/work-service-id.js +13 -0
- package/dist/planner/work-service-volume.js +3 -0
- package/dist/planner/work-service.js +6 -0
- package/dist/planner/work-services.js +3 -0
- package/dist/planner/work-volume.js +3 -0
- package/dist/program.js +155 -91
- package/dist/program.spec.js +20 -0
- package/dist/start-watch-processes.js +28 -0
- package/dist/testing/cli.js +73 -0
- package/dist/testing/create-build-file.js +1 -1
- package/dist/testing/example-test-suite.js +54 -0
- package/dist/testing/expect.js +30 -18
- package/dist/testing/get-logger.js +23 -0
- package/dist/testing/get-node.js +2 -2
- package/dist/testing/get-test-context.js +6 -5
- package/dist/testing/get-test-suite.js +2 -51
- package/dist/testing/integration/cache.spec.js +25 -28
- package/dist/testing/integration/cancellation.spec.js +19 -21
- package/dist/testing/integration/clean.spec.js +29 -13
- package/dist/testing/integration/cmd.spec.js +5 -8
- package/dist/testing/integration/concurrency.spec.js +8 -17
- package/dist/testing/integration/docker.spec.js +6 -9
- package/dist/testing/integration/env.spec.js +27 -34
- package/dist/testing/integration/error.spec.js +5 -9
- package/dist/testing/integration/extend.spec.js +32 -0
- package/dist/testing/integration/glob.spec.js +35 -28
- package/dist/testing/integration/include.spec.js +17 -16
- package/dist/testing/integration/invalid.spec.js +3 -2
- package/dist/testing/integration/invalid_loop.spec.js +13 -0
- package/dist/testing/integration/kubernetes.spec.js +15 -0
- package/dist/testing/integration/labels.spec.js +47 -0
- package/dist/testing/integration/local.spec.js +4 -7
- package/dist/testing/integration/monorepo.spec.js +6 -30
- package/dist/testing/integration/multi-line.spec.js +4 -4
- package/dist/testing/integration/program.spec.js +3 -10
- package/dist/testing/integration/reference.spec.js +10 -13
- package/dist/testing/integration/services.spec.js +14 -0
- package/dist/testing/integration/store.spec.js +42 -35
- package/dist/testing/integration/unknown.spec.js +4 -4
- package/dist/testing/integration/validate.spec.js +4 -4
- package/dist/testing/integration/watch.spec.js +25 -23
- package/dist/testing/lazy.js +17 -0
- package/dist/testing/start-watch-processes.js +29 -0
- package/dist/testing/test-suite-setup.js +3 -0
- package/dist/utils/abort-event.js +24 -0
- package/dist/utils/abortable-function.js +71 -0
- package/dist/utils/debouncer.spec.js +8 -8
- package/dist/utils/environment-config.js +13 -0
- package/dist/utils/fail-never.js +1 -1
- package/dist/utils/sleep.spec.js +3 -3
- package/package.json +24 -21
- package/dist/console/get-console-context-mock.js +0 -33
- package/dist/executer/clean.js +0 -22
- package/dist/executer/execute-local.js +0 -58
- package/dist/executer/execute.js +0 -95
- package/dist/executer/execution-context-event.js +0 -3
- package/dist/executer/execution-context-mock.js +0 -3
- package/dist/executer/executor-mock.js +0 -39
- package/dist/executer/get-environment-mock.js +0 -17
- package/dist/executer/get-execution-context-mock.js +0 -19
- package/dist/executer/get-local-executor.js +0 -22
- package/dist/executer/get-ready-work-nodes.js +0 -15
- package/dist/executer/restore.js +0 -22
- package/dist/executer/store.js +0 -23
- package/dist/logging/get-logger.js +0 -23
- package/dist/logging/message-to-console.js +0 -16
- package/dist/optimizer/optimize.js +0 -32
- package/dist/optimizer/work-node-description.js +0 -12
- package/dist/planner/utils/find-build-task.js +0 -18
- package/dist/testing/create-work-tree.js +0 -11
- package/dist/utils/defer.js +0 -57
- package/dist/utils/defer.spec.js +0 -76
|
@@ -1,139 +1,162 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getAbsolutePaths = exports.mapSource = exports.parseWorkNodeNeeds = exports.parseContainerWorkNodePorts = exports.mapLabels = exports.getWorkNode = exports.findBuildTask = exports.planTask = void 0;
|
|
4
|
+
const work_context_1 = require("../work-context");
|
|
4
5
|
const template_value_1 = require("./template-value");
|
|
5
6
|
const plan_work_command_1 = require("./plan-work-command");
|
|
6
7
|
const split_name_1 = require("./split-name");
|
|
7
|
-
const find_build_task_1 = require("./find-build-task");
|
|
8
8
|
const parse_work_node_mount_1 = require("./parse-work-node-mount");
|
|
9
9
|
const plan_work_dependency_1 = require("./plan-work-dependency");
|
|
10
10
|
const path_1 = require("path");
|
|
11
|
-
const work_node_status_1 = require("../work-node-status");
|
|
12
|
-
const defer_1 = require("../../utils/defer");
|
|
13
11
|
const work_node_id_1 = require("../work-node-id");
|
|
14
12
|
const parse_work_node_port_1 = require("./parse-work-node-port");
|
|
15
|
-
|
|
13
|
+
const work_service_id_1 = require("../work-service-id");
|
|
14
|
+
const os_1 = require("os");
|
|
15
|
+
const parse_work_service_volume_1 = require("./parse-work-service-volume");
|
|
16
|
+
const plan_work_volume_1 = require("./plan-work-volume");
|
|
17
|
+
const get_container_mounts_1 = require("./get-container-mounts");
|
|
18
|
+
function planTask(workContext, buildTaskResult) {
|
|
19
|
+
let extendedTask = null;
|
|
20
|
+
if (buildTaskResult.task.extend) {
|
|
21
|
+
extendedTask = findBuildTask(workContext, { taskName: buildTaskResult.task.extend });
|
|
22
|
+
if (extendedTask.task.extend) {
|
|
23
|
+
throw new Error(`nested extend ${extendedTask.name} is not allowed for task ${buildTaskResult.name}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
16
26
|
const envs = {
|
|
17
|
-
...
|
|
18
|
-
...
|
|
27
|
+
...(extendedTask?.task?.envs || {}),
|
|
28
|
+
...buildTaskResult.context.build.envs,
|
|
29
|
+
...(buildTaskResult.task.envs || {}),
|
|
19
30
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
...extend.task.envs,
|
|
24
|
-
...envs,
|
|
25
|
-
};
|
|
26
|
-
return {
|
|
27
|
-
task: {
|
|
28
|
-
image: task.image || extend.task.image,
|
|
29
|
-
envs: extendEnvs,
|
|
30
|
-
ports: task.ports || extend.task.ports || [],
|
|
31
|
-
cmds: task.cmds || extend.task.cmds || [],
|
|
32
|
-
description: task.description || extend.task.description,
|
|
33
|
-
shell: task.shell || extend.task.shell,
|
|
34
|
-
continuous: task.continuous || extend.task.continuous || false,
|
|
35
|
-
unknownProps: task.unknownProps,
|
|
36
|
-
src: [...(extend.task.src || []), ...(task.src || [])],
|
|
37
|
-
mounts: [...(extend.task.mounts || []), ...(task.mounts || [])],
|
|
38
|
-
generates: [...(extend.task.generates || []), ...(task.generates || [])],
|
|
39
|
-
},
|
|
40
|
-
deps: [
|
|
41
|
-
...(extend.task.deps || []).map((d) => ({ name: d, build: extend.build })),
|
|
42
|
-
...(task.deps || []).map((d) => ({ name: d, build: build })),
|
|
43
|
-
],
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
return {
|
|
48
|
-
task: {
|
|
49
|
-
image: task.image,
|
|
50
|
-
src: task.src || [],
|
|
51
|
-
cmds: task.cmds || [],
|
|
52
|
-
continuous: task.continuous || false,
|
|
53
|
-
generates: task.generates || [],
|
|
54
|
-
description: task.description,
|
|
55
|
-
shell: task.shell,
|
|
56
|
-
ports: task.ports || [],
|
|
57
|
-
unknownProps: task.unknownProps,
|
|
58
|
-
mounts: task.mounts || [],
|
|
59
|
-
envs,
|
|
60
|
-
},
|
|
61
|
-
deps: [...(task.deps || []).map((d) => ({ name: d, build: build }))],
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
exports.getMergedBuildTask = getMergedBuildTask;
|
|
66
|
-
function planWorkNode(build, taskName, nodes, context) {
|
|
67
|
-
if (build.tasks[taskName]) {
|
|
68
|
-
const { task, deps } = getMergedBuildTask(build, build.tasks[taskName]);
|
|
69
|
-
const id = work_node_id_1.getWorkNodeId(context.currentWorkdir, task, deps);
|
|
70
|
-
if (nodes[id]) {
|
|
71
|
-
return nodes[id];
|
|
31
|
+
const getReferences = (task, prop) => {
|
|
32
|
+
if (!task) {
|
|
33
|
+
return [];
|
|
72
34
|
}
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
id,
|
|
77
|
-
continuous: task.continuous,
|
|
78
|
-
description: template_value_1.templateValue(task.description, task.envs),
|
|
79
|
-
name,
|
|
80
|
-
cwd: context.currentWorkdir,
|
|
81
|
-
cmds: parseWorkNodeCommand(task, context, task.envs),
|
|
82
|
-
deps: [],
|
|
83
|
-
unknownProps: task.unknownProps,
|
|
84
|
-
buildFile: build,
|
|
85
|
-
taskName: taskName,
|
|
86
|
-
src: parseLocalWorkNodeSource(task, context, task.envs),
|
|
87
|
-
generates: parseLocalWorkNodeGenerate(task, context, task.envs),
|
|
88
|
-
mergedDeps: deps,
|
|
89
|
-
mergedTask: task,
|
|
90
|
-
status: {
|
|
91
|
-
name,
|
|
92
|
-
completedDependencies: {},
|
|
93
|
-
pendingDependencies: {},
|
|
94
|
-
state: { type: 'pending' },
|
|
95
|
-
defer: new defer_1.Defer(),
|
|
96
|
-
console: work_node_status_1.nodeConsole(),
|
|
97
|
-
},
|
|
98
|
-
}, task, context);
|
|
99
|
-
nodes[id] = node;
|
|
100
|
-
for (const dep of deps) {
|
|
101
|
-
plan_work_dependency_1.planWorkDependency(dep.build, node, taskName, template_value_1.templateValue(dep.name, task.envs), nodes, context);
|
|
35
|
+
const value = task.task[prop];
|
|
36
|
+
if (!value) {
|
|
37
|
+
return [];
|
|
102
38
|
}
|
|
103
|
-
return
|
|
39
|
+
return value.map((d) => ({
|
|
40
|
+
name: d,
|
|
41
|
+
build: buildTaskResult.context.build,
|
|
42
|
+
context: task.context,
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
const mergeReferences = (first, second) => {
|
|
46
|
+
return [...first, ...second];
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
buildTask: buildTaskResult.task,
|
|
50
|
+
build: buildTaskResult.context.build,
|
|
51
|
+
name: buildTaskResult.name,
|
|
52
|
+
cache: buildTaskResult.task.cache ?? extendedTask?.task?.cache ?? null,
|
|
53
|
+
description: buildTaskResult.task.description ?? extendedTask?.task?.description ?? null,
|
|
54
|
+
cwd: workContext.cwd,
|
|
55
|
+
image: buildTaskResult.task.image ?? extendedTask?.task?.image ?? null,
|
|
56
|
+
platform: buildTaskResult.task.platform ?? extendedTask?.task?.platform ?? null,
|
|
57
|
+
mounts: buildTaskResult.task.mounts || extendedTask?.task?.mounts || [],
|
|
58
|
+
generates: buildTaskResult.task.generates || extendedTask?.task?.generates || [],
|
|
59
|
+
shell: buildTaskResult.task.shell ?? extendedTask?.task?.shell ?? null,
|
|
60
|
+
ports: buildTaskResult.task.ports || extendedTask?.task?.ports || [],
|
|
61
|
+
src: buildTaskResult.task.src || extendedTask?.task?.src || [],
|
|
62
|
+
cmds: buildTaskResult.task.cmds || extendedTask?.task?.cmds || [],
|
|
63
|
+
continuous: buildTaskResult.task.continuous ?? extendedTask?.task?.continuous ?? false,
|
|
64
|
+
labels: {
|
|
65
|
+
...(extendedTask?.task?.labels || {}),
|
|
66
|
+
...(buildTaskResult.task.labels || {}),
|
|
67
|
+
},
|
|
68
|
+
envs,
|
|
69
|
+
deps: mergeReferences(getReferences(extendedTask, 'deps'), getReferences(buildTaskResult, 'deps')),
|
|
70
|
+
needs: mergeReferences(getReferences(extendedTask, 'needs'), getReferences(buildTaskResult, 'needs')),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
exports.planTask = planTask;
|
|
74
|
+
function findBuildTask(context, selector) {
|
|
75
|
+
if (context.build.tasks[selector.taskName]) {
|
|
76
|
+
return { task: context.build.tasks[selector.taskName], context, name: selector.taskName };
|
|
104
77
|
}
|
|
105
78
|
else {
|
|
106
|
-
const ref = split_name_1.splitName(taskName);
|
|
79
|
+
const ref = (0, split_name_1.splitName)(selector.taskName);
|
|
107
80
|
if (ref.prefix) {
|
|
108
|
-
if (build.references[ref.prefix]) {
|
|
109
|
-
return
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
namePrefix: [...context.namePrefix, ref.prefix],
|
|
114
|
-
});
|
|
81
|
+
if (context.build.references[ref.prefix]) {
|
|
82
|
+
return findBuildTask((0, work_context_1.createSubWorkContext)(context, {
|
|
83
|
+
name: ref.prefix,
|
|
84
|
+
type: 'references',
|
|
85
|
+
}), { taskName: ref.taskName });
|
|
115
86
|
}
|
|
116
|
-
else if (build.includes[ref.prefix]) {
|
|
117
|
-
return
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
87
|
+
else if (context.build.includes[ref.prefix]) {
|
|
88
|
+
return findBuildTask((0, work_context_1.createSubWorkContext)(context, {
|
|
89
|
+
name: ref.prefix,
|
|
90
|
+
type: 'includes',
|
|
91
|
+
}), {
|
|
92
|
+
taskName: ref.taskName,
|
|
121
93
|
});
|
|
122
94
|
}
|
|
123
95
|
}
|
|
124
|
-
throw new Error(`unable to find ${taskName} in ${build.path}`);
|
|
96
|
+
throw new Error(`unable to find ${selector.taskName} in ${context.build.path}`);
|
|
125
97
|
}
|
|
126
98
|
}
|
|
127
|
-
exports.
|
|
128
|
-
function
|
|
99
|
+
exports.findBuildTask = findBuildTask;
|
|
100
|
+
function getWorkNode(context, selector) {
|
|
101
|
+
const rootNode = findBuildTask(context, selector);
|
|
102
|
+
const plannedTask = planTask(rootNode.context, rootNode);
|
|
103
|
+
const id = (0, work_node_id_1.getWorkNodeId)(plannedTask);
|
|
104
|
+
if (context.workTree.nodes[id]) {
|
|
105
|
+
return context.workTree.nodes[id];
|
|
106
|
+
}
|
|
107
|
+
const node = parseWorkNode(id, plannedTask, rootNode.context);
|
|
108
|
+
context.workTree.nodes[id] = node;
|
|
109
|
+
const depNodes = [];
|
|
110
|
+
for (const plannedDep of plannedTask.deps) {
|
|
111
|
+
const depName = (0, template_value_1.templateValue)(plannedDep.name, plannedDep.build.envs);
|
|
112
|
+
const depNode = getWorkNode(plannedDep.context, { taskName: depName });
|
|
113
|
+
if (!depNodes.some((d) => d.id === depNode.id)) {
|
|
114
|
+
depNodes.push(depNode);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
(0, plan_work_dependency_1.planWorkDependency)(depNodes, node);
|
|
118
|
+
return node;
|
|
119
|
+
}
|
|
120
|
+
exports.getWorkNode = getWorkNode;
|
|
121
|
+
function mapLabels(labels) {
|
|
122
|
+
const result = {};
|
|
123
|
+
for (const [key, value] of Object.entries(labels)) {
|
|
124
|
+
result[key] = [value];
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
exports.mapLabels = mapLabels;
|
|
129
|
+
function parseWorkNode(id, task, context) {
|
|
130
|
+
const name = [...context.namePrefix, task.name].join(':');
|
|
131
|
+
const baseWorkNode = {
|
|
132
|
+
envs: task.envs,
|
|
133
|
+
id,
|
|
134
|
+
description: (0, template_value_1.templateValue)(task.description, task.envs),
|
|
135
|
+
continuous: task.continuous,
|
|
136
|
+
name,
|
|
137
|
+
cwd: task.cwd,
|
|
138
|
+
cmds: parseWorkNodeCommand(task, context, task.envs),
|
|
139
|
+
deps: [],
|
|
140
|
+
buildFile: task.build,
|
|
141
|
+
taskName: task.name,
|
|
142
|
+
src: parseLocalWorkNodeSource(task, context, task.envs),
|
|
143
|
+
generates: parseLocalWorkNodeGenerate(task, context, task.envs),
|
|
144
|
+
plannedTask: task,
|
|
145
|
+
needs: parseWorkNodeNeeds(task.needs, context),
|
|
146
|
+
labels: mapLabels(task.labels),
|
|
147
|
+
caching: task.cache ?? null,
|
|
148
|
+
};
|
|
129
149
|
if (task.image) {
|
|
150
|
+
const mounts = parseContainerWorkNodeMount(task, context, task.envs);
|
|
130
151
|
return {
|
|
131
152
|
...baseWorkNode,
|
|
132
153
|
type: 'container',
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
154
|
+
user: getContainerUser(),
|
|
155
|
+
image: (0, template_value_1.templateValue)(task.image, task.envs),
|
|
156
|
+
shell: (0, template_value_1.templateValue)(task.shell, task.envs) || '/bin/sh',
|
|
157
|
+
mounts: (0, get_container_mounts_1.getContainerMounts)(baseWorkNode, mounts),
|
|
136
158
|
ports: parseContainerWorkNodePorts(task, context, task.envs),
|
|
159
|
+
volumes: (0, plan_work_volume_1.getContainerVolumes)(baseWorkNode),
|
|
137
160
|
};
|
|
138
161
|
}
|
|
139
162
|
else {
|
|
@@ -144,46 +167,106 @@ function parseWorkNode(baseWorkNode, task, context) {
|
|
|
144
167
|
}
|
|
145
168
|
}
|
|
146
169
|
function parseContainerWorkNodePorts(task, context, envs) {
|
|
147
|
-
return task.ports.map((m) => template_value_1.templateValue(m, envs)).map((m) => parse_work_node_port_1.parseWorkNodePort(m));
|
|
170
|
+
return task.ports.map((m) => (0, template_value_1.templateValue)(m, envs)).map((m) => (0, parse_work_node_port_1.parseWorkNodePort)(m));
|
|
148
171
|
}
|
|
172
|
+
exports.parseContainerWorkNodePorts = parseContainerWorkNodePorts;
|
|
149
173
|
function parseContainerWorkNodeMount(task, context, envs) {
|
|
150
|
-
return task.mounts.map((m) => template_value_1.templateValue(m, envs)).map((m) => parse_work_node_mount_1.parseWorkNodeMount(context.
|
|
174
|
+
return task.mounts.map((m) => (0, template_value_1.templateValue)(m, envs)).map((m) => (0, parse_work_node_mount_1.parseWorkNodeMount)(context.cwd, m));
|
|
151
175
|
}
|
|
152
176
|
function parseLocalWorkNodeGenerate(task, context, envs) {
|
|
153
|
-
return getAbsolutePaths(task.generates, context.
|
|
177
|
+
return getAbsolutePaths(task.generates, context.cwd)
|
|
178
|
+
.map((g) => (0, template_value_1.templateValue)(g, envs))
|
|
179
|
+
.map((path) => ({ path, inherited: false }));
|
|
154
180
|
}
|
|
155
181
|
function parseLocalWorkNodeSource(task, context, envs) {
|
|
156
182
|
return task.src
|
|
157
183
|
.map((src) => ({
|
|
158
|
-
relativePath: template_value_1.templateValue(src.relativePath, envs),
|
|
184
|
+
relativePath: (0, template_value_1.templateValue)(src.relativePath, envs),
|
|
159
185
|
matcher: src.matcher,
|
|
160
186
|
}))
|
|
161
|
-
.map((src) => mapSource(src, context.
|
|
187
|
+
.map((src) => mapSource(src, context.cwd));
|
|
188
|
+
}
|
|
189
|
+
function getContainerUser() {
|
|
190
|
+
return (0, os_1.platform)() === 'linux' || (0, os_1.platform)() === 'freebsd' || (0, os_1.platform)() === 'openbsd' || (0, os_1.platform)() === 'sunos'
|
|
191
|
+
? `${process.getuid()}:${process.getgid()}`
|
|
192
|
+
: null;
|
|
193
|
+
}
|
|
194
|
+
function parseWorkNodeNeeds(needs, context) {
|
|
195
|
+
const result = [];
|
|
196
|
+
for (const need of needs) {
|
|
197
|
+
const service = need.build.services[need.name];
|
|
198
|
+
const id = (0, work_service_id_1.getWorkServiceId)(need.build, service);
|
|
199
|
+
if (!context.workTree.services[id]) {
|
|
200
|
+
const workService = {
|
|
201
|
+
id,
|
|
202
|
+
buildService: service,
|
|
203
|
+
name: need.name,
|
|
204
|
+
description: service.description,
|
|
205
|
+
ports: (service.ports || []).map((m) => (0, template_value_1.templateValue)(m, service.envs)).map((m) => (0, parse_work_node_port_1.parseWorkNodePort)(m)),
|
|
206
|
+
};
|
|
207
|
+
if (service.image) {
|
|
208
|
+
context.workTree.services[id] = {
|
|
209
|
+
...workService,
|
|
210
|
+
type: 'container-service',
|
|
211
|
+
cmd: service.cmd,
|
|
212
|
+
envs: service.envs || {},
|
|
213
|
+
image: service.image,
|
|
214
|
+
// user: getContainerUser(),
|
|
215
|
+
healthcheck: service.healthcheck,
|
|
216
|
+
mounts: (service.mounts || [])
|
|
217
|
+
.map((m) => (0, template_value_1.templateValue)(m, service.envs))
|
|
218
|
+
.map((m) => (0, parse_work_node_mount_1.parseWorkNodeMount)(need.build.path, m)),
|
|
219
|
+
volumes: (service.volumes || [])
|
|
220
|
+
.map((m) => (0, template_value_1.templateValue)(m, service.envs))
|
|
221
|
+
.map((m) => (0, parse_work_service_volume_1.parseWorkServiceVolume)(need.build.path, m)),
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
else if (!!service.context && !!service.selector) {
|
|
225
|
+
context.workTree.services[id] = {
|
|
226
|
+
...workService,
|
|
227
|
+
context: service.context,
|
|
228
|
+
selector: service.selector,
|
|
229
|
+
kubeconfig: service.kubeconfig ?? getDefaultKubeConfig(),
|
|
230
|
+
type: 'kubernetes-service',
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (!result.some((s) => s.id === id)) {
|
|
235
|
+
result.push(context.workTree.services[id]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
exports.parseWorkNodeNeeds = parseWorkNodeNeeds;
|
|
241
|
+
function getDefaultKubeConfig() {
|
|
242
|
+
return (0, path_1.join)((0, os_1.homedir)(), '.kube/config');
|
|
162
243
|
}
|
|
163
244
|
function parseWorkNodeCommand(task, context, envs) {
|
|
164
|
-
return plan_work_command_1.planWorkCommand(task.cmds.map((cmd) => {
|
|
245
|
+
return (0, plan_work_command_1.planWorkCommand)(task.cmds.map((cmd) => {
|
|
165
246
|
if (typeof cmd === 'string') {
|
|
166
|
-
return template_value_1.templateValue(cmd, envs);
|
|
247
|
+
return (0, template_value_1.templateValue)(cmd, envs);
|
|
167
248
|
}
|
|
168
249
|
else {
|
|
169
250
|
return {
|
|
170
|
-
cmd: template_value_1.templateValue(cmd.cmd, envs),
|
|
171
|
-
path: template_value_1.templateValue(cmd.path, envs),
|
|
251
|
+
cmd: (0, template_value_1.templateValue)(cmd.cmd, envs),
|
|
252
|
+
path: (0, template_value_1.templateValue)(cmd.path, envs),
|
|
172
253
|
type: cmd.type,
|
|
173
254
|
};
|
|
174
255
|
}
|
|
175
|
-
}), context.
|
|
256
|
+
}), context.cwd);
|
|
176
257
|
}
|
|
177
258
|
function mapSource(src, workDir) {
|
|
178
259
|
return {
|
|
179
260
|
matcher: src.matcher,
|
|
180
|
-
absolutePath: path_1.join(workDir, src.relativePath),
|
|
261
|
+
absolutePath: (0, path_1.join)(workDir, src.relativePath),
|
|
181
262
|
};
|
|
182
263
|
}
|
|
264
|
+
exports.mapSource = mapSource;
|
|
183
265
|
function getAbsolutePaths(dirs, workingDir) {
|
|
184
266
|
if (!dirs) {
|
|
185
267
|
return [];
|
|
186
268
|
}
|
|
187
|
-
return dirs.map((dir) => path_1.join(workingDir, dir));
|
|
269
|
+
return dirs.map((dir) => (0, path_1.join)(workingDir, dir));
|
|
188
270
|
}
|
|
271
|
+
exports.getAbsolutePaths = getAbsolutePaths;
|
|
189
272
|
//# sourceMappingURL=plan-work-node.js.map
|
|
@@ -1,13 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.iterateWorkNodes = exports.planWorkNodes = void 0;
|
|
3
|
+
exports.iterateWorkNodes = exports.iterateWorkServices = exports.planWorkNodes = void 0;
|
|
4
4
|
const plan_work_node_1 = require("./plan-work-node");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const work_context_1 = require("../work-context");
|
|
6
|
+
const label_values_1 = require("../../executer/label-values");
|
|
7
|
+
function planWorkNodes(build, options) {
|
|
8
|
+
const context = (0, work_context_1.createWorkContext)(build);
|
|
9
|
+
addWorkNodes(context, []);
|
|
10
|
+
const nodesIdsToRemove = [];
|
|
11
|
+
for (const [nodeId, node] of Object.entries(context.workTree.nodes)) {
|
|
12
|
+
if (!(0, label_values_1.matchesAllLabels)(options.filterLabels, node, context.workTree.nodes) ||
|
|
13
|
+
(0, label_values_1.matchesAnyLabel)(options.excludeLabels, node)) {
|
|
14
|
+
nodesIdsToRemove.push(nodeId);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
for (const nodeId of nodesIdsToRemove) {
|
|
18
|
+
removeNode(nodeId, context.workTree);
|
|
19
|
+
}
|
|
20
|
+
removeUnusedServices(context.workTree);
|
|
21
|
+
return context.workTree;
|
|
9
22
|
}
|
|
10
23
|
exports.planWorkNodes = planWorkNodes;
|
|
24
|
+
function removeUnusedServices(workTree) {
|
|
25
|
+
const needs = new Set();
|
|
26
|
+
for (const node of Object.values(workTree.nodes)) {
|
|
27
|
+
for (const need of node.needs) {
|
|
28
|
+
needs.add(need.id);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const services = Object.values(workTree.services);
|
|
32
|
+
for (const service of services) {
|
|
33
|
+
if (!needs.has(service.id)) {
|
|
34
|
+
delete workTree.services[service.id];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function removeNode(nodeId, workTree) {
|
|
39
|
+
const node = workTree.nodes[nodeId];
|
|
40
|
+
if (node) {
|
|
41
|
+
delete workTree.nodes[nodeId];
|
|
42
|
+
for (const node of Object.values(workTree.nodes)) {
|
|
43
|
+
if (node.deps.some((d) => d.id === nodeId)) {
|
|
44
|
+
removeNode(node.id, workTree);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function* iterateWorkServices(services) {
|
|
50
|
+
for (const serviceId of Object.keys(services)) {
|
|
51
|
+
const service = services[serviceId];
|
|
52
|
+
yield service;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.iterateWorkServices = iterateWorkServices;
|
|
11
56
|
function* iterateWorkNodes(nodes) {
|
|
12
57
|
for (const nodeId of Object.keys(nodes)) {
|
|
13
58
|
const node = nodes[nodeId];
|
|
@@ -15,16 +60,19 @@ function* iterateWorkNodes(nodes) {
|
|
|
15
60
|
}
|
|
16
61
|
}
|
|
17
62
|
exports.iterateWorkNodes = iterateWorkNodes;
|
|
18
|
-
function addWorkNodes(
|
|
19
|
-
if (files.indexOf(build.fileName) !== -1) {
|
|
63
|
+
function addWorkNodes(context, files) {
|
|
64
|
+
if (files.indexOf(context.build.fileName) !== -1) {
|
|
20
65
|
return;
|
|
21
66
|
}
|
|
22
|
-
files.push(build.fileName);
|
|
23
|
-
for (const
|
|
24
|
-
plan_work_node_1.
|
|
67
|
+
files.push(context.build.fileName);
|
|
68
|
+
for (const taskName of Object.keys(context.build.tasks)) {
|
|
69
|
+
(0, plan_work_node_1.getWorkNode)(context, { taskName });
|
|
70
|
+
}
|
|
71
|
+
for (const name of Object.keys(context.build.references)) {
|
|
72
|
+
addWorkNodes((0, work_context_1.createSubWorkContext)(context, { type: 'references', name }), files);
|
|
25
73
|
}
|
|
26
|
-
for (const
|
|
27
|
-
addWorkNodes(
|
|
74
|
+
for (const name of Object.keys(context.build.includes)) {
|
|
75
|
+
addWorkNodes((0, work_context_1.createSubWorkContext)(context, { type: 'includes', name }), files);
|
|
28
76
|
}
|
|
29
77
|
}
|
|
30
78
|
//# sourceMappingURL=plan-work-nodes.js.map
|
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.planWorkTree = void 0;
|
|
4
4
|
const plan_work_node_1 = require("./plan-work-node");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
5
|
+
const work_context_1 = require("../work-context");
|
|
6
|
+
function planWorkTree(build, options) {
|
|
7
|
+
const context = (0, work_context_1.createWorkContext)(build);
|
|
8
|
+
const result = (0, plan_work_node_1.getWorkNode)(context, { taskName: options.taskName });
|
|
9
|
+
return {
|
|
10
|
+
...context.workTree,
|
|
11
|
+
rootNode: result,
|
|
12
|
+
};
|
|
9
13
|
}
|
|
10
14
|
exports.planWorkTree = planWorkTree;
|
|
11
15
|
//# sourceMappingURL=plan-work-tree.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getContainerVolumes = exports.getVolumeName = exports.generateId = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
function generateId(generate) {
|
|
6
|
+
return (0, crypto_1.createHash)('sha1').update(generate).digest('hex');
|
|
7
|
+
}
|
|
8
|
+
exports.generateId = generateId;
|
|
9
|
+
function getVolumeName(generate) {
|
|
10
|
+
return `hammerkit-${generateId(generate)}`;
|
|
11
|
+
}
|
|
12
|
+
exports.getVolumeName = getVolumeName;
|
|
13
|
+
function getContainerVolumes(task) {
|
|
14
|
+
const volumes = [];
|
|
15
|
+
for (const generate of task.generates) {
|
|
16
|
+
const name = getVolumeName(generate.path);
|
|
17
|
+
volumes.push({
|
|
18
|
+
name,
|
|
19
|
+
containerPath: generate.path,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return volumes;
|
|
23
|
+
}
|
|
24
|
+
exports.getContainerVolumes = getContainerVolumes;
|
|
25
|
+
//# sourceMappingURL=plan-work-volume.js.map
|
package/dist/planner/validate.js
CHANGED
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validate = void 0;
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
async function* validate(buildFile, context, name) {
|
|
7
|
-
const tree = name ? plan_work_tree_1.planWorkTree(buildFile, name).nodes : plan_work_nodes_1.planWorkNodes(buildFile);
|
|
3
|
+
exports.checkIfContextExists = exports.hasCycle = exports.validate = void 0;
|
|
4
|
+
const read_build_file_1 = require("../parser/read-build-file");
|
|
5
|
+
async function* validate(workTree, context) {
|
|
8
6
|
const cycleNodes = [];
|
|
9
|
-
for (const
|
|
10
|
-
|
|
7
|
+
for (const service of Object.values(workTree.services)) {
|
|
8
|
+
if (!service.description) {
|
|
9
|
+
yield { type: 'warn', message: `missing description`, node: service };
|
|
10
|
+
}
|
|
11
|
+
if (service.type === 'container-service') {
|
|
12
|
+
if (!service.healthcheck) {
|
|
13
|
+
yield { type: 'warn', message: 'missing healthcheck', node: service };
|
|
14
|
+
}
|
|
15
|
+
for (const mount of service.mounts) {
|
|
16
|
+
if (!(await context.file.exists(mount.localPath))) {
|
|
17
|
+
yield {
|
|
18
|
+
type: 'warn',
|
|
19
|
+
message: `mount ${mount.localPath} does not exist`,
|
|
20
|
+
node: service,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
if (!(await context.file.exists(service.kubeconfig))) {
|
|
27
|
+
yield {
|
|
28
|
+
type: 'warn',
|
|
29
|
+
message: `kubeconfig ${service.kubeconfig} does not exist`,
|
|
30
|
+
node: service,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
else if (!(await checkIfContextExists(service, context))) {
|
|
34
|
+
yield {
|
|
35
|
+
type: 'warn',
|
|
36
|
+
message: `context ${service.context} does not exist in kubeconfig ${service.kubeconfig}`,
|
|
37
|
+
node: service,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const key of Object.keys(service.buildService.unknownProps)) {
|
|
42
|
+
yield {
|
|
43
|
+
type: 'warn',
|
|
44
|
+
message: `${key} is an unknown configuration`,
|
|
45
|
+
node: service,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const node of Object.values(workTree.nodes)) {
|
|
11
50
|
if (!node.description) {
|
|
12
51
|
yield { type: 'warn', message: `missing description`, node: node };
|
|
13
52
|
}
|
|
@@ -23,7 +62,7 @@ async function* validate(buildFile, context, name) {
|
|
|
23
62
|
};
|
|
24
63
|
}
|
|
25
64
|
}
|
|
26
|
-
for (const key of Object.keys(node.unknownProps)) {
|
|
65
|
+
for (const key of Object.keys(node.plannedTask.buildTask.unknownProps)) {
|
|
27
66
|
yield {
|
|
28
67
|
type: 'warn',
|
|
29
68
|
message: `${key} is an unknown configuration`,
|
|
@@ -52,4 +91,13 @@ function hasCycle(node, currentPath) {
|
|
|
52
91
|
}
|
|
53
92
|
return null;
|
|
54
93
|
}
|
|
94
|
+
exports.hasCycle = hasCycle;
|
|
95
|
+
async function checkIfContextExists(service, context) {
|
|
96
|
+
const kubeconfig = await (0, read_build_file_1.read)(service.kubeconfig, context);
|
|
97
|
+
if (kubeconfig.contexts && kubeconfig.contexts instanceof Array) {
|
|
98
|
+
return kubeconfig.contexts.some((c) => c['name'] === service.context);
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
exports.checkIfContextExists = checkIfContextExists;
|
|
55
103
|
//# sourceMappingURL=validate.js.map
|
|
@@ -1,3 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSubWorkContext = exports.createWorkContext = void 0;
|
|
4
|
+
function createWorkContext(build) {
|
|
5
|
+
return {
|
|
6
|
+
cwd: build.path,
|
|
7
|
+
namePrefix: [],
|
|
8
|
+
build,
|
|
9
|
+
workTree: { nodes: {}, services: {} },
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
exports.createWorkContext = createWorkContext;
|
|
13
|
+
function createSubWorkContext(context, options) {
|
|
14
|
+
const subBuildFile = context.build[options.type][options.name];
|
|
15
|
+
return {
|
|
16
|
+
build: subBuildFile,
|
|
17
|
+
workTree: context.workTree,
|
|
18
|
+
cwd: options.type === 'references' ? subBuildFile.path : context.cwd,
|
|
19
|
+
namePrefix: [...context.namePrefix, options.name],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
exports.createSubWorkContext = createSubWorkContext;
|
|
3
23
|
//# sourceMappingURL=work-context.js.map
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getWorkNodeId = void 0;
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
|
-
const
|
|
6
|
-
function getWorkNodeId(
|
|
7
|
-
const description =
|
|
5
|
+
const work_node_cache_description_1 = require("../optimizer/work-node-cache-description");
|
|
6
|
+
function getWorkNodeId(task) {
|
|
7
|
+
const description = (0, work_node_cache_description_1.getWorkNodeCacheDescription)(task);
|
|
8
8
|
const jsonData = JSON.stringify(description);
|
|
9
|
-
return crypto_1.createHash('sha1').update(jsonData).digest('hex');
|
|
9
|
+
return (0, crypto_1.createHash)('sha1').update(jsonData).digest('hex');
|
|
10
10
|
}
|
|
11
11
|
exports.getWorkNodeId = getWorkNodeId;
|
|
12
12
|
//# sourceMappingURL=work-node-id.js.map
|