@oclif/core 4.5.6 → 4.6.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.
- package/lib/help/docopts.js +15 -1
- package/lib/interfaces/parser.d.ts +5 -1
- package/lib/parser/validate.js +27 -0
- package/lib/util/cache-command.js +1 -0
- package/package.json +1 -1
package/lib/help/docopts.js
CHANGED
|
@@ -165,8 +165,22 @@ class DocOpts {
|
|
|
165
165
|
if (Array.isArray(flag.dependsOn)) {
|
|
166
166
|
this.combineElementsToFlag(elementMap, flag.name, flag.dependsOn, ' ');
|
|
167
167
|
}
|
|
168
|
+
let exclusive;
|
|
168
169
|
if (Array.isArray(flag.exclusive)) {
|
|
169
|
-
|
|
170
|
+
exclusive = new Set(flag.exclusive);
|
|
171
|
+
}
|
|
172
|
+
if (Array.isArray(flag.combinable)) {
|
|
173
|
+
const combinableFlags = new Set(flag.combinable);
|
|
174
|
+
exclusive ??= new Set();
|
|
175
|
+
for (const item of this.flagList) {
|
|
176
|
+
// each flag not in the "combinable" list, is equivalent to an "exclusive" flag
|
|
177
|
+
if (flag !== item && !combinableFlags.has(item.name)) {
|
|
178
|
+
exclusive.add(item.name);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (exclusive !== undefined && exclusive.size > 0) {
|
|
183
|
+
this.combineElementsToFlag(elementMap, flag.name, [...exclusive], ' | ');
|
|
170
184
|
}
|
|
171
185
|
}
|
|
172
186
|
// Since combineElementsToFlag deletes the references in this.flags when it combines
|
|
@@ -87,7 +87,7 @@ export type FlagRelationship = string | {
|
|
|
87
87
|
when: (flags: Record<string, unknown>) => Promise<boolean>;
|
|
88
88
|
};
|
|
89
89
|
export type Relationship = {
|
|
90
|
-
type: 'all' | 'some' | 'none';
|
|
90
|
+
type: 'all' | 'some' | 'none' | 'only';
|
|
91
91
|
flags: FlagRelationship[];
|
|
92
92
|
};
|
|
93
93
|
export type Deprecation = {
|
|
@@ -138,6 +138,10 @@ export type FlagProps = {
|
|
|
138
138
|
* List of flags that cannot be used with this flag.
|
|
139
139
|
*/
|
|
140
140
|
exclusive?: string[];
|
|
141
|
+
/**
|
|
142
|
+
* List of the only flags that can be used with this flag.
|
|
143
|
+
*/
|
|
144
|
+
combinable?: string[];
|
|
141
145
|
/**
|
|
142
146
|
* Exactly one of these flags must be provided.
|
|
143
147
|
*/
|
package/lib/parser/validate.js
CHANGED
|
@@ -57,6 +57,7 @@ async function validate(parse) {
|
|
|
57
57
|
...(flag.relationships ? validateRelationships(name, flag) : []),
|
|
58
58
|
...(flag.dependsOn ? [validateDependsOn(name, flag.dependsOn)] : []),
|
|
59
59
|
...(flag.exclusive ? [validateExclusive(name, flag.exclusive)] : []),
|
|
60
|
+
...(flag.combinable ? [validateCombinable(name, flag.combinable)] : []),
|
|
60
61
|
...(flag.exactlyOne ? [validateExactlyOne(name, flag.exactlyOne)] : []),
|
|
61
62
|
];
|
|
62
63
|
}
|
|
@@ -143,6 +144,29 @@ async function validate(parse) {
|
|
|
143
144
|
}
|
|
144
145
|
return { ...base, status: 'success' };
|
|
145
146
|
}
|
|
147
|
+
async function validateCombinable(name, flags) {
|
|
148
|
+
const base = { name, validationFn: 'validateCombinable' };
|
|
149
|
+
const combinableFlags = new Set(flags.map((flag) => (typeof flag === 'string' ? flag : flag.name)));
|
|
150
|
+
const resolved = await resolveFlags(flags);
|
|
151
|
+
for (const flag of Object.keys(parse.output.flags)) {
|
|
152
|
+
// do not enforce exclusivity for flags that were defaulted
|
|
153
|
+
if (parse.output.metadata.flags && parse.output.metadata.flags[flag]?.setFromDefault)
|
|
154
|
+
continue;
|
|
155
|
+
if (parse.output.metadata.flags && parse.output.metadata.flags[name]?.setFromDefault)
|
|
156
|
+
continue;
|
|
157
|
+
if (flag !== name && parse.output.flags[flag] !== undefined && !combinableFlags.has(flag)) {
|
|
158
|
+
const formattedFlags = Object.keys(resolved)
|
|
159
|
+
.map((f) => `--${f}`)
|
|
160
|
+
.join(', ');
|
|
161
|
+
return {
|
|
162
|
+
...base,
|
|
163
|
+
reason: `Only the following can be provided when using --${name}: ${formattedFlags}`,
|
|
164
|
+
status: 'failed',
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { ...base, status: 'success' };
|
|
169
|
+
}
|
|
146
170
|
async function validateExactlyOne(name, flags) {
|
|
147
171
|
const base = { name, validationFn: 'validateExactlyOne' };
|
|
148
172
|
const resolved = await resolveFlags(flags);
|
|
@@ -195,6 +219,9 @@ async function validate(parse) {
|
|
|
195
219
|
case 'none': {
|
|
196
220
|
return validateExclusive(name, relationship.flags);
|
|
197
221
|
}
|
|
222
|
+
case 'only': {
|
|
223
|
+
return validateCombinable(name, relationship.flags);
|
|
224
|
+
}
|
|
198
225
|
case 'some': {
|
|
199
226
|
return validateSome(name, relationship.flags);
|
|
200
227
|
}
|
|
@@ -20,6 +20,7 @@ async function cacheFlags(cmdFlags, respectNoCacheDefault) {
|
|
|
20
20
|
aliases: flag.aliases,
|
|
21
21
|
char: flag.char,
|
|
22
22
|
charAliases: flag.charAliases,
|
|
23
|
+
combinable: flag.combinable,
|
|
23
24
|
dependsOn: flag.dependsOn,
|
|
24
25
|
deprecateAliases: flag.deprecateAliases,
|
|
25
26
|
deprecated: flag.deprecated,
|