navy 7.0.0-alpha.1 → 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.
|
@@ -27,6 +27,7 @@ describe('cli/program', function () {
|
|
|
27
27
|
actionsByCommand = {};
|
|
28
28
|
helpHandlersByCommand = {};
|
|
29
29
|
fakeProgram = {
|
|
30
|
+
option: sandbox.stub().returnsThis(),
|
|
30
31
|
command(spec) {
|
|
31
32
|
const name = spec.split(' ')[0];
|
|
32
33
|
const cmd = {
|
|
@@ -150,6 +151,10 @@ describe('cli/program', function () {
|
|
|
150
151
|
});
|
|
151
152
|
(0, _chai.expect)(consoleLogStub.called).to.equal(true);
|
|
152
153
|
});
|
|
154
|
+
it('should register a global -e, --navy option on the root program', function () {
|
|
155
|
+
loadModule();
|
|
156
|
+
(0, _chai.expect)(fakeProgram.option.calledWith('-e, --navy [env]', _sinon.default.match.string, 'dev')).to.equal(true);
|
|
157
|
+
});
|
|
153
158
|
});
|
|
154
159
|
describe('lazyRequire wrapped action', function () {
|
|
155
160
|
it('should pass through arguments to the underlying module', async function () {
|
|
@@ -332,6 +337,18 @@ describe('cli/program', function () {
|
|
|
332
337
|
(0, _chai.expect)(navyStub.start.firstCall.args[0]).to.eql(['web', 'api']);
|
|
333
338
|
(0, _chai.expect)(navyStub.ensurePluginsLoaded.calledOnce).to.equal(true);
|
|
334
339
|
});
|
|
340
|
+
it('should merge optsWithGlobals so global navy is used when Commander passes the command', async function () {
|
|
341
|
+
navyStub.start = sandbox.stub().resolves();
|
|
342
|
+
const fakeCommand = {
|
|
343
|
+
optsWithGlobals: () => ({
|
|
344
|
+
navy: 'from-global'
|
|
345
|
+
})
|
|
346
|
+
};
|
|
347
|
+
await actionsByCommand.start(['web'], {
|
|
348
|
+
navy: 'subcommand-default'
|
|
349
|
+
}, fakeCommand);
|
|
350
|
+
(0, _chai.expect)(getNavyStub.firstCall.args[0]).to.equal('from-global');
|
|
351
|
+
});
|
|
335
352
|
it('should pass undefined when called with an empty service list', async function () {
|
|
336
353
|
navyStub.start = sandbox.stub().resolves();
|
|
337
354
|
await actionsByCommand.start([], {
|
|
@@ -436,6 +453,7 @@ describe('cli/program', function () {
|
|
|
436
453
|
function createCapturingProgram() {
|
|
437
454
|
capturedActions = {};
|
|
438
455
|
return {
|
|
456
|
+
option: sandbox.stub().returnsThis(),
|
|
439
457
|
command(spec) {
|
|
440
458
|
const name = spec.split(' ')[0];
|
|
441
459
|
const cmd = {
|
package/lib/cli/program.js
CHANGED
|
@@ -11,6 +11,7 @@ var _errors = require("../errors");
|
|
|
11
11
|
var _config = require("../config");
|
|
12
12
|
var _driverLogging = require("../driver-logging");
|
|
13
13
|
var _configProvider = require("../config-provider");
|
|
14
|
+
var _mergeActionOptions = require("./util/merge-action-options");
|
|
14
15
|
const loadingLabelMap = {
|
|
15
16
|
destroy: 'Destroying services...',
|
|
16
17
|
start: 'Starting services...',
|
|
@@ -28,6 +29,23 @@ const loadingLabelMap = {
|
|
|
28
29
|
function removeFirstLineFromStackTrace(stack) {
|
|
29
30
|
return stack?.split('\n')?.slice(1)?.join('\n');
|
|
30
31
|
}
|
|
32
|
+
function normaliseLazyRequireArgs(args) {
|
|
33
|
+
if (args.length === 0) return args;
|
|
34
|
+
const last = args[args.length - 1];
|
|
35
|
+
if (!last || typeof last.optsWithGlobals !== 'function') {
|
|
36
|
+
return args;
|
|
37
|
+
}
|
|
38
|
+
const command = last;
|
|
39
|
+
const rest = args.slice(0, -1);
|
|
40
|
+
if (rest.length === 0) {
|
|
41
|
+
return rest;
|
|
42
|
+
}
|
|
43
|
+
const lastOpt = rest[rest.length - 1];
|
|
44
|
+
if (lastOpt && typeof lastOpt === 'object' && !Array.isArray(lastOpt)) {
|
|
45
|
+
return [...rest.slice(0, -1), (0, _mergeActionOptions.mergeActionOptions)(lastOpt, command)];
|
|
46
|
+
}
|
|
47
|
+
return rest;
|
|
48
|
+
}
|
|
31
49
|
function wrapper(res) {
|
|
32
50
|
if (res.catch) {
|
|
33
51
|
res.catch(ex => {
|
|
@@ -62,11 +80,21 @@ function basicCliWrapper(fnName, wrapperOpts = {}) {
|
|
|
62
80
|
} = require('../navy');
|
|
63
81
|
|
|
64
82
|
// commander v12 invokes action handlers with a trailing Command instance
|
|
65
|
-
// appended after the parsed options. Strip it
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
// appended after the parsed options. Strip it and merge global options
|
|
84
|
+
// (e.g. `navy -e dev start`) into the opts object.
|
|
85
|
+
let command = null;
|
|
86
|
+
if (args.length > 0) {
|
|
87
|
+
const last = args[args.length - 1];
|
|
88
|
+
if (last && typeof last.optsWithGlobals === 'function') {
|
|
89
|
+
command = last;
|
|
90
|
+
args = args.slice(0, -1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
let opts = args.length === 0 ? maybeServices : args[args.length - 1];
|
|
69
94
|
const otherArgs = args.slice(0, args.length - 1);
|
|
95
|
+
if (command && opts && typeof opts === 'object' && !Array.isArray(opts)) {
|
|
96
|
+
opts = (0, _mergeActionOptions.mergeActionOptions)(opts, command);
|
|
97
|
+
}
|
|
70
98
|
const envName = opts.navy;
|
|
71
99
|
if (wrapperOpts.serviceBasedAlias && maybeServices.length) {
|
|
72
100
|
console.log(`This command should not be called with a list of services. calling '${wrapperOpts.serviceBasedAlias}' instead`);
|
|
@@ -102,10 +130,12 @@ function basicCliWrapper(fnName, wrapperOpts = {}) {
|
|
|
102
130
|
function lazyRequire(path) {
|
|
103
131
|
return function (...args) {
|
|
104
132
|
const mod = require(path);
|
|
105
|
-
|
|
133
|
+
const normalised = normaliseLazyRequireArgs(args);
|
|
134
|
+
return wrapper((mod.default || mod)(...normalised));
|
|
106
135
|
};
|
|
107
136
|
}
|
|
108
137
|
const defaultNavy = process.env.NAVY_NAME || (0, _config.getConfig)().defaultNavy;
|
|
138
|
+
_commander.program.option('-e, --navy [env]', `set the navy name to be used [${defaultNavy}]`, defaultNavy);
|
|
109
139
|
const importCommand = _commander.program.command('import').option('-e, --navy [env]', `set the navy name to be used [${defaultNavy}]`, defaultNavy).description('Imports docker compose configuration from the current working directory and initialises a new navy').action(lazyRequire('./import'));
|
|
110
140
|
(0, _configProvider.getImportCommandLineOptions)().forEach(opt => importCommand.option(...opt));
|
|
111
141
|
_commander.program.command('launch [services...]').option('-e, --navy [env]', `set the navy name to be used [${defaultNavy}]`, defaultNavy).description('Launches the given services in a navy').action(lazyRequire('./launch')).on('--help', () => console.log(`
|
|
@@ -0,0 +1,47 @@
|
|
|
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 _mergeActionOptions = require("../merge-action-options");
|
|
7
|
+
/* eslint-env mocha */
|
|
8
|
+
|
|
9
|
+
describe('cli/util/merge-action-options', function () {
|
|
10
|
+
it('should return parsed opts when command is missing', function () {
|
|
11
|
+
const opts = {
|
|
12
|
+
navy: 'dev'
|
|
13
|
+
};
|
|
14
|
+
(0, _chai.expect)((0, _mergeActionOptions.mergeActionOptions)(opts, null)).to.equal(opts);
|
|
15
|
+
});
|
|
16
|
+
it('should return parsed opts when optsWithGlobals is missing', function () {
|
|
17
|
+
const opts = {
|
|
18
|
+
navy: 'dev'
|
|
19
|
+
};
|
|
20
|
+
(0, _chai.expect)((0, _mergeActionOptions.mergeActionOptions)(opts, {})).to.equal(opts);
|
|
21
|
+
});
|
|
22
|
+
it('should merge optsWithGlobals so global navy wins over subcommand defaults', function () {
|
|
23
|
+
const command = {
|
|
24
|
+
optsWithGlobals: () => ({
|
|
25
|
+
navy: 'dev',
|
|
26
|
+
json: true
|
|
27
|
+
})
|
|
28
|
+
};
|
|
29
|
+
const merged = (0, _mergeActionOptions.mergeActionOptions)({
|
|
30
|
+
navy: 'default',
|
|
31
|
+
json: false
|
|
32
|
+
}, command);
|
|
33
|
+
(0, _chai.expect)(merged.navy).to.equal('dev');
|
|
34
|
+
(0, _chai.expect)(merged.json).to.equal(true);
|
|
35
|
+
});
|
|
36
|
+
it('should call optsWithGlobals on the command', function () {
|
|
37
|
+
const spy = _sinon.default.stub().returns({
|
|
38
|
+
navy: 'x'
|
|
39
|
+
});
|
|
40
|
+
(0, _mergeActionOptions.mergeActionOptions)({
|
|
41
|
+
navy: 'y'
|
|
42
|
+
}, {
|
|
43
|
+
optsWithGlobals: spy
|
|
44
|
+
});
|
|
45
|
+
(0, _chai.expect)(spy.calledOnce).to.equal(true);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.mergeActionOptions = mergeActionOptions;
|
|
7
|
+
/**
|
|
8
|
+
* Merge Commander's per-command opts with inherited globals (e.g. `navy -e dev ps`).
|
|
9
|
+
* `optsWithGlobals()` is the combined view; spread it after local opts so globals
|
|
10
|
+
* override stale option defaults on the subcommand.
|
|
11
|
+
*/
|
|
12
|
+
function mergeActionOptions(parsedOpts, command) {
|
|
13
|
+
if (!command || typeof command.optsWithGlobals !== 'function') {
|
|
14
|
+
return parsedOpts;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
...parsedOpts,
|
|
18
|
+
...command.optsWithGlobals()
|
|
19
|
+
};
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "navy",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.2",
|
|
4
4
|
"description": "Quick and powerful development environments using Docker and Docker Compose",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -49,6 +49,5 @@
|
|
|
49
49
|
"resolve": "^1.20.0",
|
|
50
50
|
"strip-ansi": "^6.0.1",
|
|
51
51
|
"www-authenticate": "^0.6.3"
|
|
52
|
-
}
|
|
53
|
-
"gitHead": "c977d36ee1e962134aee34d5fa20071cd863a619"
|
|
52
|
+
}
|
|
54
53
|
}
|