navy 6.0.0 → 7.0.0-alpha.2

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 (149) hide show
  1. package/lib/__tests__/config-provider.js +75 -0
  2. package/lib/__tests__/config.js +130 -0
  3. package/lib/__tests__/driver-logging.js +148 -0
  4. package/lib/__tests__/driver.js +19 -0
  5. package/lib/__tests__/errors.js +49 -0
  6. package/lib/__tests__/http-proxy.js +214 -0
  7. package/lib/__tests__/index.js +25 -0
  8. package/lib/__tests__/service.js +16 -0
  9. package/lib/cli/__tests__/develop.js +239 -0
  10. package/lib/cli/__tests__/external-ip.js +68 -0
  11. package/lib/cli/__tests__/health.js +257 -0
  12. package/lib/cli/__tests__/https.js +210 -0
  13. package/lib/cli/__tests__/import.js +110 -0
  14. package/lib/cli/__tests__/index.js +118 -0
  15. package/lib/cli/__tests__/lan-ip.js +90 -0
  16. package/lib/cli/__tests__/launch.js +179 -0
  17. package/lib/cli/__tests__/live.js +155 -0
  18. package/lib/cli/__tests__/local-ip.js +72 -0
  19. package/lib/cli/__tests__/logs.js +52 -0
  20. package/lib/cli/__tests__/open.js +65 -0
  21. package/lib/cli/__tests__/program.js +472 -0
  22. package/lib/cli/__tests__/ps.js +345 -0
  23. package/lib/cli/__tests__/refresh-config.js +95 -0
  24. package/lib/cli/__tests__/run.js +54 -0
  25. package/lib/cli/__tests__/status.js +204 -0
  26. package/lib/cli/__tests__/updates.js +243 -0
  27. package/lib/cli/__tests__/wait-for-healthy.js +134 -0
  28. package/lib/cli/config/__tests__/index.js +275 -0
  29. package/lib/cli/config/__tests__/wrapper.js +53 -0
  30. package/lib/cli/config/index.js +19 -37
  31. package/lib/cli/config/wrapper.js +0 -6
  32. package/lib/cli/develop.js +7 -21
  33. package/lib/cli/doctor/__tests__/clean-compose-files.js +78 -0
  34. package/lib/cli/doctor/__tests__/index.js +67 -0
  35. package/lib/cli/doctor/__tests__/invalid-compose-config.js +103 -0
  36. package/lib/cli/doctor/__tests__/invalid-state.js +83 -0
  37. package/lib/cli/doctor/__tests__/util.js +91 -0
  38. package/lib/cli/doctor/clean-compose-files.js +5 -13
  39. package/lib/cli/doctor/index.js +0 -12
  40. package/lib/cli/doctor/invalid-compose-config.js +0 -4
  41. package/lib/cli/doctor/invalid-state.js +0 -6
  42. package/lib/cli/doctor/util.js +0 -10
  43. package/lib/cli/external-ip.js +0 -4
  44. package/lib/cli/health.js +0 -12
  45. package/lib/cli/https.js +9 -25
  46. package/lib/cli/import.js +0 -12
  47. package/lib/cli/index.js +0 -9
  48. package/lib/cli/lan-ip.js +2 -8
  49. package/lib/cli/launch.js +0 -9
  50. package/lib/cli/live.js +6 -16
  51. package/lib/cli/local-ip.js +2 -7
  52. package/lib/cli/logs.js +0 -3
  53. package/lib/cli/open.js +2 -7
  54. package/lib/cli/program.js +73 -101
  55. package/lib/cli/ps.js +1 -21
  56. package/lib/cli/refresh-config.js +0 -7
  57. package/lib/cli/run.js +0 -3
  58. package/lib/cli/status.js +0 -11
  59. package/lib/cli/updates.js +0 -22
  60. package/lib/cli/util/__tests__/get-or-initialise-navy.js +66 -0
  61. package/lib/cli/util/__tests__/import.js +123 -0
  62. package/lib/cli/util/__tests__/index.js +17 -0
  63. package/lib/cli/util/__tests__/merge-action-options.js +47 -0
  64. package/lib/cli/util/__tests__/reconfigure.js +78 -0
  65. package/lib/cli/util/get-or-initialise-navy.js +0 -7
  66. package/lib/cli/util/import.js +0 -9
  67. package/lib/cli/util/index.js +0 -2
  68. package/lib/cli/util/merge-action-options.js +20 -0
  69. package/lib/cli/util/reconfigure.js +0 -4
  70. package/lib/cli/wait-for-healthy.js +0 -21
  71. package/lib/client/registry/__tests__/get-credentials.js +62 -0
  72. package/lib/client/registry/__tests__/get-endpoint.js +124 -0
  73. package/lib/client/registry/__tests__/get-fat-manifest.js +67 -0
  74. package/lib/client/registry/__tests__/get-token.js +66 -0
  75. package/lib/client/registry/__tests__/helpers.js +26 -0
  76. package/lib/client/registry/get-credentials.js +3 -9
  77. package/lib/client/registry/get-endpoint.js +29 -63
  78. package/lib/client/registry/get-fat-manifest.js +2 -9
  79. package/lib/client/registry/get-token.js +2 -13
  80. package/lib/client/registry/helpers.js +0 -4
  81. package/lib/config-provider.js +0 -12
  82. package/lib/config-providers/filesystem/__tests__/index.js +176 -0
  83. package/lib/config-providers/filesystem/index.js +5 -23
  84. package/lib/config-providers/npm/__tests__/index.js +226 -0
  85. package/lib/config-providers/npm/__tests__/util.js +1 -2
  86. package/lib/config-providers/npm/index.js +12 -35
  87. package/lib/config-providers/npm/util.js +0 -3
  88. package/lib/config.js +4 -19
  89. package/lib/domain/__tests__/container-image.js +81 -0
  90. package/lib/domain/__tests__/oci-api-specification.js +23 -0
  91. package/lib/domain/container-image.js +8 -21
  92. package/lib/domain/oci-api-specification.js +3 -5
  93. package/lib/driver-logging.js +0 -19
  94. package/lib/driver.js +0 -4
  95. package/lib/drivers/docker-compose/__tests__/client.js +249 -0
  96. package/lib/drivers/docker-compose/__tests__/index.js +430 -0
  97. package/lib/drivers/docker-compose/client.js +0 -16
  98. package/lib/drivers/docker-compose/index.js +7 -49
  99. package/lib/errors.js +0 -10
  100. package/lib/http-proxy.js +28 -23
  101. package/lib/index.js +1 -9
  102. package/lib/middleware/__tests__/add-service-proxy-config.js +258 -0
  103. package/lib/middleware/__tests__/develop.js +120 -0
  104. package/lib/middleware/__tests__/helpers.js +154 -0
  105. package/lib/middleware/__tests__/port-override.js +125 -0
  106. package/lib/middleware/__tests__/set-env-vars.js +94 -0
  107. package/lib/middleware/__tests__/set-image.js +76 -0
  108. package/lib/middleware/__tests__/set-logging-driver.js +94 -0
  109. package/lib/middleware/__tests__/tag-override.js +92 -0
  110. package/lib/middleware/add-service-proxy-config.js +8 -16
  111. package/lib/middleware/develop.js +2 -5
  112. package/lib/middleware/helpers.js +6 -12
  113. package/lib/middleware/port-override.js +5 -8
  114. package/lib/middleware/set-env-vars.js +6 -6
  115. package/lib/middleware/set-image.js +4 -5
  116. package/lib/middleware/set-logging-driver.js +6 -6
  117. package/lib/middleware/tag-override.js +4 -6
  118. package/lib/navy/__tests__/default-middleware.js +40 -0
  119. package/lib/navy/__tests__/index.js +1612 -0
  120. package/lib/navy/__tests__/middleware.js +71 -0
  121. package/lib/navy/__tests__/plugin-interface.js +121 -0
  122. package/lib/navy/__tests__/state.js +103 -0
  123. package/lib/navy/__tests__/util.js +24 -0
  124. package/lib/navy/default-middleware.js +0 -10
  125. package/lib/navy/index.js +83 -138
  126. package/lib/navy/middleware.js +0 -6
  127. package/lib/navy/plugin-interface.js +2 -10
  128. package/lib/navy/state.js +12 -24
  129. package/lib/navy/util.js +0 -1
  130. package/lib/service.js +2 -3
  131. package/lib/util/__tests__/exec-async.js +83 -0
  132. package/lib/util/__tests__/external-ip.js +97 -2
  133. package/lib/util/__tests__/get-lan-ip.js +46 -0
  134. package/lib/util/__tests__/has-update.js +136 -0
  135. package/lib/util/__tests__/https.js +301 -0
  136. package/lib/util/__tests__/navyrc.js +45 -0
  137. package/lib/util/__tests__/service-host.js +63 -5
  138. package/lib/util/__tests__/table.js +44 -0
  139. package/lib/util/docker-client.js +2 -10
  140. package/lib/util/exec-async.js +0 -4
  141. package/lib/util/external-ip.js +8 -12
  142. package/lib/util/fs.js +1 -6
  143. package/lib/util/get-lan-ip.js +0 -5
  144. package/lib/util/has-update.js +2 -14
  145. package/lib/util/https.js +11 -55
  146. package/lib/util/navyrc.js +0 -5
  147. package/lib/util/service-host.js +0 -17
  148. package/lib/util/table.js +0 -6
  149. package/package.json +14 -13
@@ -9,65 +9,52 @@ exports.getRegistryFromImage = getRegistryFromImage;
9
9
  exports.getRepositoryFromImage = getRepositoryFromImage;
10
10
  exports.getTagFromImageWithTag = getTagFromImageWithTag;
11
11
  // docker v2 registry URL
12
- const DEFAULT_REGISTRY = 'registry-1.docker.io'; // the url which docker stores in .docker/config.json for auth
13
-
14
- exports.DEFAULT_REGISTRY = DEFAULT_REGISTRY;
15
- const DEFAULT_REGISTRY_AUTH = 'https://index.docker.io/v1/'; // someregistry.com/some/image:latest -> someregistry.com/some/image
16
-
17
- exports.DEFAULT_REGISTRY_AUTH = DEFAULT_REGISTRY_AUTH;
12
+ const DEFAULT_REGISTRY = exports.DEFAULT_REGISTRY = 'registry-1.docker.io';
13
+ // the url which docker stores in .docker/config.json for auth
14
+ const DEFAULT_REGISTRY_AUTH = exports.DEFAULT_REGISTRY_AUTH = 'https://index.docker.io/v1/';
18
15
 
16
+ // someregistry.com/some/image:latest -> someregistry.com/some/image
19
17
  function getImageFromImageWithTag(imageWithTag) {
20
18
  if (imageWithTag.lastIndexOf('/') !== -1) {
21
19
  const lastSlash = imageWithTag.lastIndexOf('/');
22
-
23
20
  if (imageWithTag.indexOf(':', lastSlash) !== -1) {
24
21
  return imageWithTag.substring(0, imageWithTag.indexOf(':', lastSlash));
25
22
  }
26
-
27
23
  return imageWithTag;
28
24
  }
29
-
30
25
  if (imageWithTag.indexOf(':') !== -1) {
31
26
  return imageWithTag.substring(0, imageWithTag.indexOf(':'));
32
27
  }
33
-
34
28
  return imageWithTag;
35
- } // someregistry.com/some/image:latest -> latest
36
-
29
+ }
37
30
 
31
+ // someregistry.com/some/image:latest -> latest
38
32
  function getTagFromImageWithTag(imageWithTag) {
39
33
  if (imageWithTag.lastIndexOf('/') !== -1) {
40
34
  const lastSlash = imageWithTag.lastIndexOf('/');
41
-
42
35
  if (imageWithTag.indexOf(':', lastSlash) !== -1) {
43
36
  return imageWithTag.substring(imageWithTag.indexOf(':', lastSlash) + 1);
44
37
  }
45
-
46
38
  return 'latest';
47
39
  }
48
-
49
40
  if (imageWithTag.indexOf(':') !== -1) {
50
41
  return imageWithTag.substring(imageWithTag.indexOf(':') + 1);
51
42
  }
52
-
53
43
  return 'latest';
54
44
  }
55
-
56
45
  function getRegistryFromImage(image) {
57
46
  const parsedRegistry = image.match(/([a-zA-Z0-9-.:]+)\/[a-zA-Z0-9-]+\/[a-zA-Z0-9-]+/);
58
47
  const registry = parsedRegistry != null && parsedRegistry.length > 1 ? parsedRegistry[1] : DEFAULT_REGISTRY;
59
48
  return registry;
60
- } // someregistry.com/some/image -> some/image
61
-
49
+ }
62
50
 
51
+ // someregistry.com/some/image -> some/image
63
52
  function getRepositoryFromImage(image) {
64
53
  if (image.lastIndexOf('/') === -1) {
65
54
  return 'library/' + image;
66
55
  }
67
-
68
56
  if (image.split('/').length === 3) {
69
57
  return image.substring(image.indexOf('/') + 1);
70
58
  }
71
-
72
59
  return image;
73
60
  }
@@ -4,12 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.restSpecification = exports.MEDIA_TYPES = void 0;
7
- const restSpecification = {
7
+ const restSpecification = exports.restSpecification = {
8
8
  operation: (registry, endpoint) => `https://${registry}/v2/${endpoint}`,
9
9
  getManifest: (repository, tag) => `${repository}/manifests/${tag}`
10
10
  };
11
- exports.restSpecification = restSpecification;
12
- const MEDIA_TYPES = {
11
+ const MEDIA_TYPES = exports.MEDIA_TYPES = {
13
12
  FAT_MANIFEST: 'application/vnd.docker.distribution.manifest.list.v2+json'
14
- };
15
- exports.MEDIA_TYPES = MEDIA_TYPES;
13
+ };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
@@ -9,25 +8,19 @@ exports.isDriverLogging = isDriverLogging;
9
8
  exports.log = log;
10
9
  exports.startDriverLogging = startDriverLogging;
11
10
  exports.stopDriverLogging = stopDriverLogging;
12
-
13
11
  var _cliSpinners = require("cli-spinners");
14
-
15
12
  var _chalk = _interopRequireDefault(require("chalk"));
16
-
17
13
  let _isDriverLogging = false;
18
14
  let _spinnerInterval = null;
19
15
  let _spinnerIndex = 0;
20
16
  let _message = null;
21
-
22
17
  function _redraw(opts = {}) {
23
18
  let symbol = _chalk.default.cyan(_cliSpinners.dots.frames[_spinnerIndex]);
24
-
25
19
  if (opts.success === true) {
26
20
  symbol = _chalk.default.green('✔');
27
21
  } else if (opts.success === false) {
28
22
  symbol = _chalk.default.red('•');
29
23
  }
30
-
31
24
  if (!process.stdout.isTTY) {
32
25
  if (opts.success) {
33
26
  console.log();
@@ -36,49 +29,37 @@ function _redraw(opts = {}) {
36
29
  console.log();
37
30
  console.log(symbol, 'FAILURE');
38
31
  }
39
-
40
32
  return;
41
33
  }
42
-
43
34
  process.stdout.write(' \n');
44
35
  process.stdout.write(` ${symbol} ${opts.success === false ? _chalk.default.red(_message, 'FAILED') : _message}\n`);
45
36
  process.stdout.cursorTo(0);
46
37
  process.stdout.moveCursor(0, -2);
47
38
  }
48
-
49
39
  function startDriverLogging(message) {
50
40
  _isDriverLogging = true;
51
41
  _message = message;
52
-
53
42
  _redraw();
54
-
55
43
  _spinnerInterval = setInterval(() => {
56
44
  _spinnerIndex++;
57
-
58
45
  if (_spinnerIndex >= _cliSpinners.dots.frames.length) {
59
46
  _spinnerIndex = 0;
60
47
  }
61
-
62
48
  _redraw();
63
49
  }, _cliSpinners.dots.interval);
64
50
  }
65
-
66
51
  function stopDriverLogging(opts = {}) {
67
52
  if (!isDriverLogging()) return;
68
53
  _isDriverLogging = false;
69
54
  clearInterval(_spinnerInterval);
70
-
71
55
  _redraw({
72
56
  success: opts.success != null ? opts.success : true
73
57
  });
74
-
75
58
  if (process.stdout.isTTY) console.log('\n\n');
76
59
  }
77
-
78
60
  function isDriverLogging() {
79
61
  return _isDriverLogging;
80
62
  }
81
-
82
63
  function log(message) {
83
64
  if (!isDriverLogging()) return;
84
65
  process.stdout.write(_chalk.default.dim(message));
package/lib/driver.js CHANGED
@@ -1,19 +1,15 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.resolveDriverFromName = resolveDriverFromName;
9
-
10
8
  var _dockerCompose = _interopRequireDefault(require("./drivers/docker-compose"));
11
-
12
9
  function resolveDriverFromName(driverName) {
13
10
  switch (driverName) {
14
11
  case 'docker-compose':
15
12
  return _dockerCompose.default;
16
13
  }
17
-
18
14
  return null;
19
15
  }
@@ -0,0 +1,249 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _chai = require("chai");
5
+ var _sinon = _interopRequireDefault(require("sinon"));
6
+ var _path = _interopRequireDefault(require("path"));
7
+ var _events = require("events");
8
+ var _fs = _interopRequireDefault(require("../../../util/fs"));
9
+ var execAsyncModule = _interopRequireWildcard(require("../../../util/exec-async"));
10
+ var driverLogging = _interopRequireWildcard(require("../../../driver-logging"));
11
+ var _client = require("../client");
12
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
+ /* eslint-env mocha */
14
+
15
+ function makeNavy({
16
+ name = 'env',
17
+ normalisedName = 'env',
18
+ configProvider = null
19
+ } = {}) {
20
+ return {
21
+ name,
22
+ normalisedName,
23
+ getConfigProvider: _sinon.default.stub().resolves(configProvider)
24
+ };
25
+ }
26
+ describe('docker-compose client', function () {
27
+ let sandbox;
28
+ let originalHome;
29
+ let execStub;
30
+ beforeEach(function () {
31
+ sandbox = _sinon.default.createSandbox();
32
+ originalHome = process.env.HOME;
33
+ process.env.HOME = '/home/test';
34
+ execStub = sandbox.stub(execAsyncModule, 'execAsync').resolves('');
35
+ sandbox.stub(driverLogging, 'log');
36
+ });
37
+ afterEach(function () {
38
+ sandbox.restore();
39
+ if (originalHome === undefined) {
40
+ delete process.env.HOME;
41
+ } else {
42
+ process.env.HOME = originalHome;
43
+ }
44
+ });
45
+ describe('createComposeClient', function () {
46
+ it('should expose exec, getCompiledDockerComposePath, getDockerComposeFilePath, getOriginalDockerComposeDirectory', function () {
47
+ const client = (0, _client.createComposeClient)(makeNavy());
48
+ (0, _chai.expect)(client).to.have.property('exec').that.is.a('function');
49
+ (0, _chai.expect)(client).to.have.property('getCompiledDockerComposePath').that.is.a('function');
50
+ (0, _chai.expect)(client).to.have.property('getDockerComposeFilePath').that.is.a('function');
51
+ (0, _chai.expect)(client).to.have.property('getOriginalDockerComposeDirectory').that.is.a('function');
52
+ });
53
+ });
54
+ describe('getCompiledDockerComposePath', function () {
55
+ it('should return $HOME/.navy/navies/<env>/docker-compose.tmp.yml', function () {
56
+ const client = (0, _client.createComposeClient)(makeNavy({
57
+ normalisedName: 'envname'
58
+ }));
59
+ (0, _chai.expect)(client.getCompiledDockerComposePath()).to.equal(_path.default.join('/home/test', '.navy', 'navies', 'envname', 'docker-compose.tmp.yml'));
60
+ });
61
+ });
62
+ describe('getDockerComposeFilePath', function () {
63
+ it('should return the compiled path when the file exists', async function () {
64
+ const client = (0, _client.createComposeClient)(makeNavy());
65
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
66
+ const result = await client.getDockerComposeFilePath();
67
+ (0, _chai.expect)(result).to.contain('docker-compose.tmp.yml');
68
+ });
69
+ it('should return null when the compiled file does not exist', async function () {
70
+ const client = (0, _client.createComposeClient)(makeNavy());
71
+ sandbox.stub(_fs.default, 'statAsync').rejects(new Error('ENOENT'));
72
+ (0, _chai.expect)(await client.getDockerComposeFilePath()).to.equal(null);
73
+ });
74
+ });
75
+ describe('getOriginalDockerComposeDirectory', function () {
76
+ it('should return the navy path from the config provider', async function () {
77
+ const client = (0, _client.createComposeClient)(makeNavy({
78
+ configProvider: {
79
+ getNavyPath: async () => '/some/path'
80
+ }
81
+ }));
82
+ (0, _chai.expect)(await client.getOriginalDockerComposeDirectory()).to.equal('/some/path');
83
+ });
84
+ it('should throw an invariant violation when there is no config provider', async function () {
85
+ const client = (0, _client.createComposeClient)(makeNavy({
86
+ configProvider: null
87
+ }));
88
+ let caught;
89
+ try {
90
+ await client.getOriginalDockerComposeDirectory();
91
+ } catch (err) {
92
+ caught = err;
93
+ }
94
+ (0, _chai.expect)(caught).to.be.an('error');
95
+ (0, _chai.expect)(caught.message).to.match(/NO_CONFIG_PROVIDER/);
96
+ });
97
+ });
98
+ describe('exec', function () {
99
+ it('should call docker compose with -p <name> -f <compiled path> when compiled file exists', async function () {
100
+ const client = (0, _client.createComposeClient)(makeNavy({
101
+ normalisedName: 'env'
102
+ }));
103
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
104
+ await client.exec('up', ['-d']);
105
+ (0, _chai.expect)(execStub.calledOnce).to.equal(true);
106
+ const [cmd, args,, opts] = execStub.firstCall.args;
107
+ (0, _chai.expect)(cmd).to.equal('docker compose');
108
+ (0, _chai.expect)(args[0]).to.equal('-p');
109
+ (0, _chai.expect)(args[1]).to.equal('env');
110
+ (0, _chai.expect)(args[2]).to.equal('-f');
111
+ (0, _chai.expect)(args[3]).to.contain('docker-compose.tmp.yml');
112
+ (0, _chai.expect)(args.slice(4)).to.eql(['up', '-d']);
113
+ (0, _chai.expect)(opts.maxBuffer).to.equal(Infinity);
114
+ });
115
+ it('should set cwd to the original docker-compose directory when the compiled file is missing', async function () {
116
+ const client = (0, _client.createComposeClient)(makeNavy({
117
+ configProvider: {
118
+ getNavyPath: async () => '/orig/path'
119
+ }
120
+ }));
121
+ sandbox.stub(_fs.default, 'statAsync').rejects(new Error('ENOENT'));
122
+ await client.exec('config');
123
+ const [, args,, opts] = execStub.firstCall.args;
124
+ (0, _chai.expect)(args).to.not.include('-f');
125
+ (0, _chai.expect)(opts.cwd).to.equal('/orig/path');
126
+ });
127
+ it('should pass useOriginalDockerComposeFiles to bypass the compiled file', async function () {
128
+ const client = (0, _client.createComposeClient)(makeNavy({
129
+ configProvider: {
130
+ getNavyPath: async () => '/orig/path'
131
+ }
132
+ }));
133
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
134
+ await client.exec('config', [], {
135
+ useOriginalDockerComposeFiles: true
136
+ });
137
+ const [, args,, opts] = execStub.firstCall.args;
138
+ (0, _chai.expect)(args).to.not.include('-f');
139
+ (0, _chai.expect)(opts.cwd).to.equal('/orig/path');
140
+ });
141
+ it('should respect a custom maxBuffer', async function () {
142
+ const client = (0, _client.createComposeClient)(makeNavy());
143
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
144
+ await client.exec('up', [], {
145
+ maxBuffer: 1024
146
+ });
147
+ const [,,, opts] = execStub.firstCall.args;
148
+ (0, _chai.expect)(opts.maxBuffer).to.equal(1024);
149
+ });
150
+ it('should default args to an empty array', async function () {
151
+ const client = (0, _client.createComposeClient)(makeNavy());
152
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
153
+ await client.exec('config');
154
+ (0, _chai.expect)(execStub.calledOnce).to.equal(true);
155
+ });
156
+ it('should pipe child stdout/stderr through the spinner log when noLog and pipeLog are not set', async function () {
157
+ const client = (0, _client.createComposeClient)(makeNavy());
158
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
159
+ const child = new _events.EventEmitter();
160
+ child.stdout = new _events.EventEmitter();
161
+ child.stderr = new _events.EventEmitter();
162
+ execStub.callsFake(async (cmd, args, callback) => {
163
+ callback(child);
164
+ child.stdout.emit('data', 'out-line');
165
+ child.stderr.emit('data', 'err-line');
166
+ return '';
167
+ });
168
+ await client.exec('up');
169
+ (0, _chai.expect)(driverLogging.log.callCount).to.equal(2);
170
+ (0, _chai.expect)(driverLogging.log.firstCall.args[0]).to.equal('out-line');
171
+ (0, _chai.expect)(driverLogging.log.secondCall.args[0]).to.equal('err-line');
172
+ });
173
+ it('should pipe child stdout/stderr to process.stdout/stderr when pipeLog is true', async function () {
174
+ const client = (0, _client.createComposeClient)(makeNavy());
175
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
176
+ const child = new _events.EventEmitter();
177
+ child.stdout = new _events.EventEmitter();
178
+ child.stderr = new _events.EventEmitter();
179
+ const stdoutWrite = sandbox.stub(process.stdout, 'write').returns(true);
180
+ const stderrWrite = sandbox.stub(process.stderr, 'write').returns(true);
181
+ execStub.callsFake(async (cmd, args, callback) => {
182
+ callback(child);
183
+ child.stdout.emit('data', 'out');
184
+ child.stderr.emit('data', 'err');
185
+ return '';
186
+ });
187
+ await client.exec('logs', [], {
188
+ pipeLog: true
189
+ });
190
+ (0, _chai.expect)(stdoutWrite.calledWith('out')).to.equal(true);
191
+ (0, _chai.expect)(stderrWrite.calledWith('err')).to.equal(true);
192
+ });
193
+ it('should NOT attach stdout/stderr listeners when noLog is true', async function () {
194
+ const client = (0, _client.createComposeClient)(makeNavy());
195
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
196
+ const child = new _events.EventEmitter();
197
+ child.stdout = new _events.EventEmitter();
198
+ child.stderr = new _events.EventEmitter();
199
+ execStub.callsFake(async (cmd, args, callback) => {
200
+ callback(child);
201
+ return '';
202
+ });
203
+ await client.exec('config', [], {
204
+ noLog: true
205
+ });
206
+ (0, _chai.expect)(child.stdout.listenerCount('data')).to.equal(0);
207
+ (0, _chai.expect)(child.stderr.listenerCount('data')).to.equal(0);
208
+ });
209
+ it('should map "Can\'t find a suitable configuration file" errors to NO_DOCKER_COMPOSE_FILE invariant', async function () {
210
+ const client = (0, _client.createComposeClient)(makeNavy());
211
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
212
+ execStub.rejects(new Error("Can't find a suitable configuration file"));
213
+ let caught;
214
+ try {
215
+ await client.exec('config');
216
+ } catch (err) {
217
+ caught = err;
218
+ }
219
+ (0, _chai.expect)(caught).to.be.an('error');
220
+ (0, _chai.expect)(caught.message).to.match(/NO_DOCKER_COMPOSE_FILE/);
221
+ });
222
+ it('should rethrow other exec errors as-is', async function () {
223
+ const client = (0, _client.createComposeClient)(makeNavy());
224
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
225
+ const err = new Error('some other failure');
226
+ execStub.rejects(err);
227
+ let caught;
228
+ try {
229
+ await client.exec('up');
230
+ } catch (e) {
231
+ caught = e;
232
+ }
233
+ (0, _chai.expect)(caught).to.equal(err);
234
+ });
235
+ it('should rethrow errors that have no message', async function () {
236
+ const client = (0, _client.createComposeClient)(makeNavy());
237
+ sandbox.stub(_fs.default, 'statAsync').resolves({});
238
+ const err = {};
239
+ execStub.rejects(err);
240
+ let caught;
241
+ try {
242
+ await client.exec('up');
243
+ } catch (e) {
244
+ caught = e;
245
+ }
246
+ (0, _chai.expect)(caught).to.equal(err);
247
+ });
248
+ });
249
+ });