Charles Lyding b2b536789b refactor(@angular/cli): discover/load workspace on startup
Previously, the workspace configuration file was found and loaded by individual commands potentially multiple times.  This change moves the initial workspace location discovery and loading of the workspace to the CLI startup.  It also provides the workspace to each command so that the commands can reuse the already loaded and parsed workspace configuration.
2020-10-02 07:53:07 -04:00

233 lines
5.1 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { analytics, json, logging } from '@angular-devkit/core';
import { AngularWorkspace } from '../utilities/config';
/**
* Value type of arguments.
*/
export type Value = number | string | boolean | (number | string | boolean)[];
/**
* An object representing parsed arguments from the command line.
*/
export interface Arguments {
[argName: string]: Value | undefined;
/**
* Extra arguments that were not parsed. Will be omitted if all arguments were parsed.
*/
'--'?: string[];
}
/**
* The base interface for Command, understood by the command runner.
*/
export interface CommandInterface<T extends Arguments = Arguments> {
printHelp(options: T): Promise<number>;
printJsonHelp(options: T): Promise<number>;
validateAndRun(options: T): Promise<number>;
}
/**
* Command constructor.
*/
export interface CommandConstructor {
new(
context: CommandContext,
description: CommandDescription,
logger: logging.Logger,
): CommandInterface;
}
/**
* A command runner context.
*/
export interface CommandContext {
currentDirectory: string;
root: string;
workspace?: AngularWorkspace;
// This property is optional for backward compatibility.
analytics?: analytics.Analytics;
}
/**
* Value types of an Option.
*/
export enum OptionType {
Any = 'any',
Array = 'array',
Boolean = 'boolean',
Number = 'number',
String = 'string',
}
/**
* An option description. This is exposed when using `ng --help=json`.
*/
export interface Option {
/**
* The name of the option.
*/
name: string;
/**
* A short description of the option.
*/
description: string;
/**
* The type of option value. If multiple types exist, this type will be the first one, and the
* types array will contain all types accepted.
*/
type: OptionType;
/**
* {@see type}
*/
types?: OptionType[];
/**
* If this field is set, only values contained in this field are valid. This array can be mixed
* types (strings, numbers, boolean). For example, if this field is "enum: ['hello', true]",
* then "type" will be either string or boolean, types will be at least both, and the values
* accepted will only be either 'hello' or true (not false or any other string).
* This mean that prefixing with `no-` will not work on this field.
*/
enum?: Value[];
/**
* If this option maps to a subcommand in the parent command, will contain all the subcommands
* supported. There is a maximum of 1 subcommand Option per command, and the type of this
* option will always be "string" (no other types). The value of this option will map into
* this map and return the extra information.
*/
subcommands?: {
[name: string]: SubCommandDescription;
};
/**
* Aliases supported by this option.
*/
aliases: string[];
/**
* Whether this option is required or not.
*/
required?: boolean;
/**
* Format field of this option.
*/
format?: string;
/**
* Whether this option should be hidden from the help output. It will still show up in JSON help.
*/
hidden?: boolean;
/**
* Default value of this option.
*/
default?: string | number | boolean;
/**
* If this option can be used as an argument, the position of the argument. Otherwise omitted.
*/
positional?: number;
/**
* Smart default object.
*/
$default?: OptionSmartDefault;
/**
* Whether or not to report this option to the Angular Team, and which custom field to use.
* If this is falsey, do not report this option.
*/
userAnalytics?: number;
}
/**
* Scope of the command.
*/
export enum CommandScope {
InProject = 'in',
OutProject = 'out',
Everywhere = 'all',
Default = InProject,
}
/**
* A description of a command and its options.
*/
export interface SubCommandDescription {
/**
* The name of the subcommand.
*/
name: string;
/**
* Short description (1-2 lines) of this sub command.
*/
description: string;
/**
* A long description of the sub command, in Markdown format.
*/
longDescription?: string;
/**
* Additional notes about usage of this sub command, in Markdown format.
*/
usageNotes?: string;
/**
* List of all supported options.
*/
options: Option[];
/**
* Aliases supported for this sub command.
*/
aliases: string[];
}
/**
* A description of a command, its metadata.
*/
export interface CommandDescription extends SubCommandDescription {
/**
* Scope of the command, whether it can be executed in a project, outside of a project or
* anywhere.
*/
scope: CommandScope;
/**
* Whether this command should be hidden from a list of all commands.
*/
hidden: boolean;
/**
* The constructor of the command, which should be extending the abstract Command<> class.
*/
impl: CommandConstructor;
}
export interface OptionSmartDefault {
$source: string;
[key: string]: json.JsonValue;
}
export interface CommandDescriptionMap {
[key: string]: CommandDescription;
}