cli: added support for dynamically discovering create options
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -53,24 +53,36 @@ export class FactoryRegistry {
|
||||
factory: AnyFactory,
|
||||
provided: Record<string, string>,
|
||||
): Promise<Record<string, string>> {
|
||||
const [hasAnswers, needsAnswers] = partition(
|
||||
factory.options,
|
||||
option => option.name in provided,
|
||||
);
|
||||
let currentOptions = provided;
|
||||
|
||||
for (const option of hasAnswers) {
|
||||
const value = provided[option.name];
|
||||
|
||||
if (option.validate) {
|
||||
const result = option.validate(value);
|
||||
if (result !== true) {
|
||||
throw new Error(`Invalid option '${option.name}'. ${result}`);
|
||||
}
|
||||
}
|
||||
if (factory.optionsDiscovery) {
|
||||
const discoveredOptions = await factory.optionsDiscovery();
|
||||
currentOptions = {
|
||||
...currentOptions,
|
||||
...(discoveredOptions as Record<string, string>),
|
||||
};
|
||||
}
|
||||
|
||||
const answers = await inquirer.prompt(needsAnswers);
|
||||
if (factory.optionsPrompts) {
|
||||
const [hasAnswers, needsAnswers] = partition(
|
||||
factory.optionsPrompts,
|
||||
option => option.name in currentOptions,
|
||||
);
|
||||
|
||||
return { ...provided, ...answers };
|
||||
for (const option of hasAnswers) {
|
||||
const value = provided[option.name];
|
||||
|
||||
if (option.validate) {
|
||||
const result = option.validate(value);
|
||||
if (result !== true) {
|
||||
throw new Error(`Invalid option '${option.name}'. ${result}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
currentOptions = await inquirer.prompt(needsAnswers, currentOptions);
|
||||
}
|
||||
|
||||
return currentOptions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,27 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { paths } from '../../../lib/paths';
|
||||
import { getCodeownersFilePath, parseOwnerIds } from '../../../lib/codeowners';
|
||||
import { createFactory } from '../types';
|
||||
|
||||
type Options = {
|
||||
id: string;
|
||||
owner?: string;
|
||||
codeOwnersPath?: string;
|
||||
};
|
||||
|
||||
export const frontendPlugin = createFactory<Options>({
|
||||
name: 'plugin',
|
||||
description: 'A new frontend plugin',
|
||||
options: [
|
||||
optionsDiscovery: async () => ({
|
||||
codeOwnersPath: await getCodeownersFilePath(paths.targetRoot),
|
||||
}),
|
||||
optionsPrompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'id',
|
||||
message: 'Enter an ID for the plugin',
|
||||
message: 'Enter an ID for the plugin [required]',
|
||||
validate: (value: string) => {
|
||||
if (!value) {
|
||||
return 'Please enter an ID for the plugin';
|
||||
@@ -37,6 +44,24 @@ export const frontendPlugin = createFactory<Options>({
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'input',
|
||||
name: 'owner',
|
||||
message: 'Enter an owner of the plugin to add to CODEOWNERS [optional]',
|
||||
when: opts => Boolean(opts.codeOwnersPath),
|
||||
validate: (value: string) => {
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ownerIds = parseOwnerIds(value);
|
||||
if (!ownerIds) {
|
||||
return 'The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses (e.g. user@example.com).';
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
],
|
||||
async create(options: Options) {
|
||||
console.log(
|
||||
|
||||
@@ -21,7 +21,8 @@ export type AnyOptions = Record<string, string>;
|
||||
export interface Factory<Options extends AnyOptions> {
|
||||
name: string;
|
||||
description: string;
|
||||
options: ReadonlyArray<DistinctQuestion<Options> & { name: string }>;
|
||||
optionsDiscovery?(): Promise<Partial<Options>>;
|
||||
optionsPrompts?: ReadonlyArray<DistinctQuestion<Options> & { name: string }>;
|
||||
create(options: Options): Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user