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.
Files changed (182) hide show
  1. package/.devcontainer/Dockerfile +5 -0
  2. package/.devcontainer/devcontainer.json +40 -0
  3. package/Dockerfile +1 -1
  4. package/README.md +13 -86
  5. package/SUMMARY.md +43 -0
  6. package/build.schema.json +56 -2
  7. package/dist/cli.js +97 -0
  8. package/dist/cli.spec.js +5 -0
  9. package/dist/console/console-context-mock.js +11 -0
  10. package/dist/console/get-logger.js +23 -0
  11. package/dist/docker/pull.js +5 -5
  12. package/dist/docker/remove-container.js +21 -0
  13. package/dist/docker/stream.js +19 -21
  14. package/dist/docker/using-container.js +28 -0
  15. package/dist/environment/get-process-env.js +4 -4
  16. package/dist/environment/replace-env-variables.js +2 -3
  17. package/dist/executer/abort.js +13 -0
  18. package/dist/executer/check-readiness.js +25 -0
  19. package/dist/executer/create-scheduler-state.js +32 -0
  20. package/dist/executer/docker-node.js +123 -0
  21. package/dist/executer/docker-service.js +113 -0
  22. package/dist/executer/environment-mock.js +17 -0
  23. package/dist/executer/event-cache.js +165 -0
  24. package/dist/executer/execute-command.js +42 -0
  25. package/dist/executer/execute-docker.js +73 -223
  26. package/dist/executer/execute.spec.js +37 -37
  27. package/dist/executer/execution-steps.js +57 -0
  28. package/dist/executer/get-docker-executor.js +21 -20
  29. package/dist/executer/hierarchy-scheduler.js +94 -0
  30. package/dist/executer/kubernetes-service.js +64 -0
  31. package/dist/executer/label-values.js +65 -0
  32. package/dist/executer/local-node.js +57 -0
  33. package/dist/executer/print-container-options.js +17 -0
  34. package/dist/{logging/log-strategy.js → executer/process-item.js} +1 -1
  35. package/dist/executer/process-listener.js +3 -0
  36. package/dist/executer/process-manager.js +111 -0
  37. package/dist/executer/process-manager.spec.js +91 -0
  38. package/dist/executer/{executor.js → process.js} +1 -1
  39. package/dist/executer/{execute-result.js → readonly-state.js} +1 -1
  40. package/dist/executer/schedule.js +139 -0
  41. package/dist/executer/scheduler/check-for-loop.js +21 -0
  42. package/dist/executer/scheduler/enqueue-next.js +27 -0
  43. package/dist/{testing/test-context.js → executer/scheduler/node-state.js} +1 -1
  44. package/dist/executer/scheduler/scheduler-result.js +3 -0
  45. package/dist/executer/scheduler/scheduler-state.js +3 -0
  46. package/dist/executer/scheduler/service-state.js +3 -0
  47. package/dist/executer/service-dns.js +6 -0
  48. package/dist/executer/set-user-permission.js +16 -0
  49. package/dist/executer/start-node.js +59 -0
  50. package/dist/executer/state-listener.js +3 -0
  51. package/dist/executer/state.js +49 -0
  52. package/dist/executer/states.js +4 -129
  53. package/dist/executer/watch-node.js +57 -0
  54. package/dist/executer/watch-service.js +54 -0
  55. package/dist/executer/work-scope.js +10 -0
  56. package/dist/file/get-file-context-mock.js +1 -0
  57. package/dist/file/get-file-context-mock.spec.js +28 -27
  58. package/dist/file/get-file-context.js +73 -63
  59. package/dist/file/move-files.js +1 -1
  60. package/dist/get-work-context.js +29 -0
  61. package/dist/index.js +11 -10
  62. package/dist/log.js +209 -52
  63. package/dist/logging/grouped-logger.js +31 -19
  64. package/dist/logging/interactive-logger.js +20 -23
  65. package/dist/logging/live-logger.js +7 -17
  66. package/dist/optimizer/calculate-checksum.js +1 -1
  67. package/dist/optimizer/get-cache-directory.js +8 -13
  68. package/dist/optimizer/get-work-node-cache-stats.js +68 -21
  69. package/dist/optimizer/read-work-node-cache.js +2 -2
  70. package/dist/optimizer/work-node-cache-description.js +12 -11
  71. package/dist/optimizer/write-work-node-cache.js +9 -8
  72. package/dist/{executer/execution-context.js → parser/build-file-service.js} +1 -1
  73. package/dist/{optimizer → parser}/cache-method.js +0 -0
  74. package/dist/parser/get-build-file.js +1 -1
  75. package/dist/parser/parse-boolean.js +29 -0
  76. package/dist/parser/parse-boolean.spec.js +48 -0
  77. package/dist/parser/parse-build-file-references.js +2 -2
  78. package/dist/parser/parse-build-file-services.js +58 -0
  79. package/dist/parser/parse-build-file-task-command.js +6 -5
  80. package/dist/parser/parse-build-file-task-source.js +5 -5
  81. package/dist/parser/parse-build-file.js +29 -17
  82. package/dist/parser/parse-context.js +13 -0
  83. package/dist/parser/parse-envs.js +4 -3
  84. package/dist/parser/parse-healthcheck.js +28 -0
  85. package/dist/parser/parse-label-arguments.js +23 -0
  86. package/dist/parser/parse-service-selector.js +39 -0
  87. package/dist/parser/parse-string-array.js +6 -5
  88. package/dist/parser/parse-string-map.js +30 -0
  89. package/dist/parser/parse-string.js +20 -0
  90. package/dist/parser/read-build-file.js +16 -5
  91. package/dist/parser/read-env-file.js +7 -7
  92. package/dist/planner/utils/get-container-mounts.js +24 -0
  93. package/dist/planner/utils/normalize-path.js +17 -0
  94. package/dist/planner/utils/parse-work-node-mount.js +3 -14
  95. package/dist/planner/utils/parse-work-node-mount.spec.js +10 -10
  96. package/dist/planner/utils/parse-work-service-volume.js +21 -0
  97. package/dist/planner/utils/plan-work-command.js +1 -1
  98. package/dist/planner/utils/plan-work-dependency.js +29 -24
  99. package/dist/planner/utils/plan-work-node.js +203 -120
  100. package/dist/planner/utils/plan-work-nodes.js +60 -12
  101. package/dist/planner/utils/plan-work-tree.js +8 -4
  102. package/dist/planner/utils/plan-work-volume.js +25 -0
  103. package/dist/planner/validate.js +56 -8
  104. package/dist/planner/work-context.js +20 -0
  105. package/dist/planner/work-mount.js +3 -0
  106. package/dist/planner/work-node-id.js +4 -4
  107. package/dist/planner/work-node-id.spec.js +11 -8
  108. package/dist/planner/work-node-path.js +0 -1
  109. package/dist/planner/work-node-status.js +121 -18
  110. package/dist/planner/work-node.js +3 -3
  111. package/dist/planner/work-service-id.js +13 -0
  112. package/dist/planner/work-service-volume.js +3 -0
  113. package/dist/planner/work-service.js +6 -0
  114. package/dist/planner/work-services.js +3 -0
  115. package/dist/planner/work-volume.js +3 -0
  116. package/dist/program.js +155 -91
  117. package/dist/program.spec.js +20 -0
  118. package/dist/start-watch-processes.js +28 -0
  119. package/dist/testing/cli.js +73 -0
  120. package/dist/testing/create-build-file.js +1 -1
  121. package/dist/testing/example-test-suite.js +54 -0
  122. package/dist/testing/expect.js +30 -18
  123. package/dist/testing/get-logger.js +23 -0
  124. package/dist/testing/get-node.js +2 -2
  125. package/dist/testing/get-test-context.js +6 -5
  126. package/dist/testing/get-test-suite.js +2 -51
  127. package/dist/testing/integration/cache.spec.js +25 -28
  128. package/dist/testing/integration/cancellation.spec.js +19 -21
  129. package/dist/testing/integration/clean.spec.js +29 -13
  130. package/dist/testing/integration/cmd.spec.js +5 -8
  131. package/dist/testing/integration/concurrency.spec.js +8 -17
  132. package/dist/testing/integration/docker.spec.js +6 -9
  133. package/dist/testing/integration/env.spec.js +27 -34
  134. package/dist/testing/integration/error.spec.js +5 -9
  135. package/dist/testing/integration/extend.spec.js +32 -0
  136. package/dist/testing/integration/glob.spec.js +35 -28
  137. package/dist/testing/integration/include.spec.js +17 -16
  138. package/dist/testing/integration/invalid.spec.js +3 -2
  139. package/dist/testing/integration/invalid_loop.spec.js +13 -0
  140. package/dist/testing/integration/kubernetes.spec.js +15 -0
  141. package/dist/testing/integration/labels.spec.js +47 -0
  142. package/dist/testing/integration/local.spec.js +4 -7
  143. package/dist/testing/integration/monorepo.spec.js +6 -30
  144. package/dist/testing/integration/multi-line.spec.js +4 -4
  145. package/dist/testing/integration/program.spec.js +3 -10
  146. package/dist/testing/integration/reference.spec.js +10 -13
  147. package/dist/testing/integration/services.spec.js +14 -0
  148. package/dist/testing/integration/store.spec.js +42 -35
  149. package/dist/testing/integration/unknown.spec.js +4 -4
  150. package/dist/testing/integration/validate.spec.js +4 -4
  151. package/dist/testing/integration/watch.spec.js +25 -23
  152. package/dist/testing/lazy.js +17 -0
  153. package/dist/testing/start-watch-processes.js +29 -0
  154. package/dist/testing/test-suite-setup.js +3 -0
  155. package/dist/utils/abort-event.js +24 -0
  156. package/dist/utils/abortable-function.js +71 -0
  157. package/dist/utils/debouncer.spec.js +8 -8
  158. package/dist/utils/environment-config.js +13 -0
  159. package/dist/utils/fail-never.js +1 -1
  160. package/dist/utils/sleep.spec.js +3 -3
  161. package/package.json +24 -21
  162. package/dist/console/get-console-context-mock.js +0 -33
  163. package/dist/executer/clean.js +0 -22
  164. package/dist/executer/execute-local.js +0 -58
  165. package/dist/executer/execute.js +0 -95
  166. package/dist/executer/execution-context-event.js +0 -3
  167. package/dist/executer/execution-context-mock.js +0 -3
  168. package/dist/executer/executor-mock.js +0 -39
  169. package/dist/executer/get-environment-mock.js +0 -17
  170. package/dist/executer/get-execution-context-mock.js +0 -19
  171. package/dist/executer/get-local-executor.js +0 -22
  172. package/dist/executer/get-ready-work-nodes.js +0 -15
  173. package/dist/executer/restore.js +0 -22
  174. package/dist/executer/store.js +0 -23
  175. package/dist/logging/get-logger.js +0 -23
  176. package/dist/logging/message-to-console.js +0 -16
  177. package/dist/optimizer/optimize.js +0 -32
  178. package/dist/optimizer/work-node-description.js +0 -12
  179. package/dist/planner/utils/find-build-task.js +0 -18
  180. package/dist/testing/create-work-tree.js +0 -11
  181. package/dist/utils/defer.js +0 -57
  182. package/dist/utils/defer.spec.js +0 -76
@@ -2,13 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("jest-extended");
4
4
  const get_test_suite_1 = require("../get-test-suite");
5
- const validate_1 = require("../../planner/validate");
6
5
  describe('unknown', () => {
7
- const suite = get_test_suite_1.getTestSuite('unknown', ['build.yaml']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('unknown', ['build.yaml']);
7
+ afterAll(() => suite.close());
8
8
  async function validateTask(name, expectedErrors) {
9
- const { buildFile, context } = await suite.setup();
9
+ const { cli } = await suite.setup({ taskName: name });
10
10
  let i = 0;
11
- for await (const message of validate_1.validate(buildFile, context, name)) {
11
+ for await (const message of cli.validate()) {
12
12
  expect(expectedErrors[i++]).toEqual(message.message);
13
13
  }
14
14
  expect(i).toEqual(expectedErrors.length);
@@ -2,17 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  require("jest-extended");
4
4
  const get_test_suite_1 = require("../get-test-suite");
5
- const validate_1 = require("../../planner/validate");
6
5
  describe('validate', () => {
7
- const suite = get_test_suite_1.getTestSuite('validate', ['build.yaml', 'build-loop.yaml']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('validate', ['build.yaml', 'build-loop.yaml']);
8
7
  async function validateTask(name, expectedErrors) {
9
- const { buildFile, context } = await suite.setup();
8
+ const { cli } = await suite.setup({ taskName: name });
10
9
  let i = 0;
11
- for await (const message of validate_1.validate(buildFile, context, name)) {
10
+ for await (const message of cli.validate()) {
12
11
  expect(expectedErrors[i++]).toEqual(message.message);
13
12
  }
14
13
  expect(i).toEqual(expectedErrors.length);
15
14
  }
15
+ afterAll(() => suite.close());
16
16
  it('should validate regular task', async () => {
17
17
  await validateTask('regular_task', []);
18
18
  });
@@ -1,44 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
4
3
  const get_test_suite_1 = require("../get-test-suite");
5
- const execute_1 = require("../../executer/execute");
6
4
  const path_1 = require("path");
7
5
  describe('watch', () => {
8
- const suite = get_test_suite_1.getTestSuite('watch', ['build.yaml', 'src', 'package.json', 'package-lock.json', 'tsconfig.json']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('watch', ['build.yaml', 'src', 'package.json', 'package-lock.json', 'tsconfig.json']);
9
7
  afterAll(() => suite.close());
10
8
  it('should run watch task and cancel', async () => {
11
- const { buildFile, context, executionContext } = await suite.setup();
12
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'api');
13
- executionContext.watch = true;
14
- executionContext.events.on(({ workTree, nodeId, newState }) => {
15
- if (nodeId === workTree.rootNode.id && newState.type === 'running') {
16
- context.cancelDefer.resolve();
9
+ const { cli, environment } = await suite.setup({ taskName: 'api' });
10
+ const apiNode = cli.node('api');
11
+ const exec = cli.execWatch({ watch: true });
12
+ exec.processManager.on((evt) => {
13
+ if (evt.context.id === apiNode.id && evt.type === 'started') {
14
+ environment.abortCtrl.abort();
17
15
  }
18
16
  });
19
- const result = await execute_1.execute(workTree, executionContext);
17
+ const result = await exec.start();
20
18
  expect(result.success).toBeFalsy();
21
- expect(result.nodes[workTree.rootNode.id].state.type).toEqual('aborted');
22
- }, 120000);
19
+ expect(result.state.node[apiNode.id].type).toEqual('canceled');
20
+ });
23
21
  it('should restart task if dependency updates', async () => {
24
- const { buildFile, context, executionContext } = await suite.setup();
25
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'api');
22
+ const { cli, environment } = await suite.setup({ taskName: 'api' });
23
+ const apiNode = cli.node('api');
24
+ const exec = cli.execWatch({ watch: true });
25
+ let appendedFile = false;
26
26
  let restarted = false;
27
- executionContext.watch = true;
28
- executionContext.events.on(({ nodeId, newState }) => {
29
- if (nodeId === workTree.rootNode.id && newState.type === 'running') {
30
- if (restarted) {
31
- context.cancelDefer.resolve();
27
+ exec.processManager.on((evt) => {
28
+ if (evt.type === 'started' && evt.context.id === apiNode.id) {
29
+ if (!appendedFile) {
30
+ appendedFile = true;
31
+ environment.file.appendFile((0, path_1.join)(environment.cwd, 'package.json'), '\n');
32
32
  }
33
33
  else {
34
- context.file.appendFile(path_1.join(buildFile.path, 'package.json'), '\n');
35
34
  restarted = true;
35
+ environment.abortCtrl.abort();
36
36
  }
37
37
  }
38
38
  });
39
- const result = await execute_1.execute(workTree, executionContext);
39
+ const result = await exec.start();
40
+ expect(appendedFile).toBeTruthy();
41
+ expect(restarted).toBeTruthy();
40
42
  expect(result.success).toBeFalsy();
41
- expect(result.nodes[workTree.rootNode.id].state.type).toEqual('aborted');
42
- }, 120000);
43
+ expect(result.state.node[apiNode.id].type).toEqual('canceled');
44
+ });
43
45
  });
44
46
  //# sourceMappingURL=watch.spec.js.map
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Lazy = void 0;
4
+ class Lazy {
5
+ constructor(factory) {
6
+ this.factory = factory;
7
+ this.current = null;
8
+ }
9
+ resolve() {
10
+ if (!this.current) {
11
+ this.current = { result: this.factory() };
12
+ }
13
+ return this.current.result;
14
+ }
15
+ }
16
+ exports.Lazy = Lazy;
17
+ //# sourceMappingURL=lazy.js.map
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startWatchProcesses = void 0;
4
+ const plan_work_nodes_1 = require("../planner/utils/plan-work-nodes");
5
+ const watch_node_1 = require("../executer/watch-node");
6
+ const work_service_1 = require("../planner/work-service");
7
+ const watch_service_1 = require("../executer/watch-service");
8
+ const work_node_status_1 = require("../planner/work-node-status");
9
+ function startWatchProcesses(state, processManager, environment) {
10
+ for (const node of (0, plan_work_nodes_1.iterateWorkNodes)(state.current.node)) {
11
+ if (node.node.src.length > 0) {
12
+ if (node.node.continuous) {
13
+ environment.status.task(node.node).write('debug', 'do not start files watches for continuous task');
14
+ continue;
15
+ }
16
+ processManager.background((0, work_node_status_1.logContext)('task', node.node), (0, watch_node_1.watchNode)(node.node, state, environment));
17
+ }
18
+ }
19
+ for (const service of (0, plan_work_nodes_1.iterateWorkServices)(state.current.service)) {
20
+ if (!(0, work_service_1.isContainerWorkService)(service.service)) {
21
+ continue;
22
+ }
23
+ if (service.service.mounts.length > 0) {
24
+ processManager.background((0, work_node_status_1.logContext)('service', service.service), (0, watch_service_1.watchService)(service.service, state, environment));
25
+ }
26
+ }
27
+ }
28
+ exports.startWatchProcesses = startWatchProcesses;
29
+ //# sourceMappingURL=start-watch-processes.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=test-suite-setup.js.map
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.waitOnAbort = exports.listenOnAbort = void 0;
4
+ function listenOnAbort(abort, callback) {
5
+ if (abort.aborted) {
6
+ callback();
7
+ return;
8
+ }
9
+ const listener = abort;
10
+ listener.addEventListener('abort', () => {
11
+ callback();
12
+ }, { once: true });
13
+ }
14
+ exports.listenOnAbort = listenOnAbort;
15
+ function waitOnAbort(abort) {
16
+ if (abort.aborted) {
17
+ return Promise.resolve();
18
+ }
19
+ return new Promise((resolve) => {
20
+ listenOnAbort(abort, resolve);
21
+ });
22
+ }
23
+ exports.waitOnAbort = waitOnAbort;
24
+ //# sourceMappingURL=abort-event.js.map
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.abortableFunction = void 0;
4
+ const abort_event_1 = require("./abort-event");
5
+ const log_1 = require("../log");
6
+ function abortableFunction(console, abortSignal, fn) {
7
+ return new Promise((resolve, reject) => {
8
+ const cleanupFunctions = [];
9
+ let aborted = false;
10
+ function doAbort(err) {
11
+ aborted = true;
12
+ Promise.allSettled(cleanupFunctions.map((fn) => fn())).then((results) => {
13
+ for (const result of results) {
14
+ if (result.status === 'rejected') {
15
+ console.error((0, log_1.getErrorMessage)(result.reason));
16
+ }
17
+ }
18
+ reject(err);
19
+ });
20
+ }
21
+ if (abortSignal instanceof Array) {
22
+ for (const signal of abortSignal) {
23
+ (0, abort_event_1.listenOnAbort)(signal, () => {
24
+ doAbort(new Error('canceled'));
25
+ });
26
+ }
27
+ }
28
+ else {
29
+ (0, abort_event_1.listenOnAbort)(abortSignal, () => {
30
+ doAbort(new Error('canceled'));
31
+ });
32
+ }
33
+ const isAborted = () => {
34
+ if (abortSignal instanceof Array) {
35
+ for (const signal of abortSignal) {
36
+ if (signal.aborted) {
37
+ return true;
38
+ }
39
+ }
40
+ return false;
41
+ }
42
+ else {
43
+ return abortSignal.aborted;
44
+ }
45
+ };
46
+ fn({
47
+ addAbortFunction(cleanupFn) {
48
+ if (aborted) {
49
+ cleanupFn();
50
+ }
51
+ else {
52
+ cleanupFunctions.push(cleanupFn);
53
+ }
54
+ },
55
+ isAborted,
56
+ checkForAbort() {
57
+ if (isAborted()) {
58
+ throw new Error('canceled');
59
+ }
60
+ },
61
+ })
62
+ .then((result) => {
63
+ resolve(result);
64
+ })
65
+ .catch((err) => {
66
+ doAbort(err);
67
+ });
68
+ });
69
+ }
70
+ exports.abortableFunction = abortableFunction;
71
+ //# sourceMappingURL=abortable-function.js.map
@@ -8,7 +8,7 @@ describe('utils/debouncer', () => {
8
8
  new debouncer_1.Debouncer(() => {
9
9
  called = true;
10
10
  }, 10);
11
- await sleep_1.sleep(20);
11
+ await (0, sleep_1.sleep)(20);
12
12
  expect(called).toBeFalsy();
13
13
  });
14
14
  it('should trigger after start', async () => {
@@ -17,7 +17,7 @@ describe('utils/debouncer', () => {
17
17
  called = true;
18
18
  }, 10);
19
19
  debouncer.start();
20
- await sleep_1.sleep(20);
20
+ await (0, sleep_1.sleep)(20);
21
21
  expect(called).toBeTruthy();
22
22
  });
23
23
  it('should delay trigger after bounce', async () => {
@@ -26,11 +26,11 @@ describe('utils/debouncer', () => {
26
26
  called = true;
27
27
  }, 20);
28
28
  debouncer.start();
29
- await sleep_1.sleep(10);
29
+ await (0, sleep_1.sleep)(10);
30
30
  debouncer.bounce();
31
- await sleep_1.sleep(15);
31
+ await (0, sleep_1.sleep)(15);
32
32
  expect(called).toBeFalsy();
33
- await sleep_1.sleep(5);
33
+ await (0, sleep_1.sleep)(5);
34
34
  expect(called).toBeTruthy();
35
35
  });
36
36
  it('should cancel trigger after clear', async () => {
@@ -39,9 +39,9 @@ describe('utils/debouncer', () => {
39
39
  called = true;
40
40
  }, 20);
41
41
  debouncer.start();
42
- await sleep_1.sleep(10);
42
+ await (0, sleep_1.sleep)(10);
43
43
  debouncer.clear();
44
- await sleep_1.sleep(15);
44
+ await (0, sleep_1.sleep)(15);
45
45
  expect(called).toBeFalsy();
46
46
  });
47
47
  it('should trigger on flush', async () => {
@@ -50,7 +50,7 @@ describe('utils/debouncer', () => {
50
50
  called = true;
51
51
  }, 20);
52
52
  debouncer.start();
53
- await sleep_1.sleep(5);
53
+ await (0, sleep_1.sleep)(5);
54
54
  debouncer.flush();
55
55
  expect(called).toBeTruthy();
56
56
  });
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEnvironmentConfig = void 0;
4
+ function getEnvironmentConfig(name, defaultValue) {
5
+ if (name in process.env) {
6
+ return parseInt(`${process.env[name]}`, 0) ?? defaultValue;
7
+ }
8
+ else {
9
+ return defaultValue;
10
+ }
11
+ }
12
+ exports.getEnvironmentConfig = getEnvironmentConfig;
13
+ //# sourceMappingURL=environment-config.js.map
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.failNever = void 0;
4
- function failNever(message) {
4
+ function failNever(value, message) {
5
5
  throw new Error(message);
6
6
  }
7
7
  exports.failNever = failNever;
@@ -4,18 +4,18 @@ const sleep_1 = require("./sleep");
4
4
  describe('utils/sleep', () => {
5
5
  it('should resolve not before timeout', () => {
6
6
  let called = false;
7
- sleep_1.sleep(10).then(() => {
7
+ (0, sleep_1.sleep)(10).then(() => {
8
8
  called = true;
9
9
  });
10
10
  expect(called).toBeFalsy();
11
11
  });
12
12
  it('should resolve after timeout', async () => {
13
13
  let called = false;
14
- sleep_1.sleep(10).then(() => {
14
+ (0, sleep_1.sleep)(10).then(() => {
15
15
  called = true;
16
16
  });
17
17
  expect(called).toBeFalsy();
18
- await sleep_1.sleep(10);
18
+ await (0, sleep_1.sleep)(10);
19
19
  expect(called).toBeTruthy();
20
20
  });
21
21
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hammerkit",
3
3
  "description": "build stuff and things",
4
- "version": "1.4.0-beta.6",
4
+ "version": "1.5.0-alpha.0",
5
5
  "bin": "dist/index.js",
6
6
  "bugs": {
7
7
  "url": "https://github.com/no0dles/hammerkit"
@@ -18,30 +18,33 @@
18
18
  "scripts": {
19
19
  "prepack": "tsc -b tsconfig.json",
20
20
  "build": "tsc -b tsconfig.json",
21
- "test": "jest"
21
+ "test": "jest",
22
+ "format": "prettier -w src/** && eslint . --fix --ext .ts"
22
23
  },
23
24
  "dependencies": {
24
- "commander": "^7.2.0",
25
- "dockerode": "^3.2.1",
26
- "minimatch": "^3.0.4",
25
+ "chokidar": "^3.5.3",
26
+ "tar": "^6.1.11",
27
27
  "colors": "^1.4.0",
28
- "chokidar": "^3.5.2",
29
- "yaml": "^1.10.2"
28
+ "commander": "^9.4.1",
29
+ "dockerode": "^3.3.4",
30
+ "minimatch": "^5.1.0",
31
+ "yaml": "^2.1.3"
30
32
  },
31
33
  "devDependencies": {
32
- "@types/dockerode": "^3.2.3",
33
- "@types/jest": "^26.0.22",
34
- "@types/minimatch": "^3.0.4",
35
- "@types/node": "^14.14.37",
36
- "@typescript-eslint/eslint-plugin": "^4.20.0",
37
- "@typescript-eslint/parser": "^4.20.0",
38
- "eslint": "^7.23.0",
39
- "jest": "^26.6.3",
40
- "jest-extended": "^0.11.5",
41
- "prettier": "^2.2.1",
42
- "ts-jest": "^26.5.4",
43
- "ts-node": "^9.1.1",
44
- "typescript": "^4.2.3",
45
- "pkg": "^5.2.1"
34
+ "@types/dockerode": "^3.3.11",
35
+ "@types/jest": "^29.1.2",
36
+ "@types/minimatch": "^5.1.2",
37
+ "@types/node": "^16.10.2",
38
+ "@types/tar": "^6.1.3",
39
+ "@typescript-eslint/eslint-plugin": "^5.40.0",
40
+ "@typescript-eslint/parser": "^5.40.0",
41
+ "eslint": "^8.25.0",
42
+ "jest": "^29.2.0",
43
+ "jest-extended": "^3.1.0",
44
+ "pkg": "^5.8.0",
45
+ "prettier": "^2.7.1",
46
+ "ts-jest": "^29.0.3",
47
+ "ts-node": "^10.9.1",
48
+ "typescript": "^4.8.4"
46
49
  }
47
50
  }
@@ -1,33 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getConsoleContextMock = void 0;
4
- function getConsoleContextMock() {
5
- const expectedLogs = {};
6
- function complete(message) {
7
- const obj = expectedLogs[message];
8
- if (obj) {
9
- obj.fulfilled = true;
10
- delete expectedLogs[message];
11
- }
12
- }
13
- return {
14
- warn(message) {
15
- complete(message);
16
- },
17
- info(message) {
18
- complete(message);
19
- },
20
- error(message) {
21
- complete(message);
22
- },
23
- debug(message) {
24
- complete(message);
25
- },
26
- expectLog(message) {
27
- expectedLogs[message] = { fulfilled: false };
28
- return expectedLogs[message];
29
- },
30
- };
31
- }
32
- exports.getConsoleContextMock = getConsoleContextMock;
33
- //# sourceMappingURL=get-console-context-mock.js.map
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.clean = void 0;
4
- const plan_work_nodes_1 = require("../planner/utils/plan-work-nodes");
5
- const get_cache_directory_1 = require("../optimizer/get-cache-directory");
6
- async function clean(workNodes, context) {
7
- for (const node of plan_work_nodes_1.iterateWorkNodes(workNodes)) {
8
- for (const generate of node.generates) {
9
- if (await context.file.exists(generate)) {
10
- node.status.console.write('internal', 'info', `remove generate ${generate}`);
11
- await context.file.remove(generate);
12
- }
13
- }
14
- const cachePath = get_cache_directory_1.getCacheDirectory(node.id);
15
- if (await context.file.exists(cachePath)) {
16
- node.status.console.write('internal', 'info', `remove cache ${cachePath}`);
17
- await context.file.remove(cachePath);
18
- }
19
- }
20
- }
21
- exports.clean = clean;
22
- //# sourceMappingURL=clean.js.map
@@ -1,58 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.executeLocal = void 0;
4
- const child_process_1 = require("child_process");
5
- const log_1 = require("../log");
6
- const template_value_1 = require("../planner/utils/template-value");
7
- const os_1 = require("os");
8
- const get_process_env_1 = require("../environment/get-process-env");
9
- async function executeLocal(node, arg, cancelDefer) {
10
- node.status.console.write('internal', 'info', `execute ${node.name} locally`);
11
- const envs = get_process_env_1.getProcessEnvs(node.envs, arg.environment);
12
- for (const cmd of node.cmds) {
13
- if (cancelDefer.isResolved) {
14
- return;
15
- }
16
- const command = template_value_1.templateValue(cmd.cmd, envs);
17
- await new Promise((resolve, reject) => {
18
- node.status.console.write('internal', 'info', `execute cmd ${command} locally`);
19
- const ps = child_process_1.exec(command, {
20
- env: envs,
21
- cwd: cmd.path,
22
- shell: os_1.platform() === 'win32' ? 'powershell.exe' : undefined,
23
- });
24
- ps.stdout?.on('data', (data) => {
25
- for (const log of log_1.getLogs(data)) {
26
- node.status.console.write('process', 'info', log);
27
- }
28
- });
29
- ps.stderr?.on('data', (data) => {
30
- for (const log of log_1.getLogs(data)) {
31
- node.status.console.write('process', 'info', log);
32
- }
33
- });
34
- ps.on('error', (err) => {
35
- node.status.console.write('process', 'error', err.message);
36
- });
37
- ps.on('close', (code) => {
38
- if (cancelDefer.isResolved) {
39
- reject(new Error('canceled'));
40
- return;
41
- }
42
- if (code !== 0 && code !== null) {
43
- const message = `failed with code ${code}`;
44
- node.status.console.write('process', 'error', message);
45
- reject(new Error(message));
46
- }
47
- else {
48
- resolve();
49
- }
50
- });
51
- cancelDefer.promise.then(() => {
52
- ps.kill();
53
- });
54
- });
55
- }
56
- }
57
- exports.executeLocal = executeLocal;
58
- //# sourceMappingURL=execute-local.js.map
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.execute = void 0;
4
- const optimize_1 = require("../optimizer/optimize");
5
- const get_ready_work_nodes_1 = require("./get-ready-work-nodes");
6
- const write_work_node_cache_1 = require("../optimizer/write-work-node-cache");
7
- const path_1 = require("path");
8
- const plan_work_nodes_1 = require("../planner/utils/plan-work-nodes");
9
- const states_1 = require("./states");
10
- const debouncer_1 = require("../utils/debouncer");
11
- const get_work_node_cache_stats_1 = require("../optimizer/get-work-node-cache-stats");
12
- async function execute(workTree, context) {
13
- context.environment.cancelDefer.promise.then(() => {
14
- states_1.cancelNodes(workTree, context);
15
- });
16
- await optimize_1.optimize(workTree, context);
17
- if (context.watch) {
18
- await watchNodes(workTree, context);
19
- }
20
- runPendingNodes(workTree, context);
21
- await workTree.rootNode.status.defer.promise;
22
- for (const node of plan_work_nodes_1.iterateWorkNodes(workTree.nodes)) {
23
- await node.status.defer.promise;
24
- }
25
- const result = {
26
- success: true,
27
- nodes: {},
28
- };
29
- for (const node of plan_work_nodes_1.iterateWorkNodes(workTree.nodes)) {
30
- result.nodes[node.id] = node.status;
31
- if (node.status.state.type === 'failed' || node.status.state.type === 'aborted') {
32
- result.success = false;
33
- }
34
- }
35
- return result;
36
- }
37
- exports.execute = execute;
38
- async function watchNodes(workTree, context) {
39
- for (const node of plan_work_nodes_1.iterateWorkNodes(workTree.nodes)) {
40
- if (node.src.length === 0) {
41
- continue;
42
- }
43
- let currentState = await get_work_node_cache_stats_1.getWorkNodeCacheStats(node, context.environment);
44
- const debouncer = new debouncer_1.Debouncer(async () => {
45
- if (context.environment.cancelDefer.isResolved) {
46
- return;
47
- }
48
- const newStats = await get_work_node_cache_stats_1.getWorkNodeCacheStats(node, context.environment);
49
- const hasChanged = await get_work_node_cache_stats_1.hasStatsChanged(node, currentState, newStats, context.cacheMethod);
50
- if (!hasChanged) {
51
- return;
52
- }
53
- currentState = newStats;
54
- states_1.resetNode(workTree, node.id, context);
55
- runPendingNodes(workTree, context);
56
- }, 100);
57
- for (const src of node.src) {
58
- const watcher = context.environment.file.watch(src.absolutePath, async (fileName) => {
59
- const absoluteFileName = path_1.join(src.absolutePath, fileName);
60
- if (src.matcher(absoluteFileName, node.cwd)) {
61
- node.status.console.write('internal', 'debug', `source ${absoluteFileName} change for watched task ${node.name}`);
62
- debouncer.bounce();
63
- }
64
- });
65
- context.environment.cancelDefer.promise.then(() => {
66
- watcher.close();
67
- });
68
- }
69
- }
70
- }
71
- function runPendingNodes(workTree, arg) {
72
- const pendingNodes = get_ready_work_nodes_1.getReadyWorkNodes(workTree);
73
- for (const pendingNode of pendingNodes) {
74
- if (arg.workers !== 0 && Object.keys(arg.runningNodes).length === arg.workers) {
75
- continue;
76
- }
77
- if (arg.runningNodes[pendingNode.id]) {
78
- continue;
79
- }
80
- continueExecution(workTree, pendingNode, arg);
81
- }
82
- }
83
- async function continueExecution(workTree, node, context) {
84
- const cancelDefer = states_1.runNode(workTree, node.id, context);
85
- try {
86
- await context.executor.exec(node, context, cancelDefer);
87
- await write_work_node_cache_1.writeWorkNodeCache(node, context.environment);
88
- states_1.completeNode(workTree, node.id, context, true);
89
- }
90
- catch (e) {
91
- states_1.failNode(workTree, node.id, context, e);
92
- }
93
- runPendingNodes(workTree, context);
94
- }
95
- //# sourceMappingURL=execute.js.map
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=execution-context-event.js.map
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=execution-context-mock.js.map