hammerkit 1.5.0-alpha.1 → 1.5.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/Dockerfile +1 -1
- package/build.schema.json +338 -161
- package/dist/executer/docker-service.js +1 -1
- package/dist/executer/environment-mock.js +6 -3
- package/dist/executer/event-cache.js +2 -6
- package/dist/executer/execute-docker.js +1 -1
- package/dist/executer/execute.spec.js +1 -1
- package/dist/executer/execution-steps.js +10 -1
- package/dist/executer/get-docker-executor.js +34 -7
- package/dist/executer/schedule.js +4 -6
- package/dist/executer/start-node.js +11 -3
- package/dist/executer/watch-node.js +0 -1
- package/dist/index.js +5 -2
- package/dist/log.js +30 -30
- package/dist/logging/grouped-logger.js +2 -2
- package/dist/logging/interactive-logger.js +3 -3
- package/dist/logging/live-logger.js +1 -1
- package/dist/optimizer/get-work-node-cache-stats.js +8 -2
- package/dist/optimizer/work-node-cache-description.js +1 -1
- package/dist/parser/default-build-file.js +22 -0
- package/dist/parser/parse-build-file-references.js +13 -2
- package/dist/parser/parse-build-file.js +25 -3
- package/dist/planner/utils/parse-work-service-volume.js +2 -0
- package/dist/planner/utils/plan-work-dependency.js +4 -1
- package/dist/planner/utils/plan-work-node.js +27 -6
- package/dist/planner/utils/plan-work-volume.js +2 -0
- package/dist/planner/work-node-status.js +2 -1
- package/dist/program.js +23 -22
- package/dist/testing/example-test-suite.js +17 -6
- package/dist/testing/integration/cache.spec.js +3 -3
- package/dist/testing/integration/cancellation.spec.js +1 -1
- package/dist/testing/integration/clean.spec.js +1 -1
- package/dist/testing/integration/cmd.spec.js +1 -1
- package/dist/testing/integration/concurrency.spec.js +1 -1
- package/dist/testing/integration/docker.spec.js +1 -1
- package/dist/testing/integration/env.spec.js +1 -1
- package/dist/testing/integration/error.spec.js +1 -1
- package/dist/testing/integration/extend.spec.js +2 -2
- package/dist/testing/integration/glob.spec.js +1 -1
- package/dist/testing/integration/include.spec.js +1 -1
- package/dist/testing/integration/invalid.spec.js +1 -1
- package/dist/testing/integration/invalid_loop.spec.js +1 -1
- package/dist/testing/integration/kubernetes.spec.js +1 -1
- package/dist/testing/integration/labels.spec.js +1 -1
- package/dist/testing/integration/local.spec.js +1 -1
- package/dist/testing/integration/monorepo.spec.js +1 -1
- package/dist/testing/integration/multi-line.spec.js +1 -1
- package/dist/testing/integration/reference.spec.js +1 -1
- package/dist/testing/integration/services.spec.js +7 -1
- package/dist/testing/integration/store.spec.js +2 -2
- package/dist/testing/integration/unknown.spec.js +1 -1
- package/dist/testing/integration/validate.spec.js +1 -1
- package/dist/testing/integration/watch-dependency.spec.js +30 -0
- package/dist/testing/integration/watch.spec.js +1 -1
- package/dist/utils/empty-writable.js +13 -0
- package/logs/cache-console.log +0 -0
- package/logs/cache-status.log +6 -0
- package/logs/cache-stout.log +0 -0
- package/logs/cancellation-console.log +0 -0
- package/logs/cancellation-status.log +3 -0
- package/logs/cancellation-stout.log +3 -0
- package/logs/clean-console.log +0 -0
- package/logs/clean-status.log +37 -0
- package/logs/clean-stout.log +95 -0
- package/logs/cmd-console.log +0 -0
- package/logs/cmd-status.log +8 -0
- package/logs/cmd-stout.log +9 -0
- package/logs/concurrency-console.log +0 -0
- package/logs/concurrency-status.log +14 -0
- package/logs/concurrency-stout.log +88 -0
- package/logs/docker-console.log +0 -0
- package/logs/docker-status.log +14 -0
- package/logs/docker-stout.log +39 -0
- package/logs/env-console.log +1 -0
- package/logs/env-status.log +1 -0
- package/logs/env-stout.log +0 -0
- package/logs/error-console.log +0 -0
- package/logs/error-status.log +10 -0
- package/logs/error-stout.log +36 -0
- package/logs/extend-console.log +0 -0
- package/logs/extend-status.log +1 -0
- package/logs/extend-stout.log +0 -0
- package/logs/glob-console.log +28 -0
- package/logs/glob-status.log +23 -0
- package/logs/glob-stout.log +52 -0
- package/logs/hello-world-node-console.log +0 -0
- package/logs/hello-world-node-status.log +37 -0
- package/logs/hello-world-node-stout.log +41 -0
- package/logs/include-console.log +0 -0
- package/logs/include-status.log +3 -0
- package/logs/include-stout.log +0 -0
- package/logs/invalid-console.log +0 -0
- package/logs/invalid-status.log +1 -0
- package/logs/invalid-stout.log +0 -0
- package/logs/invalid_loop-console.log +0 -0
- package/logs/invalid_loop-status.log +1 -0
- package/logs/invalid_loop-stout.log +11 -0
- package/logs/labels-console.log +0 -0
- package/logs/labels-status.log +1 -0
- package/logs/labels-stout.log +0 -0
- package/logs/local-console.log +0 -0
- package/logs/local-status.log +7 -0
- package/logs/local-stout.log +8 -0
- package/logs/monorepo-console.log +0 -0
- package/logs/monorepo-status.log +152 -0
- package/logs/monorepo-stout.log +2354 -0
- package/logs/multi-line-console.log +0 -0
- package/logs/multi-line-status.log +1 -0
- package/logs/multi-line-stout.log +0 -0
- package/logs/reference-console.log +0 -0
- package/logs/reference-status.log +5 -0
- package/logs/reference-stout.log +0 -0
- package/logs/services-console.log +0 -0
- package/logs/services-status.log +129 -0
- package/logs/services-stout.log +639 -0
- package/logs/store-restore-console.log +0 -0
- package/logs/store-restore-status.log +40 -0
- package/logs/store-restore-stout.log +97 -0
- package/logs/unknown-console.log +3 -0
- package/logs/unknown-status.log +1 -0
- package/logs/unknown-stout.log +0 -0
- package/logs/validate-console.log +0 -0
- package/logs/validate-status.log +2 -0
- 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 +176 -0
- package/logs/watch-dependency-stout.log +779 -0
- package/logs/watch-status.log +100 -0
- package/logs/watch-stout.log +349 -0
- package/package.json +1 -1
|
@@ -21,7 +21,7 @@ async function startContainer(status, container) {
|
|
|
21
21
|
return new Promise((resolve, reject) => {
|
|
22
22
|
const handle = setTimeout(() => {
|
|
23
23
|
status.write('warn', 'start of container is potentially stuck on start');
|
|
24
|
-
},
|
|
24
|
+
}, 10000);
|
|
25
25
|
container
|
|
26
26
|
.start()
|
|
27
27
|
.then(() => {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const get_test_suite_1 = require("../testing/get-test-suite");
|
|
4
4
|
const expect_1 = require("../testing/expect");
|
|
5
5
|
describe('execute', () => {
|
|
6
|
-
const suite = (0, get_test_suite_1.getTestSuite)('hello-world-node', ['
|
|
6
|
+
const suite = (0, get_test_suite_1.getTestSuite)('hello-world-node', ['.hammerkit.yaml', 'package.json', 'index.js']);
|
|
7
7
|
afterAll(() => suite.close());
|
|
8
8
|
it('should restart watching task if once completed', async () => {
|
|
9
9
|
const { cli, environment } = await suite.setup({ taskName: 'api' });
|
|
@@ -19,7 +19,16 @@ exports.pullImage = pullImage;
|
|
|
19
19
|
async function prepareVolume(node, environment) {
|
|
20
20
|
if ((0, work_node_1.isContainerWorkNode)(node) || (0, work_service_1.isContainerWorkService)(node)) {
|
|
21
21
|
for (const volume of node.volumes) {
|
|
22
|
-
|
|
22
|
+
if (volume.resetOnChange && !volume.inherited) {
|
|
23
|
+
const scopedConsole = environment.status.from(node);
|
|
24
|
+
scopedConsole.write('debug', 'recreate volume');
|
|
25
|
+
await (0, get_docker_executor_1.recreateVolume)(environment, scopedConsole, volume.name);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
const scopedConsole = environment.status.from(node);
|
|
29
|
+
scopedConsole.write('debug', 'ensure volume exists');
|
|
30
|
+
await (0, get_docker_executor_1.ensureVolumeExists)(environment, scopedConsole, volume.name);
|
|
31
|
+
}
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureVolumeExists = exports.existsVolume = void 0;
|
|
3
|
+
exports.recreateVolume = exports.removeVolume = exports.createVolume = exports.ensureVolumeExists = exports.existsVolume = void 0;
|
|
4
|
+
const log_1 = require("../log");
|
|
4
5
|
async function existsVolume(environment, volumeName) {
|
|
5
6
|
try {
|
|
6
7
|
const volume = await environment.docker.getVolume(volumeName);
|
|
@@ -11,15 +12,41 @@ async function existsVolume(environment, volumeName) {
|
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
exports.existsVolume = existsVolume;
|
|
14
|
-
async function ensureVolumeExists(environment, volumeName) {
|
|
15
|
+
async function ensureVolumeExists(environment, scopedConsole, volumeName) {
|
|
15
16
|
const volumeExists = await existsVolume(environment, volumeName);
|
|
16
17
|
if (!volumeExists) {
|
|
17
|
-
await
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
18
|
+
await createVolume(environment, scopedConsole, volumeName);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
scopedConsole.write('debug', 'volume exists ' + volumeName);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
exports.ensureVolumeExists = ensureVolumeExists;
|
|
25
|
+
async function createVolume(environment, scopedConsole, volumeName) {
|
|
26
|
+
scopedConsole.write('debug', 'create volume ' + volumeName);
|
|
27
|
+
await environment.docker.createVolume({
|
|
28
|
+
Name: volumeName,
|
|
29
|
+
Driver: 'local',
|
|
30
|
+
Labels: { app: 'hammerkit' },
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.createVolume = createVolume;
|
|
34
|
+
async function removeVolume(environment, scopedConsole, volumeName) {
|
|
35
|
+
try {
|
|
36
|
+
const volume = await environment.docker.getVolume(volumeName);
|
|
37
|
+
scopedConsole.write('debug', 'remove volume ' + volumeName);
|
|
38
|
+
await volume.remove({ force: true });
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
scopedConsole.write('warn', `removing volume ${volumeName} failed: ${(0, log_1.getErrorMessage)(e)}`);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.removeVolume = removeVolume;
|
|
47
|
+
async function recreateVolume(environment, scopedConsole, volumeName) {
|
|
48
|
+
await removeVolume(environment, scopedConsole, volumeName);
|
|
49
|
+
await createVolume(environment, scopedConsole, volumeName);
|
|
50
|
+
}
|
|
51
|
+
exports.recreateVolume = recreateVolume;
|
|
25
52
|
//# sourceMappingURL=get-docker-executor.js.map
|
|
@@ -31,9 +31,8 @@ async function schedule(processManager, state, environment) {
|
|
|
31
31
|
type: 'task',
|
|
32
32
|
name: nodeState.node.name,
|
|
33
33
|
id: nodeState.node.id + '-cache',
|
|
34
|
-
}, async () => {
|
|
35
|
-
|
|
36
|
-
await (0, start_node_1.startNode)(nodeState, state, environment);
|
|
34
|
+
}, async (abort) => {
|
|
35
|
+
await (0, start_node_1.startNode)(nodeState, state, environment, abort.signal);
|
|
37
36
|
});
|
|
38
37
|
}
|
|
39
38
|
else if (nodeState.type === 'ready') {
|
|
@@ -65,9 +64,8 @@ async function schedule(processManager, state, environment) {
|
|
|
65
64
|
type: 'service',
|
|
66
65
|
name: pendingNeed.service.name,
|
|
67
66
|
id: pendingNeed.service.id + '-cache',
|
|
68
|
-
}, async () => {
|
|
69
|
-
|
|
70
|
-
await (0, start_node_1.startService)(pendingNeed.service, state, environment);
|
|
67
|
+
}, async (abort) => {
|
|
68
|
+
await (0, start_node_1.startService)(pendingNeed.service, state, environment, abort.signal);
|
|
71
69
|
});
|
|
72
70
|
}
|
|
73
71
|
continue;
|
|
@@ -5,9 +5,12 @@ const enqueue_next_1 = require("./scheduler/enqueue-next");
|
|
|
5
5
|
const states_1 = require("./states");
|
|
6
6
|
const work_service_1 = require("../planner/work-service");
|
|
7
7
|
const get_work_node_cache_stats_1 = require("../optimizer/get-work-node-cache-stats");
|
|
8
|
-
async function startNode(node, state, environment) {
|
|
8
|
+
async function startNode(node, state, environment, abortSignal) {
|
|
9
9
|
const cacheState = await (0, enqueue_next_1.checkCacheState)(node.node, state.current.cacheMethod, environment);
|
|
10
10
|
const currentState = state.current.node[node.node.id];
|
|
11
|
+
if (abortSignal.aborted) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
11
14
|
if (!!currentState.stateKey && currentState.stateKey !== cacheState.stateKey) {
|
|
12
15
|
const status = environment.status.task(node.node);
|
|
13
16
|
status.write('debug', `cache check for ${node.node.name} no longer valid, skipping result`);
|
|
@@ -32,12 +35,17 @@ async function startNode(node, state, environment) {
|
|
|
32
35
|
}
|
|
33
36
|
}
|
|
34
37
|
exports.startNode = startNode;
|
|
35
|
-
async function startService(service, state, environment) {
|
|
38
|
+
async function startService(service, state, environment, abortSignal) {
|
|
39
|
+
const currentStats = await (0, get_work_node_cache_stats_1.getServiceNodeCacheStats)(service, environment);
|
|
40
|
+
const stateKey = (0, get_work_node_cache_stats_1.getStateKey)(currentStats, state.current.cacheMethod);
|
|
41
|
+
if (abortSignal.aborted) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
36
44
|
if (!(0, work_service_1.isContainerWorkService)(service)) {
|
|
37
45
|
state.patchService({
|
|
38
46
|
type: 'ready',
|
|
39
47
|
service,
|
|
40
|
-
stateKey
|
|
48
|
+
stateKey,
|
|
41
49
|
});
|
|
42
50
|
return;
|
|
43
51
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ const log_1 = require("./log");
|
|
|
6
6
|
const get_file_context_1 = require("./file/get-file-context");
|
|
7
7
|
const work_node_status_1 = require("./planner/work-node-status");
|
|
8
8
|
const execute_docker_1 = require("./executer/execute-docker");
|
|
9
|
+
const empty_writable_1 = require("./utils/empty-writable");
|
|
9
10
|
const abortCtrl = new AbortController();
|
|
10
11
|
process.on('SIGINT', function () {
|
|
11
12
|
abortCtrl.abort();
|
|
@@ -15,9 +16,11 @@ process.on('SIGINT', function () {
|
|
|
15
16
|
abortCtrl,
|
|
16
17
|
processEnvs: process.env,
|
|
17
18
|
file: (0, get_file_context_1.getFileContext)(process.cwd()),
|
|
18
|
-
console: (0, log_1.consoleContext)(),
|
|
19
|
-
status: (0, work_node_status_1.statusConsole)(),
|
|
19
|
+
console: (0, log_1.consoleContext)(process.stdout),
|
|
20
|
+
status: (0, work_node_status_1.statusConsole)((0, empty_writable_1.emptyWritable)()),
|
|
20
21
|
docker: (0, execute_docker_1.getContainerCli)(),
|
|
22
|
+
stdout: process.stdout,
|
|
23
|
+
stdoutColumns: process.stdout.columns,
|
|
21
24
|
}, process.argv).then(({ program, args }) => {
|
|
22
25
|
return program.parseAsync(args);
|
|
23
26
|
});
|
package/dist/log.js
CHANGED
|
@@ -40,24 +40,24 @@ function getErrorMessage(e) {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
exports.getErrorMessage = getErrorMessage;
|
|
43
|
-
function consoleContext() {
|
|
43
|
+
function consoleContext(stream) {
|
|
44
44
|
return {
|
|
45
45
|
debug(message) {
|
|
46
|
-
|
|
46
|
+
stream.write(`${formatDate(new Date())} ${getType('cli')} ${getLogLevel('debug')}: ${message}\n`);
|
|
47
47
|
},
|
|
48
48
|
error(message) {
|
|
49
|
-
|
|
49
|
+
stream.write(`${formatDate(new Date())} ${getType('cli')} ${getLogLevel('error')}: ${message}\n`);
|
|
50
50
|
},
|
|
51
51
|
info(message) {
|
|
52
|
-
|
|
52
|
+
stream.write(`${formatDate(new Date())} ${getType('cli')} ${getLogLevel('info')}: ${message}\n`);
|
|
53
53
|
},
|
|
54
54
|
warn(message) {
|
|
55
|
-
|
|
55
|
+
stream.write(`${formatDate(new Date())} ${getType('cli')} ${getLogLevel('warn')}: ${message}\n`);
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
exports.consoleContext = consoleContext;
|
|
60
|
-
exports.isVerbose = process.argv.some((a) => a === '--verbose');
|
|
60
|
+
exports.isVerbose = process.argv.some((a) => a === '--verbose') || process.env['VERBOSE'] === 'true';
|
|
61
61
|
const typeLength = ['service', 'task', 'cli']
|
|
62
62
|
.map((s) => s.length)
|
|
63
63
|
.reduce((max, current) => (max > current ? max : current), 0);
|
|
@@ -69,14 +69,14 @@ async function printWorkTreeResult(schedulerState, env) {
|
|
|
69
69
|
const maxNodeNameLength = getNodeNameLengthForSchedulerState(schedulerState);
|
|
70
70
|
for (const log of env.status.read()) {
|
|
71
71
|
if (exports.isVerbose || (log.type === 'status' && log.level === 'error')) {
|
|
72
|
-
|
|
72
|
+
env.stdout.write(`${formatDate(log.date)} ${getType(log.context.type)} ${getNodeName(log.context.name, maxNodeNameLength)} - ${colors_1.default.white(log.message)}\n`);
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
for (const state of (0, plan_work_nodes_1.iterateWorkServices)(schedulerState.service)) {
|
|
76
76
|
if (state.type === 'end' && state.reason === 'crash') {
|
|
77
77
|
const message = `${getType('service')} ${getNodeName(state.service.name, maxNodeNameLength)}`;
|
|
78
78
|
for (const log of env.status.service(state.service).logs()) {
|
|
79
|
-
|
|
79
|
+
env.stdout.write(`${formatDate(log.date)} ${message} - ${log.console}: ${log.message}\n`);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
}
|
|
@@ -84,7 +84,7 @@ async function printWorkTreeResult(schedulerState, env) {
|
|
|
84
84
|
if (state.type === 'error' || state.type === 'crash') {
|
|
85
85
|
const message = `${getType('task')} ${getNodeName(state.node.name, maxNodeNameLength)}`;
|
|
86
86
|
for (const log of env.status.task(state.node).logs()) {
|
|
87
|
-
|
|
87
|
+
env.stdout.write(`${formatDate(log.date)} ${message} - ${log.console}: ${log.message}\n`);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -94,7 +94,7 @@ async function printWorkTreeResult(schedulerState, env) {
|
|
|
94
94
|
if (state.reason === 'crash') {
|
|
95
95
|
message += ` crashed`;
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
env.stdout.write(`${message}\n`);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
for (const state of (0, plan_work_nodes_1.iterateWorkNodes)(schedulerState.node)) {
|
|
@@ -111,7 +111,7 @@ async function printWorkTreeResult(schedulerState, env) {
|
|
|
111
111
|
if (state.type === 'error') {
|
|
112
112
|
message += ` with message ${state.errorMessage}`;
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
env.stdout.write(`${message}\n`);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
exports.printWorkTreeResult = printWorkTreeResult;
|
|
@@ -157,16 +157,16 @@ function getNodeNameLengthForSchedulerState(schedulerState) {
|
|
|
157
157
|
return getNodeNameLength(Names);
|
|
158
158
|
}
|
|
159
159
|
exports.getNodeNameLengthForSchedulerState = getNodeNameLengthForSchedulerState;
|
|
160
|
-
function printProperty(name, value) {
|
|
161
|
-
|
|
160
|
+
function printProperty(env, name, value) {
|
|
161
|
+
env.stdout.write(` ${colors_1.default.grey(`${name}:`)} ${value}\n`);
|
|
162
162
|
}
|
|
163
163
|
exports.printProperty = printProperty;
|
|
164
|
-
function printItem(item) {
|
|
165
|
-
|
|
164
|
+
function printItem(env, item) {
|
|
165
|
+
env.stdout.write(`• ${item.name}${item.description ? `: ${colors_1.default.white(item.description)}` : ''}\n`);
|
|
166
166
|
}
|
|
167
167
|
exports.printItem = printItem;
|
|
168
|
-
function printTitle(name) {
|
|
169
|
-
|
|
168
|
+
function printTitle(env, name) {
|
|
169
|
+
env.stdout.write(`${colors_1.default.bgWhite(name + ':\n')}`);
|
|
170
170
|
}
|
|
171
171
|
exports.printTitle = printTitle;
|
|
172
172
|
function getNodeNameLength(names) {
|
|
@@ -195,7 +195,7 @@ function getNodeName(name, maxNodeNameLength) {
|
|
|
195
195
|
return colors_1.default.white(name) + ' '.repeat(Math.max(0, maxNodeNameLength - name.length));
|
|
196
196
|
}
|
|
197
197
|
exports.getNodeName = getNodeName;
|
|
198
|
-
function writeNodeLogToConsole(log, maxNodeNameLength) {
|
|
198
|
+
function writeNodeLogToConsole(env, log, maxNodeNameLength) {
|
|
199
199
|
if (log.type === 'status') {
|
|
200
200
|
if (log.level === 'debug' && !exports.isVerbose) {
|
|
201
201
|
return;
|
|
@@ -206,7 +206,7 @@ function writeNodeLogToConsole(log, maxNodeNameLength) {
|
|
|
206
206
|
? colors_1.default.white(log.message)
|
|
207
207
|
: colors_1.default.red(log.message)
|
|
208
208
|
: `${getLogLevel(log.level)} - ${log.message}`;
|
|
209
|
-
|
|
209
|
+
env.stdout.write(`${formatDate(log.date)} ${colors_1.default.grey(log.context.type + ':')} ${getNodeName(log.context.name, maxNodeNameLength)} - ${log.date.toLocaleTimeString()} - ${content}\n`);
|
|
210
210
|
}
|
|
211
211
|
exports.writeNodeLogToConsole = writeNodeLogToConsole;
|
|
212
212
|
function formatDate(date) {
|
|
@@ -223,7 +223,7 @@ function formatDate(date) {
|
|
|
223
223
|
}
|
|
224
224
|
exports.formatDate = formatDate;
|
|
225
225
|
function writeWorkTreeStatus(schedulerState, env, ticker) {
|
|
226
|
-
(0, readline_1.clearScreenDown)(
|
|
226
|
+
(0, readline_1.clearScreenDown)(env.stdout);
|
|
227
227
|
const maxNodeNameLength = getNodeNameLengthForSchedulerState(schedulerState);
|
|
228
228
|
let count = 0;
|
|
229
229
|
for (const state of (0, plan_work_nodes_1.iterateWorkServices)(schedulerState.service)) {
|
|
@@ -232,7 +232,7 @@ function writeWorkTreeStatus(schedulerState, env, ticker) {
|
|
|
232
232
|
if (currentMessage) {
|
|
233
233
|
message += ` ${currentMessage.message}`;
|
|
234
234
|
}
|
|
235
|
-
count += printWithTruncate(message);
|
|
235
|
+
count += printWithTruncate(env, message);
|
|
236
236
|
}
|
|
237
237
|
for (const state of (0, plan_work_nodes_1.iterateWorkNodes)(schedulerState.node)) {
|
|
238
238
|
let message = `${getType('task')} ${getNodeName(state.node.name, maxNodeNameLength)} - ${getStateText(state)}`;
|
|
@@ -271,9 +271,9 @@ function writeWorkTreeStatus(schedulerState, env, ticker) {
|
|
|
271
271
|
else if (state.type === 'error') {
|
|
272
272
|
message += ` ${state.errorMessage}`;
|
|
273
273
|
}
|
|
274
|
-
count += printWithTruncate(message);
|
|
274
|
+
count += printWithTruncate(env, message);
|
|
275
275
|
}
|
|
276
|
-
(0, readline_1.moveCursor)(
|
|
276
|
+
(0, readline_1.moveCursor)(env.stdout, 0, -1 * count);
|
|
277
277
|
}
|
|
278
278
|
exports.writeWorkTreeStatus = writeWorkTreeStatus;
|
|
279
279
|
function countChar(message, char) {
|
|
@@ -285,24 +285,24 @@ function countChar(message, char) {
|
|
|
285
285
|
}
|
|
286
286
|
return result;
|
|
287
287
|
}
|
|
288
|
-
function printWithTruncate(message) {
|
|
288
|
+
function printWithTruncate(env, message) {
|
|
289
289
|
let lineCount = 0;
|
|
290
290
|
let index = 0;
|
|
291
291
|
do {
|
|
292
292
|
const newLineCount = countChar(message, '\n');
|
|
293
|
-
|
|
294
|
-
index +=
|
|
293
|
+
env.stdout.write(`${message.substr(index, env.stdoutColumns)}\n`);
|
|
294
|
+
index += env.stdoutColumns;
|
|
295
295
|
lineCount++;
|
|
296
296
|
lineCount += newLineCount;
|
|
297
297
|
} while (index < message.length);
|
|
298
298
|
return lineCount;
|
|
299
299
|
}
|
|
300
|
-
function hideCursor() {
|
|
301
|
-
|
|
300
|
+
function hideCursor(env) {
|
|
301
|
+
env.stdout.write('\x1B[?25l');
|
|
302
302
|
}
|
|
303
303
|
exports.hideCursor = hideCursor;
|
|
304
|
-
function showCursor() {
|
|
305
|
-
|
|
304
|
+
function showCursor(env) {
|
|
305
|
+
env.stdout.write('\x1B[?25h');
|
|
306
306
|
}
|
|
307
307
|
exports.showCursor = showCursor;
|
|
308
308
|
//# sourceMappingURL=log.js.map
|
|
@@ -15,7 +15,7 @@ function groupedLogger(state, env) {
|
|
|
15
15
|
if (node.type === 'crash' || node.type === 'error' || node.type === 'completed') {
|
|
16
16
|
completedNodes.push(node.node.id);
|
|
17
17
|
for (const log of env.status.task(node.node).read()) {
|
|
18
|
-
(0, log_1.writeNodeLogToConsole)(log, maxNodeNameLength);
|
|
18
|
+
(0, log_1.writeNodeLogToConsole)(env, log, maxNodeNameLength);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -26,7 +26,7 @@ function groupedLogger(state, env) {
|
|
|
26
26
|
if (service.type === 'end') {
|
|
27
27
|
completedServices.push(service.service.id);
|
|
28
28
|
for (const log of env.status.service(service.service).read()) {
|
|
29
|
-
(0, log_1.writeNodeLogToConsole)(log, maxNodeNameLength);
|
|
29
|
+
(0, log_1.writeNodeLogToConsole)(env, log, maxNodeNameLength);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -16,7 +16,7 @@ function interactiveLogger(state, env) {
|
|
|
16
16
|
setTimeout(tickerFn, 100);
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
-
(0, log_1.hideCursor)();
|
|
19
|
+
(0, log_1.hideCursor)(env);
|
|
20
20
|
tickerFn();
|
|
21
21
|
state.on((currentState) => {
|
|
22
22
|
(0, log_1.writeWorkTreeStatus)(currentState, env, count);
|
|
@@ -24,9 +24,9 @@ function interactiveLogger(state, env) {
|
|
|
24
24
|
return {
|
|
25
25
|
async complete(evt, env) {
|
|
26
26
|
running = false;
|
|
27
|
-
(0, readline_1.clearScreenDown)(
|
|
27
|
+
(0, readline_1.clearScreenDown)(env.stdout);
|
|
28
28
|
await (0, log_1.printWorkTreeResult)(evt.state, env);
|
|
29
|
-
(0, log_1.showCursor)();
|
|
29
|
+
(0, log_1.showCursor)(env);
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
32
|
}
|
|
@@ -5,7 +5,7 @@ const log_1 = require("../log");
|
|
|
5
5
|
function liveLogger(state, env) {
|
|
6
6
|
const maxNodeNameLength = (0, log_1.getNodeNameLengthForWorkTree)(state.current.node, state.current.service);
|
|
7
7
|
env.status.on((log) => {
|
|
8
|
-
(0, log_1.writeNodeLogToConsole)(log, maxNodeNameLength);
|
|
8
|
+
(0, log_1.writeNodeLogToConsole)(env, log, maxNodeNameLength);
|
|
9
9
|
});
|
|
10
10
|
return {
|
|
11
11
|
async complete(evt, env) {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getStateKey = exports.getCacheState = exports.getWorkNodeCacheStats = exports.getServiceNodeCacheStats = void 0;
|
|
4
4
|
const calculate_checksum_1 = require("./calculate-checksum");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
+
const work_service_1 = require("../planner/work-service");
|
|
6
7
|
const crypto_1 = require("crypto");
|
|
7
8
|
async function addWorkNodeCacheStats(result, cwd, path, matcher, context) {
|
|
8
9
|
const exists = await context.file.exists(path);
|
|
@@ -47,8 +48,13 @@ async function getServiceNodeCacheStats(cache, environment) {
|
|
|
47
48
|
const result = {
|
|
48
49
|
files: {},
|
|
49
50
|
};
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if ((0, work_service_1.isContainerWorkService)(cache)) {
|
|
52
|
+
for (const mount of cache.mounts) {
|
|
53
|
+
await addWorkServiceCacheStats(result, mount.localPath, environment);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
await addWorkServiceCacheStats(result, cache.kubeconfig, environment);
|
|
52
58
|
}
|
|
53
59
|
return result;
|
|
54
60
|
}
|
|
@@ -7,7 +7,7 @@ function getWorkNodeCacheDescription(task) {
|
|
|
7
7
|
shell: task.shell ?? undefined,
|
|
8
8
|
image: task.image ?? undefined,
|
|
9
9
|
platform: task.image ? 'container' : (0, os_1.platform)(),
|
|
10
|
-
generates: task.generates.sort() ?? undefined,
|
|
10
|
+
generates: task.generates.map((g) => g.path).sort() ?? undefined,
|
|
11
11
|
src: task.src.map((s) => s.relativePath).sort() ?? undefined,
|
|
12
12
|
deps: task.deps.map((d) => d.name).sort() ?? undefined,
|
|
13
13
|
envs: Object.keys(task.envs)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultBuildFilename = void 0;
|
|
4
|
+
const path_1 = require("path");
|
|
5
|
+
async function getDefaultBuildFilename(folder, env) {
|
|
6
|
+
const fileNames = ['.hammerkit.yaml', '.hammerkit.yml', 'build.yaml'];
|
|
7
|
+
const existingFiles = [];
|
|
8
|
+
for (const fileName of fileNames) {
|
|
9
|
+
if (await env.file.exists((0, path_1.join)(folder, fileName))) {
|
|
10
|
+
existingFiles.push(fileName);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (existingFiles.length > 1) {
|
|
14
|
+
env.console.warn(`multiple hammerkit files ${existingFiles.join(', ')} in ${folder}`);
|
|
15
|
+
}
|
|
16
|
+
if (existingFiles.length > 0) {
|
|
17
|
+
return existingFiles[0];
|
|
18
|
+
}
|
|
19
|
+
return fileNames[0];
|
|
20
|
+
}
|
|
21
|
+
exports.getDefaultBuildFilename = getDefaultBuildFilename;
|
|
22
|
+
//# sourceMappingURL=default-build-file.js.map
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseBuildFileReferences = void 0;
|
|
4
4
|
const path_1 = require("path");
|
|
5
5
|
const read_build_file_1 = require("./read-build-file");
|
|
6
|
+
const default_build_file_1 = require("./default-build-file");
|
|
6
7
|
async function parseBuildFileReferences(type, fileName, files, refs, context) {
|
|
7
8
|
if (!refs) {
|
|
8
9
|
return {};
|
|
@@ -14,9 +15,19 @@ async function parseBuildFileReferences(type, fileName, files, refs, context) {
|
|
|
14
15
|
for (const [key, value] of Object.entries(refs || {})) {
|
|
15
16
|
const referenceFileName = (0, path_1.join)((0, path_1.dirname)(fileName), value);
|
|
16
17
|
if (!(await context.file.exists(referenceFileName))) {
|
|
17
|
-
throw new Error(`${fileName} ${type} ${key} not found`);
|
|
18
|
+
throw new Error(`${fileName} ${type} ${key} ${referenceFileName} not found`);
|
|
19
|
+
}
|
|
20
|
+
const stats = await context.file.stats(referenceFileName);
|
|
21
|
+
if (stats.type === 'directory') {
|
|
22
|
+
const defaultReferenceFileName = (0, path_1.join)(referenceFileName, await (0, default_build_file_1.getDefaultBuildFilename)(referenceFileName, context));
|
|
23
|
+
if (!(await context.file.exists(defaultReferenceFileName))) {
|
|
24
|
+
throw new Error(`${fileName} ${type} ${key} ${defaultReferenceFileName} not found in ${referenceFileName}`);
|
|
25
|
+
}
|
|
26
|
+
result[key] = await (0, read_build_file_1.readBuildFile)(defaultReferenceFileName, files, context);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
result[key] = await (0, read_build_file_1.readBuildFile)(referenceFileName, files, context);
|
|
18
30
|
}
|
|
19
|
-
result[key] = await (0, read_build_file_1.readBuildFile)(referenceFileName, files, context);
|
|
20
31
|
}
|
|
21
32
|
return result;
|
|
22
33
|
}
|
|
@@ -10,6 +10,7 @@ const parse_build_file_task_source_1 = require("./parse-build-file-task-source")
|
|
|
10
10
|
const parse_build_file_task_command_1 = require("./parse-build-file-task-command");
|
|
11
11
|
const parse_build_file_services_1 = require("./parse-build-file-services");
|
|
12
12
|
const parse_string_map_1 = require("./parse-string-map");
|
|
13
|
+
const parse_context_1 = require("./parse-context");
|
|
13
14
|
const parse_string_1 = require("./parse-string");
|
|
14
15
|
const parse_boolean_1 = require("./parse-boolean");
|
|
15
16
|
const validTaskKeys = [
|
|
@@ -22,8 +23,8 @@ const validTaskKeys = [
|
|
|
22
23
|
'description',
|
|
23
24
|
'extend',
|
|
24
25
|
'cmds',
|
|
25
|
-
'watch',
|
|
26
26
|
'continuous',
|
|
27
|
+
'cache',
|
|
27
28
|
];
|
|
28
29
|
const validDockerTaskKeys = ['image', 'mounts', 'ports', 'shell', ...validTaskKeys];
|
|
29
30
|
async function parseBuildFile(fileName, files, input, context) {
|
|
@@ -74,7 +75,7 @@ async function parseBuildFile(fileName, files, input, context) {
|
|
|
74
75
|
mounts: (0, parse_string_array_1.parseStringArray)(ctx, 'mounts', value.mounts),
|
|
75
76
|
src: (0, parse_build_file_task_source_1.parseBuildFileTaskSource)(ctx, value.src, context),
|
|
76
77
|
deps: (0, parse_string_array_1.parseStringArray)(ctx, 'deps', value.deps),
|
|
77
|
-
generates: (
|
|
78
|
+
generates: parseGenerateArray(ctx, 'generates', value.generates),
|
|
78
79
|
description: (0, parse_string_1.parseString)(ctx, 'description', value.description, true)?.trim() ?? null,
|
|
79
80
|
labels: (0, parse_string_map_1.parseStringMap)(ctx, 'labels', value.labels),
|
|
80
81
|
image: value.image || null,
|
|
@@ -91,7 +92,7 @@ async function parseBuildFile(fileName, files, input, context) {
|
|
|
91
92
|
return map;
|
|
92
93
|
}, {}),
|
|
93
94
|
platform: null,
|
|
94
|
-
cache: value.
|
|
95
|
+
cache: value.cache || null,
|
|
95
96
|
};
|
|
96
97
|
if (Object.keys(result.tasks[key].unknownProps).length > 0) {
|
|
97
98
|
context.console.warn(`unknown props ${Object.keys(result.tasks[key].unknownProps)} for ${key} in ${fileName}`);
|
|
@@ -100,4 +101,25 @@ async function parseBuildFile(fileName, files, input, context) {
|
|
|
100
101
|
return result;
|
|
101
102
|
}
|
|
102
103
|
exports.parseBuildFile = parseBuildFile;
|
|
104
|
+
function parseGenerateArray(ctx, valueName, value) {
|
|
105
|
+
if (!value) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
if (value instanceof Array) {
|
|
109
|
+
return value.map((v, i) => {
|
|
110
|
+
if (typeof v === 'string') {
|
|
111
|
+
return v;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
return {
|
|
115
|
+
path: (0, parse_string_1.parseString)(ctx, `generate[${i}].path`, v.path, false),
|
|
116
|
+
resetOnChange: (0, parse_boolean_1.parseBoolean)(ctx, `generate[${i}].resetOnChange`, v.resetOnChange, true) || false,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
throw new Error(`${(0, parse_context_1.parseContextDescription)(ctx)} ${valueName} needs to be a string array`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
103
125
|
//# sourceMappingURL=parse-build-file.js.map
|
|
@@ -15,7 +15,9 @@ exports.parseWorkServiceVolume = parseWorkServiceVolume;
|
|
|
15
15
|
function parseVolume(cwd, name, containerPath) {
|
|
16
16
|
return {
|
|
17
17
|
name,
|
|
18
|
+
resetOnChange: false,
|
|
18
19
|
containerPath: (0, normalize_path_1.normalizePath)(cwd, cwd, containerPath),
|
|
20
|
+
inherited: false,
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
23
|
//# sourceMappingURL=parse-work-service-volume.js.map
|
|
@@ -22,7 +22,10 @@ function planWorkDependency(deps, node) {
|
|
|
22
22
|
if ((0, work_node_1.isContainerWorkNode)(depNode) && (0, work_node_1.isContainerWorkNode)(node)) {
|
|
23
23
|
for (const volume of depNode.volumes) {
|
|
24
24
|
if (!node.volumes.some((v) => v.name === volume.name)) {
|
|
25
|
-
node.volumes.push(
|
|
25
|
+
node.volumes.push({
|
|
26
|
+
...volume,
|
|
27
|
+
inherited: true,
|
|
28
|
+
});
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
}
|