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
@@ -1,54 +1,47 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const expect_1 = require("../expect");
4
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
5
4
  const get_test_suite_1 = require("../get-test-suite");
6
- const execute_1 = require("../../executer/execute");
7
5
  describe('env', () => {
8
- const suite = get_test_suite_1.getTestSuite('env', ['build.yaml', '.env']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('env', ['build.yaml', '.env']);
9
7
  afterAll(() => suite.close());
10
8
  it('should use env from build file', async () => {
11
- const { buildFile, executionContext } = await suite.setup();
12
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
13
- const result = await execute_1.execute(workTree, executionContext);
14
- await expect_1.expectSuccessfulResult(result);
15
- await expect_1.expectLog(result, `example`, '16.6.0');
9
+ const { cli, environment } = await suite.setup({ taskName: 'example' });
10
+ const result = await cli.exec();
11
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
12
+ await (0, expect_1.expectLog)(result, environment, `example`, '16.6.0');
16
13
  });
17
14
  it('should pass env to docker', async () => {
18
- const { buildFile, executionContext } = await suite.setup();
19
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example_docker');
20
- const result = await execute_1.execute(workTree, executionContext);
21
- await expect_1.expectSuccessfulResult(result);
22
- await expect_1.expectLog(result, `example_docker`, '16.6.0');
15
+ const { cli, environment } = await suite.setup({ taskName: 'example_docker' });
16
+ const result = await cli.exec();
17
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
18
+ await (0, expect_1.expectLog)(result, environment, `example_docker`, '16.6.0');
23
19
  });
24
20
  it('should use env from task', async () => {
25
- const { buildFile, executionContext } = await suite.setup();
26
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example_override');
27
- const result = await execute_1.execute(workTree, executionContext);
28
- await expect_1.expectSuccessfulResult(result);
29
- await expect_1.expectLog(result, `example_override`, '15.0.0');
21
+ const { cli, environment } = await suite.setup({ taskName: 'example_override' });
22
+ const result = await cli.exec();
23
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
24
+ await (0, expect_1.expectLog)(result, environment, `example_override`, '15.0.0');
30
25
  });
31
26
  it('should use env from .env', async () => {
32
- const { buildFile, executionContext } = await suite.setup();
33
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example_with_dotenv');
34
- const result = await execute_1.execute(workTree, executionContext);
35
- await expect_1.expectSuccessfulResult(result);
36
- await expect_1.expectLog(result, `example_with_dotenv`, '123456');
27
+ const { cli, environment } = await suite.setup({ taskName: 'example_with_dotenv' });
28
+ const result = await cli.exec();
29
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
30
+ await (0, expect_1.expectLog)(result, environment, `example_with_dotenv`, '123456');
37
31
  });
38
32
  it('should use process env', async () => {
39
- const { buildFile, executionContext } = await suite.setup();
40
- executionContext.environment.processEnvs['VERSION'] = '1.0.0';
41
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example_with_shell_env');
42
- const result = await execute_1.execute(workTree, executionContext);
43
- await expect_1.expectSuccessfulResult(result);
44
- await expect_1.expectLog(result, `example_with_shell_env`, '1.0.0');
33
+ const { cli, environment } = await suite.setup({
34
+ taskName: 'example_with_shell_env',
35
+ envs: {
36
+ VERSION: '1.0.0',
37
+ },
38
+ });
39
+ const result = await cli.exec();
40
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
41
+ await (0, expect_1.expectLog)(result, environment, `example_with_shell_env`, '1.0.0');
45
42
  });
46
43
  it('should throw if process env is missing', async () => {
47
- const { buildFile, executionContext } = await suite.setup();
48
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example_with_shell_env');
49
- const result = await execute_1.execute(workTree, executionContext);
50
- expect(result.success).toBeFalsy();
51
- //expect(result.nodes[`${buildFile.path}:example_with_shell_env`].type).toEqual('failed')
44
+ await expect(suite.setup({ taskName: 'example_with_shell_env' })).rejects.toThrow('missing env $VERSION');
52
45
  });
53
46
  });
54
47
  //# sourceMappingURL=env.spec.js.map
@@ -1,21 +1,17 @@
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
  describe('error', () => {
7
- const suite = get_test_suite_1.getTestSuite('error', ['build.yaml']);
5
+ const suite = (0, get_test_suite_1.getTestSuite)('error', ['build.yaml']);
8
6
  afterAll(() => suite.close());
9
7
  it('should return error when local task failed', async () => {
10
- const { buildFile, executionContext } = await suite.setup();
11
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'local_error');
12
- const result = await execute_1.execute(workTree, executionContext);
8
+ const { cli } = await suite.setup({ taskName: 'local_error' });
9
+ const result = await cli.exec();
13
10
  expect(result.success).toBeFalsy();
14
11
  });
15
12
  it('should return error when docker task failed', async () => {
16
- const { buildFile, executionContext } = await suite.setup();
17
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'docker_error');
18
- const result = await execute_1.execute(workTree, executionContext);
13
+ const { cli } = await suite.setup({ taskName: 'docker_error' });
14
+ const result = await cli.exec();
19
15
  expect(result.success).toBeFalsy();
20
16
  });
21
17
  });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const get_test_suite_1 = require("../get-test-suite");
4
+ describe('extend', () => {
5
+ const suite = (0, get_test_suite_1.getTestSuite)('extend', ['build.yaml']);
6
+ afterAll(() => suite.close());
7
+ it('should merge env variables', async () => {
8
+ const { cli } = await suite.setup({ taskName: 'extend_env' });
9
+ const node = await cli.node('extend_env');
10
+ expect(node.envs).toContainEntries([
11
+ ['NAME', 'base'],
12
+ ['KEEP', 'value'],
13
+ ]);
14
+ });
15
+ it('should extend and override', async () => {
16
+ const { cli } = await suite.setup({ taskName: 'extend_container_task' });
17
+ const node = await cli.node('extend_container_task');
18
+ expect(node.envs).toEqual({
19
+ NAME: 'override',
20
+ });
21
+ expect(node.type).toBe('container');
22
+ if (node.type === 'container') {
23
+ expect(node.image).toBe('alpine');
24
+ }
25
+ });
26
+ it('should merge deps', async () => {
27
+ const { cli } = await suite.setup({ taskName: 'extend_dep' });
28
+ const node = await cli.node('extend_dep');
29
+ expect(node.deps.map((d) => d.name)).toIncludeSameMembers(['base_env', 'extend_env']);
30
+ });
31
+ });
32
+ //# sourceMappingURL=extend.spec.js.map
@@ -1,41 +1,48 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const path_1 = require("path");
4
- const fs_1 = require("fs");
5
- const write_work_node_cache_1 = require("../../optimizer/write-work-node-cache");
6
- const optimize_1 = require("../../optimizer/optimize");
7
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
8
3
  const get_test_suite_1 = require("../get-test-suite");
4
+ const expect_1 = require("../expect");
9
5
  describe('glob', () => {
10
- const suite = get_test_suite_1.getTestSuite('glob', ['build.yaml', 'test.md', 'test.txt']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('glob', ['build.yaml', 'test.md', 'test.txt']);
11
7
  afterAll(() => suite.close());
8
+ async function testCache(expectInvalidate, action) {
9
+ const { cli, environment } = await suite.setup({ taskName: 'example' });
10
+ const result1 = await cli.exec();
11
+ await (0, expect_1.expectSuccessfulResult)(result1, environment);
12
+ const node = cli.node('example');
13
+ const nodeState1 = result1.state.node[node.id];
14
+ expect(nodeState1.type).toEqual('completed');
15
+ if (nodeState1.type === 'completed') {
16
+ expect(nodeState1.duration).toBeGreaterThanOrEqual(100);
17
+ }
18
+ if (action) {
19
+ await action(environment);
20
+ }
21
+ const result2 = await cli.exec();
22
+ await (0, expect_1.expectSuccessfulResult)(result2, environment);
23
+ const nodeState2 = result2.state.node[node.id];
24
+ expect(nodeState2.type).toEqual('completed');
25
+ if (nodeState2.type === 'completed') {
26
+ if (expectInvalidate) {
27
+ expect(nodeState2.cached).toBeFalsy();
28
+ }
29
+ else {
30
+ expect(nodeState2.cached).toBeTruthy();
31
+ }
32
+ }
33
+ }
12
34
  it('should remove task after written cache', async () => {
13
- const { buildFile, context, executionContext } = await suite.setup();
14
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
15
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('pending');
16
- await optimize_1.optimize(workTree, executionContext);
17
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('pending');
18
- await write_work_node_cache_1.writeWorkNodeCache(workTree.rootNode, context);
19
- await optimize_1.optimize(workTree, executionContext);
20
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('completed');
35
+ await testCache(false);
21
36
  });
22
37
  it('should keep being cached after ignored file changed', async () => {
23
- const { buildFile, context, executionContext } = await suite.setup();
24
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
25
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('pending');
26
- await write_work_node_cache_1.writeWorkNodeCache(workTree.rootNode, context);
27
- fs_1.appendFileSync(path_1.join(buildFile.path, 'test.txt'), '\n');
28
- await optimize_1.optimize(workTree, executionContext);
29
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('completed');
38
+ await testCache(false, async (env) => {
39
+ await env.file.appendFile('test.txt', '\n');
40
+ });
30
41
  });
31
42
  it('should invalid cache after file has changed', async () => {
32
- const { buildFile, context, executionContext } = await suite.setup();
33
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
34
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('pending');
35
- await write_work_node_cache_1.writeWorkNodeCache(workTree.rootNode, context);
36
- fs_1.appendFileSync(path_1.join(buildFile.path, 'test.md'), '\n');
37
- await optimize_1.optimize(workTree, executionContext);
38
- expect(workTree.nodes[workTree.rootNode.id].status.state.type).toEqual('pending');
43
+ await testCache(true, async (env) => {
44
+ await env.file.appendFile('test.md', '\n');
45
+ });
39
46
  });
40
47
  });
41
48
  //# sourceMappingURL=glob.spec.js.map
@@ -1,30 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const expect_1 = require("../expect");
4
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
5
4
  const get_test_suite_1 = require("../get-test-suite");
6
- const execute_1 = require("../../executer/execute");
7
5
  describe('include', () => {
8
- const suite = get_test_suite_1.getTestSuite('include', ['build.yaml', 'foo', 'foobar.txt']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('include', ['build.yaml', 'foo', 'foobar.txt']);
9
7
  afterAll(() => suite.close());
10
8
  it('should run included task', async () => {
11
- const { buildFile, executionContext } = await suite.setup();
12
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
13
- const result = await execute_1.execute(workTree, executionContext);
14
- await expect_1.expectSuccessfulResult(result);
15
- await expect_1.expectLog(result, `foo:bar`, 'foobar');
9
+ const { cli, environment } = await suite.setup({ taskName: 'example' });
10
+ const result = await cli.exec();
11
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
12
+ await (0, expect_1.expectLog)(result, environment, `foo:bar`, 'foobar');
16
13
  });
17
14
  it('should get name:example', async () => {
18
- const { buildFile, executionContext } = await suite.setup();
19
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'name:example');
20
- const result = await execute_1.execute(workTree, executionContext);
21
- await expect_1.expectSuccessfulResult(result);
15
+ const { cli, environment } = await suite.setup({ taskName: 'name:example' });
16
+ const result = await cli.exec();
17
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
22
18
  });
23
19
  it('should get included task', async () => {
24
- const { buildFile } = await suite.setup();
25
- const tree = plan_work_tree_1.planWorkTree(buildFile, 'foo:bar');
26
- expect(tree.rootNode.name).toEqual('foo:bar');
27
- expect(tree.rootNode.cwd).toEqual(buildFile.path);
20
+ const { cli } = await suite.setup({ taskName: 'foo:bar' });
21
+ expect(cli.ls().map((n) => n.item.name)).toEqual(['foo:bar']);
22
+ const item = cli.ls()[0];
23
+ if (item.type === 'task') {
24
+ expect(item.item.cwd).toBe(suite.path);
25
+ }
26
+ else {
27
+ expect(item.type).toBe('task');
28
+ }
28
29
  });
29
30
  });
30
31
  //# sourceMappingURL=include.spec.js.map
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const get_test_suite_1 = require("../get-test-suite");
4
+ const work_scope_1 = require("../../executer/work-scope");
4
5
  describe('invalid', () => {
5
- const suite = get_test_suite_1.getTestSuite('invalid', ['build.yaml']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('invalid', ['build.yaml']);
6
7
  afterAll(() => suite.close());
7
8
  it('should throw on invalid yaml', async () => {
8
9
  try {
9
- await suite.setup();
10
+ await suite.setup((0, work_scope_1.emptyWorkLabelScope)());
10
11
  expect.fail('should not be called');
11
12
  }
12
13
  catch (e) {
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const get_test_suite_1 = require("../get-test-suite");
4
+ describe('invalid', () => {
5
+ const suite = (0, get_test_suite_1.getTestSuite)('invalid_loop', ['build.yaml']);
6
+ afterAll(() => suite.close());
7
+ it('should detect loop in execution', async () => {
8
+ const { cli } = await suite.setup({ taskName: 'foo' });
9
+ const result = await cli.exec();
10
+ expect(result.success).toBeFalsy();
11
+ });
12
+ });
13
+ //# sourceMappingURL=invalid_loop.spec.js.map
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const get_test_suite_1 = require("../get-test-suite");
4
+ const expect_1 = require("../expect");
5
+ describe('kubernetes', () => {
6
+ const suite = (0, get_test_suite_1.getTestSuite)('kubernetes', ['index.js', 'package.json', 'package-lock.json', 'build.yaml']);
7
+ afterAll(() => suite.close());
8
+ // CI setup missing
9
+ xit('should forward deployment', async () => {
10
+ const { cli, environment } = await suite.setup({ taskName: 'api' });
11
+ const result = await cli.exec();
12
+ (0, expect_1.expectSuccessfulResult)(result, environment);
13
+ });
14
+ });
15
+ //# sourceMappingURL=kubernetes.spec.js.map
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const get_test_suite_1 = require("../get-test-suite");
4
+ describe('local', () => {
5
+ const suite = (0, get_test_suite_1.getTestSuite)('labels', ['build.yaml']);
6
+ afterAll(() => suite.close());
7
+ it('should run only run labeled task with app=bar and dependencies', async () => {
8
+ const { cli } = await suite.setup({
9
+ filterLabels: { app: ['bar'] },
10
+ excludeLabels: {},
11
+ });
12
+ expectNodes(cli.ls(), ['bar', 'base']);
13
+ });
14
+ it('should not run labeled task with app=foo and dependencies', async () => {
15
+ const { cli } = await suite.setup({
16
+ filterLabels: { app: ['foo'] },
17
+ excludeLabels: {},
18
+ });
19
+ expectNodes(cli.ls(), ['foo', 'base']);
20
+ });
21
+ it('should exclude foo labeled nodes', async () => {
22
+ const { cli } = await suite.setup({
23
+ filterLabels: {},
24
+ excludeLabels: { app: ['foo'] },
25
+ });
26
+ expectNodes(cli.ls(), ['bar', 'base']);
27
+ });
28
+ it('should exclude base labeled nodes', async () => {
29
+ const { cli } = await suite.setup({
30
+ filterLabels: {},
31
+ excludeLabels: { app: ['base'] },
32
+ });
33
+ expectNodes(cli.ls(), []);
34
+ });
35
+ it('should run nodes with label app=bar or app=foo', async () => {
36
+ const { cli } = await suite.setup({
37
+ filterLabels: { app: ['foo', 'bar'] },
38
+ excludeLabels: {},
39
+ });
40
+ expectNodes(cli.ls(), ['foo', 'bar', 'base']);
41
+ });
42
+ });
43
+ function expectNodes(nodes, expectedNodes) {
44
+ const nodeNames = Object.values(nodes).map((n) => n.item.name);
45
+ expect(nodeNames).toIncludeSameMembers(expectedNodes);
46
+ }
47
+ //# sourceMappingURL=labels.spec.js.map
@@ -1,17 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const expect_1 = require("../expect");
4
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
5
4
  const get_test_suite_1 = require("../get-test-suite");
6
- const execute_1 = require("../../executer/execute");
7
5
  describe('local', () => {
8
- const suite = get_test_suite_1.getTestSuite('local', ['build.yaml']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('local', ['build.yaml']);
9
7
  afterAll(() => suite.close());
10
8
  it('should run local task', async () => {
11
- const { buildFile, executionContext } = await suite.setup();
12
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
13
- const result = await execute_1.execute(workTree, executionContext);
14
- await expect_1.expectSuccessfulResult(result);
9
+ const { cli, environment } = await suite.setup({ taskName: 'example' });
10
+ const result = await cli.exec();
11
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
15
12
  });
16
13
  });
17
14
  //# sourceMappingURL=local.spec.js.map
@@ -1,39 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const fs_1 = require("fs");
4
- const path_1 = require("path");
5
3
  const expect_1 = require("../expect");
6
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
7
- const clean_1 = require("../../executer/clean");
8
4
  const get_test_suite_1 = require("../get-test-suite");
9
- const execute_1 = require("../../executer/execute");
10
5
  describe('monorepo', () => {
11
- const suite = get_test_suite_1.getTestSuite('monorepo', ['build.yaml', 'projects', 'build.npm.yaml', 'build.tsc.yaml']);
6
+ const suite = (0, get_test_suite_1.getTestSuite)('monorepo', ['build.yaml', 'projects', 'build.npm.yaml', 'build.tsc.yaml']);
12
7
  afterAll(() => suite.close());
13
- it('should build monorepo', async () => {
14
- const { buildFile, executionContext } = await suite.setup();
15
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'build');
16
- const result = await execute_1.execute(workTree, executionContext);
17
- await expect_1.expectSuccessfulResult(result);
18
- }, 120000);
19
- it('should clean monorepo', async () => {
20
- const { buildFile, context, executionContext } = await suite.setup();
21
- const files = [
22
- path_1.join(buildFile.path, 'projects/a/node_modules'),
23
- path_1.join(buildFile.path, 'projects/a/dist'),
24
- path_1.join(buildFile.path, 'projects/b/node_modules'),
25
- path_1.join(buildFile.path, 'projects/b/dist'),
26
- ];
27
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'build');
28
- const result = await execute_1.execute(workTree, executionContext);
29
- await expect_1.expectSuccessfulResult(result);
30
- for (const file of files) {
31
- expect(fs_1.existsSync(file)).toBeTruthy();
32
- }
33
- await clean_1.clean(workTree.nodes, context);
34
- for (const file of files) {
35
- expect(fs_1.existsSync(file)).toBeFalsy();
36
- }
8
+ it('should build and clean monorepo', async () => {
9
+ const { cli, environment } = await suite.setup({ taskName: 'build' });
10
+ const result = await cli.exec();
11
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
12
+ await cli.clean();
37
13
  }, 120000);
38
14
  });
39
15
  //# sourceMappingURL=monorepo.spec.js.map
@@ -2,12 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const get_test_suite_1 = require("../get-test-suite");
4
4
  describe('multi-line', () => {
5
- const suite = get_test_suite_1.getTestSuite('multi-line', ['build.yaml']);
5
+ const suite = (0, get_test_suite_1.getTestSuite)('multi-line', ['build.yaml']);
6
6
  afterAll(() => suite.close());
7
7
  it('should get multi lines', async () => {
8
- const { buildFile } = await suite.setup();
9
- const task = buildFile.tasks['example'];
10
- expect(task.cmds || []).toEqual([
8
+ const { cli } = await suite.setup({ taskName: 'example' });
9
+ const task = cli.node('example');
10
+ expect((task.cmds || []).map((c) => c.cmd)).toEqual([
11
11
  'some very long cmd continues on line 2',
12
12
  'some other very long cmd continues on line 2',
13
13
  ]);
@@ -5,9 +5,9 @@ const get_test_context_1 = require("../get-test-context");
5
5
  const program_1 = require("../../program");
6
6
  describe('program', () => {
7
7
  async function testCommand(commandArgs) {
8
- const fileName = path_1.join(__dirname, '../../../examples/program');
9
- const context = get_test_context_1.getTestContext(fileName);
10
- const { program, args } = await program_1.getProgram(context, [process.argv[0], fileName, ...commandArgs]);
8
+ const fileName = (0, path_1.join)(__dirname, '../../../examples/program');
9
+ const context = (0, get_test_context_1.getTestContext)(fileName);
10
+ const { program, args } = await (0, program_1.getProgram)(context, [process.argv[0], fileName, ...commandArgs]);
11
11
  return new Promise((resolve, reject) => {
12
12
  program
13
13
  .exitOverride((err) => {
@@ -18,13 +18,6 @@ describe('program', () => {
18
18
  .then(() => resolve());
19
19
  });
20
20
  }
21
- it('should get help with description', async () => {
22
- const fileName = path_1.join(__dirname, '../../../examples/program');
23
- const context = get_test_context_1.getTestContext(fileName);
24
- const { program } = await program_1.getProgram(context, process.argv);
25
- const help = program.exitOverride().helpInformation({ error: false });
26
- expect(help).toContain('example [options] install npm packages');
27
- });
28
21
  it('should run when cache is up to date and --no-cache arg is passed', async () => {
29
22
  await testCommand(['example', '--cache', 'none']);
30
23
  }, 120000);
@@ -1,25 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const expect_1 = require("../expect");
4
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
5
- const plan_work_nodes_1 = require("../../planner/utils/plan-work-nodes");
6
4
  const get_test_suite_1 = require("../get-test-suite");
7
- const execute_1 = require("../../executer/execute");
5
+ const work_scope_1 = require("../../executer/work-scope");
8
6
  describe('reference', () => {
9
- const suite = get_test_suite_1.getTestSuite('reference', ['build.yaml', 'foo']);
7
+ const suite = (0, get_test_suite_1.getTestSuite)('reference', ['build.yaml', 'foo']);
10
8
  afterAll(() => suite.close());
11
9
  it('should run included task', async () => {
12
- const { buildFile, executionContext } = await suite.setup();
13
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
14
- const result = await execute_1.execute(workTree, executionContext);
15
- await expect_1.expectSuccessfulResult(result);
16
- await expect_1.expectLog(result, `foo:bar`, 'foobar');
17
- await expect_1.expectLog(result, `example`, 'hammertime');
10
+ const { cli, environment } = await suite.setup({ taskName: 'example' });
11
+ const result = await cli.exec();
12
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
13
+ await (0, expect_1.expectLog)(result, environment, `foo:bar`, 'foobar');
14
+ await (0, expect_1.expectLog)(result, environment, `example`, 'hammertime');
18
15
  });
19
16
  it('should list task with references tasks nested', async () => {
20
- const { buildFile } = await suite.setup();
21
- const node = plan_work_nodes_1.planWorkNodes(buildFile);
22
- expect(Object.values(node).map((t) => t.name)).toEqual(['example', 'foo:bar', 'foo:sub:sub']);
17
+ const { cli } = await suite.setup((0, work_scope_1.emptyWorkLabelScope)());
18
+ const workNodes = cli.ls();
19
+ expect(workNodes.map((t) => t.item.name)).toEqual(['example', 'foo:bar', 'foo:sub:sub']);
23
20
  });
24
21
  });
25
22
  //# sourceMappingURL=reference.spec.js.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const get_test_suite_1 = require("../get-test-suite");
4
+ const expect_1 = require("../expect");
5
+ describe('services', () => {
6
+ const suite = (0, get_test_suite_1.getTestSuite)('services', ['index.js', 'config.json', 'package.json', 'package-lock.json', 'build.yaml']);
7
+ afterAll(() => suite.close());
8
+ it('should run service', async () => {
9
+ const { cli, environment } = await suite.setup({ taskName: 'api' });
10
+ const result = await cli.exec();
11
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
12
+ }, 120000);
13
+ });
14
+ //# sourceMappingURL=services.spec.js.map
@@ -1,46 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const path_1 = require("path");
4
- const expect_1 = require("../expect");
5
- const restore_1 = require("../../executer/restore");
6
- const plan_work_tree_1 = require("../../planner/utils/plan-work-tree");
7
- const store_1 = require("../../executer/store");
8
- const clean_1 = require("../../executer/clean");
9
- const plan_work_nodes_1 = require("../../planner/utils/plan-work-nodes");
10
4
  const get_test_suite_1 = require("../get-test-suite");
11
- const execute_1 = require("../../executer/execute");
12
5
  const fs_1 = require("fs");
6
+ const expect_1 = require("../expect");
13
7
  describe('store/restore', () => {
14
- const suite = get_test_suite_1.getTestSuite('store-restore', ['build.yaml']);
8
+ const suite = (0, get_test_suite_1.getTestSuite)('store-restore', ['build.yaml', 'package.json']);
15
9
  afterAll(() => suite.close());
16
- it('should clean created outputs', async () => {
17
- const { buildFile, context, executionContext } = await suite.setup();
18
- const outputPath = path_1.join(buildFile.path, 'test-output');
19
- const generatedPath = path_1.join(buildFile.path, 'node_modules');
20
- const workTree = plan_work_tree_1.planWorkTree(buildFile, 'example');
21
- const result = await execute_1.execute(workTree, executionContext);
22
- await expect_1.expectSuccessfulResult(result);
23
- expect(fs_1.existsSync(generatedPath)).toBeTruthy();
24
- expect(fs_1.existsSync(outputPath)).toBeFalsy();
25
- await store_1.store(workTree.nodes, outputPath, context);
26
- await clean_1.clean(workTree.nodes, context);
27
- expect(fs_1.existsSync(outputPath)).toBeTruthy();
28
- expect(fs_1.existsSync(generatedPath)).toBeFalsy();
29
- await restore_1.restore(workTree.nodes, outputPath, context);
30
- expect(fs_1.existsSync(outputPath)).toBeTruthy();
31
- expect(fs_1.existsSync(generatedPath)).toBeTruthy();
10
+ it('should clean and restore created outputs locally', async () => {
11
+ const { cli, environment } = await suite.setup({ taskName: 'example' });
12
+ const generatedPath = (0, path_1.join)(environment.cwd, 'node_modules');
13
+ const cacheStoragePath = (0, path_1.join)(environment.cwd, 'storage');
14
+ expect((0, fs_1.existsSync)(generatedPath)).toBeFalsy();
15
+ expect((0, fs_1.existsSync)(cacheStoragePath)).toBeFalsy();
16
+ const result = await cli.exec({});
17
+ await (0, expect_1.expectSuccessfulResult)(result, environment);
18
+ expect((0, fs_1.existsSync)(generatedPath)).toBeTruthy();
19
+ expect((0, fs_1.existsSync)(cacheStoragePath)).toBeFalsy();
20
+ await cli.store(cacheStoragePath);
21
+ expect((0, fs_1.existsSync)(cacheStoragePath)).toBeTruthy();
22
+ await cli.clean();
23
+ expect((0, fs_1.existsSync)(generatedPath)).toBeFalsy();
24
+ await cli.restore(cacheStoragePath);
25
+ expect((0, fs_1.existsSync)(generatedPath)).toBeTruthy();
26
+ const execAfterRestore = await cli.exec();
27
+ await (0, expect_1.expectSuccessfulResult)(execAfterRestore, environment);
28
+ const node = cli.node('example');
29
+ const nodeState = execAfterRestore.state.node[node.id];
30
+ expect(nodeState.type).toBe('completed');
31
+ if (nodeState.type === 'completed') {
32
+ expect(nodeState.cached).toBeTruthy();
33
+ }
32
34
  });
33
- it('should not store anything if nothing got generated', async () => {
34
- const { buildFile, context } = await suite.setup();
35
- const workNodes = plan_work_nodes_1.planWorkNodes(buildFile);
36
- const outputPath = path_1.join(buildFile.path, 'test-output');
37
- const generatedPath = path_1.join(buildFile.path, 'node_modules');
38
- expect(fs_1.existsSync(generatedPath)).toBeFalsy();
39
- expect(fs_1.existsSync(outputPath)).toBeFalsy();
40
- await store_1.store(workNodes, outputPath, context);
41
- await restore_1.restore(workNodes, outputPath, context);
42
- expect(fs_1.existsSync(generatedPath)).toBeFalsy();
43
- expect(fs_1.existsSync(outputPath)).toBeFalsy();
35
+ it('should clean and restore created outputs in container', async () => {
36
+ const { cli, environment } = await suite.setup({ taskName: 'example:docker' });
37
+ const cacheStoragePath = (0, path_1.join)(environment.cwd, 'storage');
38
+ const firstExecResult = await cli.exec();
39
+ await (0, expect_1.expectSuccessfulResult)(firstExecResult, environment);
40
+ await cli.store(cacheStoragePath);
41
+ await cli.clean();
42
+ await cli.restore(cacheStoragePath);
43
+ const execAfterRestore = await cli.exec();
44
+ await (0, expect_1.expectSuccessfulResult)(execAfterRestore, environment);
45
+ const node = cli.node('example:docker');
46
+ const nodeState = execAfterRestore.state.node[node.id];
47
+ expect(nodeState.type).toBe('completed');
48
+ if (nodeState.type === 'completed') {
49
+ expect(nodeState.cached).toBeTruthy();
50
+ }
44
51
  });
45
52
  });
46
53
  //# sourceMappingURL=store.spec.js.map