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.
- package/lib/__tests__/config-provider.js +75 -0
- package/lib/__tests__/config.js +130 -0
- package/lib/__tests__/driver-logging.js +148 -0
- package/lib/__tests__/driver.js +19 -0
- package/lib/__tests__/errors.js +49 -0
- package/lib/__tests__/http-proxy.js +214 -0
- package/lib/__tests__/index.js +25 -0
- package/lib/__tests__/service.js +16 -0
- package/lib/cli/__tests__/develop.js +239 -0
- package/lib/cli/__tests__/external-ip.js +68 -0
- package/lib/cli/__tests__/health.js +257 -0
- package/lib/cli/__tests__/https.js +210 -0
- package/lib/cli/__tests__/import.js +110 -0
- package/lib/cli/__tests__/index.js +118 -0
- package/lib/cli/__tests__/lan-ip.js +90 -0
- package/lib/cli/__tests__/launch.js +179 -0
- package/lib/cli/__tests__/live.js +155 -0
- package/lib/cli/__tests__/local-ip.js +72 -0
- package/lib/cli/__tests__/logs.js +52 -0
- package/lib/cli/__tests__/open.js +65 -0
- package/lib/cli/__tests__/program.js +472 -0
- package/lib/cli/__tests__/ps.js +345 -0
- package/lib/cli/__tests__/refresh-config.js +95 -0
- package/lib/cli/__tests__/run.js +54 -0
- package/lib/cli/__tests__/status.js +204 -0
- package/lib/cli/__tests__/updates.js +243 -0
- package/lib/cli/__tests__/wait-for-healthy.js +134 -0
- package/lib/cli/config/__tests__/index.js +275 -0
- package/lib/cli/config/__tests__/wrapper.js +53 -0
- package/lib/cli/config/index.js +19 -37
- package/lib/cli/config/wrapper.js +0 -6
- package/lib/cli/develop.js +7 -21
- package/lib/cli/doctor/__tests__/clean-compose-files.js +78 -0
- package/lib/cli/doctor/__tests__/index.js +67 -0
- package/lib/cli/doctor/__tests__/invalid-compose-config.js +103 -0
- package/lib/cli/doctor/__tests__/invalid-state.js +83 -0
- package/lib/cli/doctor/__tests__/util.js +91 -0
- package/lib/cli/doctor/clean-compose-files.js +5 -13
- package/lib/cli/doctor/index.js +0 -12
- package/lib/cli/doctor/invalid-compose-config.js +0 -4
- package/lib/cli/doctor/invalid-state.js +0 -6
- package/lib/cli/doctor/util.js +0 -10
- package/lib/cli/external-ip.js +0 -4
- package/lib/cli/health.js +0 -12
- package/lib/cli/https.js +9 -25
- package/lib/cli/import.js +0 -12
- package/lib/cli/index.js +0 -9
- package/lib/cli/lan-ip.js +2 -8
- package/lib/cli/launch.js +0 -9
- package/lib/cli/live.js +6 -16
- package/lib/cli/local-ip.js +2 -7
- package/lib/cli/logs.js +0 -3
- package/lib/cli/open.js +2 -7
- package/lib/cli/program.js +73 -101
- package/lib/cli/ps.js +1 -21
- package/lib/cli/refresh-config.js +0 -7
- package/lib/cli/run.js +0 -3
- package/lib/cli/status.js +0 -11
- package/lib/cli/updates.js +0 -22
- package/lib/cli/util/__tests__/get-or-initialise-navy.js +66 -0
- package/lib/cli/util/__tests__/import.js +123 -0
- package/lib/cli/util/__tests__/index.js +17 -0
- package/lib/cli/util/__tests__/merge-action-options.js +47 -0
- package/lib/cli/util/__tests__/reconfigure.js +78 -0
- package/lib/cli/util/get-or-initialise-navy.js +0 -7
- package/lib/cli/util/import.js +0 -9
- package/lib/cli/util/index.js +0 -2
- package/lib/cli/util/merge-action-options.js +20 -0
- package/lib/cli/util/reconfigure.js +0 -4
- package/lib/cli/wait-for-healthy.js +0 -21
- package/lib/client/registry/__tests__/get-credentials.js +62 -0
- package/lib/client/registry/__tests__/get-endpoint.js +124 -0
- package/lib/client/registry/__tests__/get-fat-manifest.js +67 -0
- package/lib/client/registry/__tests__/get-token.js +66 -0
- package/lib/client/registry/__tests__/helpers.js +26 -0
- package/lib/client/registry/get-credentials.js +3 -9
- package/lib/client/registry/get-endpoint.js +29 -63
- package/lib/client/registry/get-fat-manifest.js +2 -9
- package/lib/client/registry/get-token.js +2 -13
- package/lib/client/registry/helpers.js +0 -4
- package/lib/config-provider.js +0 -12
- package/lib/config-providers/filesystem/__tests__/index.js +176 -0
- package/lib/config-providers/filesystem/index.js +5 -23
- package/lib/config-providers/npm/__tests__/index.js +226 -0
- package/lib/config-providers/npm/__tests__/util.js +1 -2
- package/lib/config-providers/npm/index.js +12 -35
- package/lib/config-providers/npm/util.js +0 -3
- package/lib/config.js +4 -19
- package/lib/domain/__tests__/container-image.js +81 -0
- package/lib/domain/__tests__/oci-api-specification.js +23 -0
- package/lib/domain/container-image.js +8 -21
- package/lib/domain/oci-api-specification.js +3 -5
- package/lib/driver-logging.js +0 -19
- package/lib/driver.js +0 -4
- package/lib/drivers/docker-compose/__tests__/client.js +249 -0
- package/lib/drivers/docker-compose/__tests__/index.js +430 -0
- package/lib/drivers/docker-compose/client.js +0 -16
- package/lib/drivers/docker-compose/index.js +7 -49
- package/lib/errors.js +0 -10
- package/lib/http-proxy.js +28 -23
- package/lib/index.js +1 -9
- package/lib/middleware/__tests__/add-service-proxy-config.js +258 -0
- package/lib/middleware/__tests__/develop.js +120 -0
- package/lib/middleware/__tests__/helpers.js +154 -0
- package/lib/middleware/__tests__/port-override.js +125 -0
- package/lib/middleware/__tests__/set-env-vars.js +94 -0
- package/lib/middleware/__tests__/set-image.js +76 -0
- package/lib/middleware/__tests__/set-logging-driver.js +94 -0
- package/lib/middleware/__tests__/tag-override.js +92 -0
- package/lib/middleware/add-service-proxy-config.js +8 -16
- package/lib/middleware/develop.js +2 -5
- package/lib/middleware/helpers.js +6 -12
- package/lib/middleware/port-override.js +5 -8
- package/lib/middleware/set-env-vars.js +6 -6
- package/lib/middleware/set-image.js +4 -5
- package/lib/middleware/set-logging-driver.js +6 -6
- package/lib/middleware/tag-override.js +4 -6
- package/lib/navy/__tests__/default-middleware.js +40 -0
- package/lib/navy/__tests__/index.js +1612 -0
- package/lib/navy/__tests__/middleware.js +71 -0
- package/lib/navy/__tests__/plugin-interface.js +121 -0
- package/lib/navy/__tests__/state.js +103 -0
- package/lib/navy/__tests__/util.js +24 -0
- package/lib/navy/default-middleware.js +0 -10
- package/lib/navy/index.js +83 -138
- package/lib/navy/middleware.js +0 -6
- package/lib/navy/plugin-interface.js +2 -10
- package/lib/navy/state.js +12 -24
- package/lib/navy/util.js +0 -1
- package/lib/service.js +2 -3
- package/lib/util/__tests__/exec-async.js +83 -0
- package/lib/util/__tests__/external-ip.js +97 -2
- package/lib/util/__tests__/get-lan-ip.js +46 -0
- package/lib/util/__tests__/has-update.js +136 -0
- package/lib/util/__tests__/https.js +301 -0
- package/lib/util/__tests__/navyrc.js +45 -0
- package/lib/util/__tests__/service-host.js +63 -5
- package/lib/util/__tests__/table.js +44 -0
- package/lib/util/docker-client.js +2 -10
- package/lib/util/exec-async.js +0 -4
- package/lib/util/external-ip.js +8 -12
- package/lib/util/fs.js +1 -6
- package/lib/util/get-lan-ip.js +0 -5
- package/lib/util/has-update.js +2 -14
- package/lib/util/https.js +11 -55
- package/lib/util/navyrc.js +0 -5
- package/lib/util/service-host.js +0 -17
- package/lib/util/table.js +0 -6
- package/package.json +14 -13
|
@@ -1,20 +1,14 @@
|
|
|
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.default = createFileSystemConfigProvider;
|
|
9
|
-
|
|
10
8
|
var _path = _interopRequireDefault(require("path"));
|
|
11
|
-
|
|
12
9
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
13
|
-
|
|
14
10
|
var _fs = _interopRequireDefault(require("../../util/fs"));
|
|
15
|
-
|
|
16
11
|
var _execAsync = require("../../util/exec-async");
|
|
17
|
-
|
|
18
12
|
async function cwdHasValidDockerComposeConfig() {
|
|
19
13
|
try {
|
|
20
14
|
await (0, _execAsync.execAsync)('docker compose', ['config'], null, {
|
|
@@ -24,62 +18,51 @@ async function cwdHasValidDockerComposeConfig() {
|
|
|
24
18
|
} catch (ex) {
|
|
25
19
|
return false;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
21
|
return true;
|
|
29
22
|
}
|
|
30
|
-
|
|
31
23
|
function createFileSystemConfigProvider(navy) {
|
|
32
|
-
|
|
24
|
+
const provider = {
|
|
33
25
|
async getNavyPath() {
|
|
34
26
|
const envState = await navy.getState();
|
|
35
27
|
(0, _invariant.default)(!!envState, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
36
28
|
(0, _invariant.default)(!!envState.path, "FILESYSTEM_PROVIDER_REQUIRES_PATH: File system config provider requires a path for %s", navy.name);
|
|
37
|
-
|
|
38
29
|
try {
|
|
39
30
|
await _fs.default.statAsync(envState.path);
|
|
40
31
|
} catch (ex) {
|
|
41
32
|
(0, _invariant.default)(false, "FILESYSTEM_PROVIDER_INVALID_PATH: Invalid path given to navy: %s", navy.name);
|
|
42
33
|
}
|
|
43
|
-
|
|
44
34
|
return envState.path;
|
|
45
35
|
},
|
|
46
|
-
|
|
47
36
|
async getNavyFilePath() {
|
|
48
|
-
|
|
37
|
+
const navyPath = await provider.getNavyPath();
|
|
38
|
+
(0, _invariant.default)(navyPath, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
39
|
+
return _path.default.join(navyPath, 'Navyfile.js');
|
|
49
40
|
},
|
|
50
|
-
|
|
51
41
|
async refreshConfig() {
|
|
52
42
|
// no-op
|
|
53
43
|
return false;
|
|
54
44
|
},
|
|
55
|
-
|
|
56
45
|
async getLocationDisplayName() {
|
|
57
46
|
const envState = await navy.getState();
|
|
58
47
|
(0, _invariant.default)(!!envState, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
59
48
|
return envState.path;
|
|
60
49
|
},
|
|
61
|
-
|
|
62
50
|
async isDangling() {
|
|
63
51
|
const envState = await navy.getState();
|
|
64
|
-
|
|
65
52
|
if (!envState || !envState.path) {
|
|
66
53
|
return true;
|
|
67
54
|
}
|
|
68
|
-
|
|
69
55
|
try {
|
|
70
56
|
await _fs.default.statAsync(envState.path);
|
|
71
57
|
} catch (ex) {
|
|
72
58
|
return true;
|
|
73
59
|
}
|
|
74
|
-
|
|
75
60
|
return false;
|
|
76
61
|
}
|
|
77
|
-
|
|
78
62
|
};
|
|
63
|
+
return provider;
|
|
79
64
|
}
|
|
80
|
-
|
|
81
65
|
createFileSystemConfigProvider.importCliOptions = [];
|
|
82
|
-
|
|
83
66
|
createFileSystemConfigProvider.getImportOptionsForCLI = async opts => {
|
|
84
67
|
const hasValidComposeConfig = await cwdHasValidDockerComposeConfig();
|
|
85
68
|
(0, _invariant.default)(hasValidComposeConfig, "NO_DOCKER_COMPOSE_FILE: No docker-compose.yml (or valid Docker Compose config) found");
|
|
@@ -88,5 +71,4 @@ createFileSystemConfigProvider.getImportOptionsForCLI = async opts => {
|
|
|
88
71
|
path: process.cwd()
|
|
89
72
|
};
|
|
90
73
|
};
|
|
91
|
-
|
|
92
74
|
module.exports = exports.default;
|
|
@@ -0,0 +1,226 @@
|
|
|
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 _fs = require("fs");
|
|
7
|
+
var _child_process = _interopRequireDefault(require("child_process"));
|
|
8
|
+
var _fs2 = _interopRequireDefault(require("../../../util/fs"));
|
|
9
|
+
var _index = _interopRequireDefault(require("../index"));
|
|
10
|
+
/* eslint-env mocha */
|
|
11
|
+
|
|
12
|
+
function makeNavy({
|
|
13
|
+
name = 'env',
|
|
14
|
+
state = null
|
|
15
|
+
} = {}) {
|
|
16
|
+
return {
|
|
17
|
+
name,
|
|
18
|
+
getState: _sinon.default.stub().resolves(state)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
describe('npm config provider', function () {
|
|
22
|
+
let sandbox;
|
|
23
|
+
let originalHome;
|
|
24
|
+
beforeEach(function () {
|
|
25
|
+
sandbox = _sinon.default.createSandbox();
|
|
26
|
+
originalHome = process.env.HOME;
|
|
27
|
+
process.env.HOME = '/home/test';
|
|
28
|
+
});
|
|
29
|
+
afterEach(function () {
|
|
30
|
+
sandbox.restore();
|
|
31
|
+
if (originalHome === undefined) {
|
|
32
|
+
delete process.env.HOME;
|
|
33
|
+
} else {
|
|
34
|
+
process.env.HOME = originalHome;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
describe('getNavyPath', function () {
|
|
38
|
+
it('should return the resolved module path when the package is installed', async function () {
|
|
39
|
+
const provider = (0, _index.default)(makeNavy({
|
|
40
|
+
state: {
|
|
41
|
+
npmPackage: 'my-config'
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
sandbox.stub(_fs2.default, 'accessSync');
|
|
45
|
+
const result = await provider.getNavyPath();
|
|
46
|
+
(0, _chai.expect)(result).to.contain('node_modules');
|
|
47
|
+
(0, _chai.expect)(result).to.contain('my-config');
|
|
48
|
+
});
|
|
49
|
+
it('should throw STATE_NONEXISTANT when state is missing', async function () {
|
|
50
|
+
const provider = (0, _index.default)(makeNavy({
|
|
51
|
+
state: null
|
|
52
|
+
}));
|
|
53
|
+
let caught;
|
|
54
|
+
try {
|
|
55
|
+
await provider.getNavyPath();
|
|
56
|
+
} catch (e) {
|
|
57
|
+
caught = e;
|
|
58
|
+
}
|
|
59
|
+
(0, _chai.expect)(caught.message).to.match(/STATE_NONEXISTANT/);
|
|
60
|
+
});
|
|
61
|
+
it('should throw NPM_PROVIDER_REQUIRES_PACKAGE when state has no npmPackage', async function () {
|
|
62
|
+
const provider = (0, _index.default)(makeNavy({
|
|
63
|
+
state: {}
|
|
64
|
+
}));
|
|
65
|
+
let caught;
|
|
66
|
+
try {
|
|
67
|
+
await provider.getNavyPath();
|
|
68
|
+
} catch (e) {
|
|
69
|
+
caught = e;
|
|
70
|
+
}
|
|
71
|
+
(0, _chai.expect)(caught.message).to.match(/NPM_PROVIDER_REQUIRES_PACKAGE/);
|
|
72
|
+
});
|
|
73
|
+
it('should throw when accessSync fails', async function () {
|
|
74
|
+
const provider = (0, _index.default)(makeNavy({
|
|
75
|
+
state: {
|
|
76
|
+
npmPackage: 'missing'
|
|
77
|
+
}
|
|
78
|
+
}));
|
|
79
|
+
sandbox.stub(_fs2.default, 'accessSync').throws(new Error('ENOENT'));
|
|
80
|
+
let caught;
|
|
81
|
+
try {
|
|
82
|
+
await provider.getNavyPath();
|
|
83
|
+
} catch (e) {
|
|
84
|
+
caught = e;
|
|
85
|
+
}
|
|
86
|
+
(0, _chai.expect)(caught).to.be.an('error');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('getNavyFilePath', function () {
|
|
90
|
+
it('should return <navyPath>/Navyfile.js', async function () {
|
|
91
|
+
const provider = (0, _index.default)(makeNavy({
|
|
92
|
+
state: {
|
|
93
|
+
npmPackage: 'my-config'
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
sandbox.stub(_fs2.default, 'accessSync');
|
|
97
|
+
const filePath = await provider.getNavyFilePath();
|
|
98
|
+
(0, _chai.expect)(filePath).to.match(/my-config\/Navyfile\.js$/);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('refreshConfig', function () {
|
|
102
|
+
it('should reinstall the package via npm and return true', async function () {
|
|
103
|
+
const provider = (0, _index.default)(makeNavy({
|
|
104
|
+
state: {
|
|
105
|
+
npmPackage: 'pkg'
|
|
106
|
+
}
|
|
107
|
+
}));
|
|
108
|
+
sandbox.stub(_fs.promises, 'mkdir').resolves();
|
|
109
|
+
const execSync = sandbox.stub(_child_process.default, 'execSync').returns('');
|
|
110
|
+
(0, _chai.expect)(await provider.refreshConfig()).to.equal(true);
|
|
111
|
+
const calls = execSync.getCalls().map(c => c.args[0]);
|
|
112
|
+
(0, _chai.expect)(calls[0]).to.match(/npm info pkg name/);
|
|
113
|
+
(0, _chai.expect)(calls[1]).to.match(/npm i pkg/);
|
|
114
|
+
});
|
|
115
|
+
it('should throw STATE_NONEXISTANT when state is missing', async function () {
|
|
116
|
+
const provider = (0, _index.default)(makeNavy({
|
|
117
|
+
state: null
|
|
118
|
+
}));
|
|
119
|
+
let caught;
|
|
120
|
+
try {
|
|
121
|
+
await provider.refreshConfig();
|
|
122
|
+
} catch (e) {
|
|
123
|
+
caught = e;
|
|
124
|
+
}
|
|
125
|
+
(0, _chai.expect)(caught.message).to.match(/STATE_NONEXISTANT/);
|
|
126
|
+
});
|
|
127
|
+
it('should throw NPM_PROVIDER_REQUIRES_PACKAGE when no npmPackage in state', async function () {
|
|
128
|
+
const provider = (0, _index.default)(makeNavy({
|
|
129
|
+
state: {}
|
|
130
|
+
}));
|
|
131
|
+
let caught;
|
|
132
|
+
try {
|
|
133
|
+
await provider.refreshConfig();
|
|
134
|
+
} catch (e) {
|
|
135
|
+
caught = e;
|
|
136
|
+
}
|
|
137
|
+
(0, _chai.expect)(caught.message).to.match(/NPM_PROVIDER_REQUIRES_PACKAGE/);
|
|
138
|
+
});
|
|
139
|
+
it('should throw a friendly error when npm info fails', async function () {
|
|
140
|
+
const provider = (0, _index.default)(makeNavy({
|
|
141
|
+
state: {
|
|
142
|
+
npmPackage: 'unknown-pkg'
|
|
143
|
+
}
|
|
144
|
+
}));
|
|
145
|
+
sandbox.stub(_fs.promises, 'mkdir').resolves();
|
|
146
|
+
sandbox.stub(_child_process.default, 'execSync').callsFake(cmd => {
|
|
147
|
+
if (cmd.startsWith('npm info')) throw new Error('not found');
|
|
148
|
+
return '';
|
|
149
|
+
});
|
|
150
|
+
let caught;
|
|
151
|
+
try {
|
|
152
|
+
await provider.refreshConfig();
|
|
153
|
+
} catch (e) {
|
|
154
|
+
caught = e;
|
|
155
|
+
}
|
|
156
|
+
(0, _chai.expect)(caught.message).to.contain('Package "unknown-pkg" not found or unreachable');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe('getLocationDisplayName', function () {
|
|
160
|
+
it('should return the npmPackage from state', async function () {
|
|
161
|
+
const provider = (0, _index.default)(makeNavy({
|
|
162
|
+
state: {
|
|
163
|
+
npmPackage: 'pkg'
|
|
164
|
+
}
|
|
165
|
+
}));
|
|
166
|
+
(0, _chai.expect)(await provider.getLocationDisplayName()).to.equal('pkg');
|
|
167
|
+
});
|
|
168
|
+
it('should throw STATE_NONEXISTANT when state is missing', async function () {
|
|
169
|
+
const provider = (0, _index.default)(makeNavy({
|
|
170
|
+
state: null
|
|
171
|
+
}));
|
|
172
|
+
let caught;
|
|
173
|
+
try {
|
|
174
|
+
await provider.getLocationDisplayName();
|
|
175
|
+
} catch (e) {
|
|
176
|
+
caught = e;
|
|
177
|
+
}
|
|
178
|
+
(0, _chai.expect)(caught.message).to.match(/STATE_NONEXISTANT/);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
describe('isDangling', function () {
|
|
182
|
+
it('should return true when state is null', async function () {
|
|
183
|
+
const provider = (0, _index.default)(makeNavy({
|
|
184
|
+
state: null
|
|
185
|
+
}));
|
|
186
|
+
(0, _chai.expect)(await provider.isDangling()).to.equal(true);
|
|
187
|
+
});
|
|
188
|
+
it('should return true when state has no npmPackage', async function () {
|
|
189
|
+
const provider = (0, _index.default)(makeNavy({
|
|
190
|
+
state: {}
|
|
191
|
+
}));
|
|
192
|
+
(0, _chai.expect)(await provider.isDangling()).to.equal(true);
|
|
193
|
+
});
|
|
194
|
+
it('should return false when state has an npmPackage', async function () {
|
|
195
|
+
const provider = (0, _index.default)(makeNavy({
|
|
196
|
+
state: {
|
|
197
|
+
npmPackage: 'pkg'
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
(0, _chai.expect)(await provider.isDangling()).to.equal(false);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
describe('importCliOptions', function () {
|
|
204
|
+
it('should advertise the --npm-package CLI option', function () {
|
|
205
|
+
(0, _chai.expect)(_index.default.importCliOptions).to.have.lengthOf(1);
|
|
206
|
+
(0, _chai.expect)(_index.default.importCliOptions[0][0]).to.match(/--npm-package/);
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
describe('getImportOptionsForCLI', function () {
|
|
210
|
+
it('should install the package and return npm provider config when --npm-package is provided', async function () {
|
|
211
|
+
sandbox.stub(_fs.promises, 'mkdir').resolves();
|
|
212
|
+
sandbox.stub(_child_process.default, 'execSync').returns('');
|
|
213
|
+
const result = await _index.default.getImportOptionsForCLI({
|
|
214
|
+
npmPackage: 'my-pkg'
|
|
215
|
+
});
|
|
216
|
+
(0, _chai.expect)(result).to.eql({
|
|
217
|
+
configProvider: 'npm',
|
|
218
|
+
npmPackage: 'my-pkg'
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
it('should return undefined when --npm-package is not provided', async function () {
|
|
222
|
+
const result = await _index.default.getImportOptionsForCLI({});
|
|
223
|
+
(0, _chai.expect)(result).to.equal(undefined);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _chai = require("chai");
|
|
4
|
-
|
|
5
4
|
var _util = require("../util");
|
|
6
|
-
|
|
7
5
|
/* eslint-env mocha */
|
|
6
|
+
|
|
8
7
|
describe('npm config provider', function () {
|
|
9
8
|
describe('pathToModule', function () {
|
|
10
9
|
it('should return the correct path to the module', function () {
|
|
@@ -1,69 +1,51 @@
|
|
|
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.default = createNpmConfigProvider;
|
|
9
|
-
|
|
10
8
|
var _path = _interopRequireDefault(require("path"));
|
|
11
|
-
|
|
12
9
|
var _child_process = require("child_process");
|
|
13
|
-
|
|
14
10
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
15
|
-
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
var _fs = _interopRequireDefault(require("../../util/fs"));
|
|
19
|
-
|
|
11
|
+
var _fs = require("fs");
|
|
12
|
+
var _fs2 = _interopRequireDefault(require("../../util/fs"));
|
|
20
13
|
var _state = require("../../navy/state");
|
|
21
|
-
|
|
22
14
|
var _util = require("./util");
|
|
23
|
-
|
|
24
|
-
const mkdirp = _bluebird.default.promisify(require('mkdirp'));
|
|
25
|
-
|
|
26
15
|
const npmContext = _path.default.join((0, _state.pathToNavyRoot)(), 'npm');
|
|
27
|
-
|
|
28
16
|
const nodeModulesPath = _path.default.join(npmContext, 'node_modules');
|
|
29
|
-
|
|
30
17
|
async function tryAndInstall(pkgName) {
|
|
31
|
-
await
|
|
32
|
-
|
|
18
|
+
await _fs.promises.mkdir(nodeModulesPath, {
|
|
19
|
+
recursive: true
|
|
20
|
+
});
|
|
33
21
|
try {
|
|
34
|
-
// $FlowIgnore some weird bug with execSync
|
|
35
22
|
(0, _child_process.execSync)(`npm info ${pkgName} name`, {
|
|
36
23
|
stdio: 'ignore'
|
|
37
24
|
});
|
|
38
25
|
} catch (ex) {
|
|
39
26
|
throw new Error(`Package "${pkgName}" not found or unreachable`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
}
|
|
43
28
|
(0, _child_process.execSync)(`npm i ${pkgName}`, {
|
|
44
29
|
stdio: 'inherit',
|
|
45
30
|
cwd: npmContext
|
|
46
31
|
});
|
|
47
32
|
}
|
|
48
|
-
|
|
49
33
|
function createNpmConfigProvider(navy) {
|
|
50
|
-
|
|
34
|
+
const provider = {
|
|
51
35
|
async getNavyPath() {
|
|
52
36
|
const envState = await navy.getState();
|
|
53
37
|
(0, _invariant.default)(!!envState, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
54
38
|
(0, _invariant.default)(!!envState.npmPackage, "NPM_PROVIDER_REQUIRES_PACKAGE: NPM config provider requires an NPM package for %s", navy.name);
|
|
55
39
|
const navyPath = await (0, _util.pathToModule)(nodeModulesPath, envState.npmPackage);
|
|
56
|
-
|
|
57
|
-
_fs.default.accessSync(navyPath); // see if path exists
|
|
58
|
-
|
|
40
|
+
_fs2.default.accessSync(navyPath); // see if path exists
|
|
59
41
|
|
|
60
42
|
return navyPath;
|
|
61
43
|
},
|
|
62
|
-
|
|
63
44
|
async getNavyFilePath() {
|
|
64
|
-
|
|
45
|
+
const navyPath = await provider.getNavyPath();
|
|
46
|
+
(0, _invariant.default)(navyPath, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
47
|
+
return _path.default.join(navyPath, 'Navyfile.js');
|
|
65
48
|
},
|
|
66
|
-
|
|
67
49
|
async refreshConfig() {
|
|
68
50
|
const envState = await navy.getState();
|
|
69
51
|
(0, _invariant.default)(!!envState, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
@@ -71,23 +53,19 @@ function createNpmConfigProvider(navy) {
|
|
|
71
53
|
await tryAndInstall(envState.npmPackage);
|
|
72
54
|
return true;
|
|
73
55
|
},
|
|
74
|
-
|
|
75
56
|
async getLocationDisplayName() {
|
|
76
57
|
const envState = await navy.getState();
|
|
77
58
|
(0, _invariant.default)(!!envState, "STATE_NONEXISTANT: State doesn't exist for navy %s", navy.name);
|
|
78
59
|
return envState.npmPackage;
|
|
79
60
|
},
|
|
80
|
-
|
|
81
61
|
async isDangling() {
|
|
82
62
|
const envState = await navy.getState();
|
|
83
63
|
return !envState || !envState.npmPackage;
|
|
84
64
|
}
|
|
85
|
-
|
|
86
65
|
};
|
|
66
|
+
return provider;
|
|
87
67
|
}
|
|
88
|
-
|
|
89
68
|
createNpmConfigProvider.importCliOptions = [['--npm-package [package]', 'set the NPM package to use for docker compose config']];
|
|
90
|
-
|
|
91
69
|
createNpmConfigProvider.getImportOptionsForCLI = async opts => {
|
|
92
70
|
if (opts.npmPackage) {
|
|
93
71
|
await tryAndInstall(opts.npmPackage);
|
|
@@ -97,5 +75,4 @@ createNpmConfigProvider.getImportOptionsForCLI = async opts => {
|
|
|
97
75
|
};
|
|
98
76
|
}
|
|
99
77
|
};
|
|
100
|
-
|
|
101
78
|
module.exports = exports.default;
|
|
@@ -1,14 +1,11 @@
|
|
|
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.pathToModule = pathToModule;
|
|
9
|
-
|
|
10
8
|
var _path = _interopRequireDefault(require("path"));
|
|
11
|
-
|
|
12
9
|
function pathToModule(nodeModulesPath, pkgName) {
|
|
13
10
|
const pkgNameWithNoTags = pkgName.lastIndexOf('@') !== 0 && pkgName.lastIndexOf('@') !== -1 ? pkgName.substring(0, pkgName.lastIndexOf('@')) : pkgName;
|
|
14
11
|
return _path.default.join(nodeModulesPath, pkgNameWithNoTags);
|
package/lib/config.js
CHANGED
|
@@ -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
|
});
|
|
@@ -10,60 +9,46 @@ exports.getConfig = getConfig;
|
|
|
10
9
|
exports.getConfigDir = getConfigDir;
|
|
11
10
|
exports.getConfigPath = getConfigPath;
|
|
12
11
|
exports.setConfig = setConfig;
|
|
13
|
-
|
|
14
12
|
var _path = _interopRequireDefault(require("path"));
|
|
15
|
-
|
|
16
13
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
17
|
-
|
|
18
14
|
var _fs = _interopRequireWildcard(require("fs"));
|
|
19
|
-
|
|
20
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
|
-
|
|
22
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
|
-
|
|
24
|
-
// $FlowIgnore
|
|
15
|
+
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); }
|
|
25
16
|
const DEFAULT_ENVIRONMENT_NAME = 'dev';
|
|
26
|
-
const DEFAULT_TLS_ROOT_CA_DIR = `${getConfigDir()}/tls-root-ca`;
|
|
27
|
-
exports.DEFAULT_TLS_ROOT_CA_DIR = DEFAULT_TLS_ROOT_CA_DIR;
|
|
17
|
+
const DEFAULT_TLS_ROOT_CA_DIR = exports.DEFAULT_TLS_ROOT_CA_DIR = `${getConfigDir()}/tls-root-ca`;
|
|
28
18
|
const DEFAULT_CONFIG = {
|
|
29
19
|
defaultNavy: DEFAULT_ENVIRONMENT_NAME,
|
|
30
20
|
externalIP: null,
|
|
31
21
|
tlsRootCaDir: DEFAULT_TLS_ROOT_CA_DIR
|
|
32
22
|
};
|
|
33
23
|
let _config = null;
|
|
34
|
-
|
|
35
24
|
function getConfigDir() {
|
|
36
25
|
const home = process.env.HOME;
|
|
37
26
|
(0, _invariant.default)(home, "NO_HOME_DIRECTORY: No home directory available");
|
|
38
27
|
return _path.default.join(home, '.navy');
|
|
39
28
|
}
|
|
40
|
-
|
|
41
29
|
function getConfigPath() {
|
|
42
30
|
const configDir = getConfigDir();
|
|
43
31
|
return _path.default.join(configDir, 'config.json');
|
|
44
32
|
}
|
|
45
|
-
|
|
46
33
|
function getConfig() {
|
|
47
34
|
if (_config) {
|
|
48
35
|
return _config;
|
|
49
36
|
}
|
|
50
|
-
|
|
51
37
|
try {
|
|
52
38
|
const file = _fs.default.readFileSync(getConfigPath(), 'utf8');
|
|
53
|
-
|
|
54
39
|
_config = JSON.parse(file);
|
|
55
40
|
return _config;
|
|
56
41
|
} catch (ex) {
|
|
57
42
|
return DEFAULT_CONFIG;
|
|
58
43
|
}
|
|
59
44
|
}
|
|
60
|
-
|
|
61
45
|
async function setConfig(config) {
|
|
62
46
|
if (config == null) config = DEFAULT_CONFIG;
|
|
63
47
|
await _fs.promises.mkdir(_path.default.dirname(getConfigPath()), {
|
|
64
48
|
recursive: true
|
|
65
49
|
});
|
|
66
|
-
await _fs.promises.writeFile(getConfigPath(), JSON.stringify(config, null, 2));
|
|
50
|
+
await _fs.promises.writeFile(getConfigPath(), JSON.stringify(config, null, 2));
|
|
67
51
|
|
|
52
|
+
// trash cached config
|
|
68
53
|
_config = null;
|
|
69
54
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _chai = require("chai");
|
|
4
|
+
var _containerImage = require("../container-image");
|
|
5
|
+
/* eslint-env mocha */
|
|
6
|
+
|
|
7
|
+
describe('container-image', function () {
|
|
8
|
+
describe('constants', function () {
|
|
9
|
+
it('should expose the default registry hostname', function () {
|
|
10
|
+
(0, _chai.expect)(_containerImage.DEFAULT_REGISTRY).to.equal('registry-1.docker.io');
|
|
11
|
+
});
|
|
12
|
+
it('should expose the docker config.json auth URL', function () {
|
|
13
|
+
(0, _chai.expect)(_containerImage.DEFAULT_REGISTRY_AUTH).to.equal('https://index.docker.io/v1/');
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe('getImageFromImageWithTag', function () {
|
|
17
|
+
it('should strip the tag from a registry/org/image:tag string', function () {
|
|
18
|
+
(0, _chai.expect)((0, _containerImage.getImageFromImageWithTag)('someregistry.com/some/image:latest')).to.equal('someregistry.com/some/image');
|
|
19
|
+
});
|
|
20
|
+
it('should return the image unchanged when it has slashes but no tag', function () {
|
|
21
|
+
(0, _chai.expect)((0, _containerImage.getImageFromImageWithTag)('someregistry.com/some/image')).to.equal('someregistry.com/some/image');
|
|
22
|
+
});
|
|
23
|
+
it('should strip the tag from a single-segment image:tag string', function () {
|
|
24
|
+
(0, _chai.expect)((0, _containerImage.getImageFromImageWithTag)('node:18')).to.equal('node');
|
|
25
|
+
});
|
|
26
|
+
it('should return a single-segment image unchanged when it has no tag', function () {
|
|
27
|
+
(0, _chai.expect)((0, _containerImage.getImageFromImageWithTag)('node')).to.equal('node');
|
|
28
|
+
});
|
|
29
|
+
it('should not be confused by a colon in the registry port (no tag)', function () {
|
|
30
|
+
(0, _chai.expect)((0, _containerImage.getImageFromImageWithTag)('myregistry.local:5000/foo/bar')).to.equal('myregistry.local:5000/foo/bar');
|
|
31
|
+
});
|
|
32
|
+
it('should strip the tag while preserving the registry port', function () {
|
|
33
|
+
(0, _chai.expect)((0, _containerImage.getImageFromImageWithTag)('myregistry.local:5000/foo/bar:1.0')).to.equal('myregistry.local:5000/foo/bar');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('getTagFromImageWithTag', function () {
|
|
37
|
+
it('should extract the tag from a registry/org/image:tag string', function () {
|
|
38
|
+
(0, _chai.expect)((0, _containerImage.getTagFromImageWithTag)('someregistry.com/some/image:1.2.3')).to.equal('1.2.3');
|
|
39
|
+
});
|
|
40
|
+
it('should default to "latest" when slashes exist but no tag', function () {
|
|
41
|
+
(0, _chai.expect)((0, _containerImage.getTagFromImageWithTag)('someregistry.com/some/image')).to.equal('latest');
|
|
42
|
+
});
|
|
43
|
+
it('should extract the tag from a single-segment image:tag', function () {
|
|
44
|
+
(0, _chai.expect)((0, _containerImage.getTagFromImageWithTag)('node:18-alpine')).to.equal('18-alpine');
|
|
45
|
+
});
|
|
46
|
+
it('should default to "latest" for a single-segment image with no tag', function () {
|
|
47
|
+
(0, _chai.expect)((0, _containerImage.getTagFromImageWithTag)('node')).to.equal('latest');
|
|
48
|
+
});
|
|
49
|
+
it('should not treat the registry port colon as a tag', function () {
|
|
50
|
+
(0, _chai.expect)((0, _containerImage.getTagFromImageWithTag)('myregistry.local:5000/foo/bar')).to.equal('latest');
|
|
51
|
+
});
|
|
52
|
+
it('should extract the tag with a registry port present', function () {
|
|
53
|
+
(0, _chai.expect)((0, _containerImage.getTagFromImageWithTag)('myregistry.local:5000/foo/bar:1.0')).to.equal('1.0');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe('getRegistryFromImage', function () {
|
|
57
|
+
it('should return the registry from a registry/org/image string', function () {
|
|
58
|
+
(0, _chai.expect)((0, _containerImage.getRegistryFromImage)('someregistry.com/some/image')).to.equal('someregistry.com');
|
|
59
|
+
});
|
|
60
|
+
it('should fall back to the default registry when no registry is present', function () {
|
|
61
|
+
(0, _chai.expect)((0, _containerImage.getRegistryFromImage)('library/node')).to.equal(_containerImage.DEFAULT_REGISTRY);
|
|
62
|
+
});
|
|
63
|
+
it('should fall back to default for an unprefixed image', function () {
|
|
64
|
+
(0, _chai.expect)((0, _containerImage.getRegistryFromImage)('node')).to.equal(_containerImage.DEFAULT_REGISTRY);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('getRepositoryFromImage', function () {
|
|
68
|
+
it('should prefix a single-segment image with library/', function () {
|
|
69
|
+
(0, _chai.expect)((0, _containerImage.getRepositoryFromImage)('node')).to.equal('library/node');
|
|
70
|
+
});
|
|
71
|
+
it('should strip the registry from a 3-segment image', function () {
|
|
72
|
+
(0, _chai.expect)((0, _containerImage.getRepositoryFromImage)('someregistry.com/some/image')).to.equal('some/image');
|
|
73
|
+
});
|
|
74
|
+
it('should return a 2-segment image unchanged', function () {
|
|
75
|
+
(0, _chai.expect)((0, _containerImage.getRepositoryFromImage)('library/node')).to.equal('library/node');
|
|
76
|
+
});
|
|
77
|
+
it('should return a 4+-segment image unchanged', function () {
|
|
78
|
+
(0, _chai.expect)((0, _containerImage.getRepositoryFromImage)('host/a/b/c')).to.equal('host/a/b/c');
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _chai = require("chai");
|
|
4
|
+
var _ociApiSpecification = require("../oci-api-specification");
|
|
5
|
+
/* eslint-env mocha */
|
|
6
|
+
|
|
7
|
+
describe('oci-api-specification', function () {
|
|
8
|
+
describe('restSpecification.operation', function () {
|
|
9
|
+
it('should build a v2 endpoint URL for the given registry and endpoint', function () {
|
|
10
|
+
(0, _chai.expect)(_ociApiSpecification.restSpecification.operation('registry-1.docker.io', 'library/node/manifests/latest')).to.equal('https://registry-1.docker.io/v2/library/node/manifests/latest');
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
describe('restSpecification.getManifest', function () {
|
|
14
|
+
it('should produce <repository>/manifests/<tag>', function () {
|
|
15
|
+
(0, _chai.expect)(_ociApiSpecification.restSpecification.getManifest('library/node', 'lts')).to.equal('library/node/manifests/lts');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('MEDIA_TYPES', function () {
|
|
19
|
+
it('should expose the docker fat manifest list media type', function () {
|
|
20
|
+
(0, _chai.expect)(_ociApiSpecification.MEDIA_TYPES.FAT_MANIFEST).to.equal('application/vnd.docker.distribution.manifest.list.v2+json');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
});
|