UNPKG

@sfdx-falcon/generator

Version:

Extends Yeoman's Generator class, adding customized support for SFDX-Falcon specific tools and capabilities. Part of the SFDX-Falcon Library.

262 lines (261 loc) 15.5 kB
/** * @author Vivek M. Chawla <@VivekMChawla> * @copyright 2019, Vivek M. Chawla / Salesforce. All rights reserved. * @license BSD-3-Clause For full license text, see the LICENSE file in the repo root or * `https://opensource.org/licenses/BSD-3-Clause` * @file packages/generator/src/generator.ts * @summary Exports `SfdxFalconGenerator` for use with custom Yeoman generators. * @description Exports an abstract class that extends Yeoman's `Generator` class, adding * customized support for SFDX-Falcon specific tools and capabilities. */ import * as Generator from 'yeoman-generator'; import { ExternalContext } from '@sfdx-falcon/builder'; import { SfdxEnvironment } from '@sfdx-falcon/environment'; import { SfdxFalconInterview } from '@sfdx-falcon/interview'; import { SfdxFalconResult } from '@sfdx-falcon/status'; import { GeneratorStatus } from '@sfdx-falcon/status'; import { GeneratorOptions } from '@sfdx-falcon/command'; import { SfdxEnvironmentRequirements } from '@sfdx-falcon/environment'; import { SfdxFalconTableData } from '@sfdx-falcon/status'; import { ConfirmationAnswers } from '@sfdx-falcon/types'; import { JsonMap } from '@sfdx-falcon/types'; /** * Interface. Collection of objects that represent the Answers that will be leveraged by an * `SfdxFalconGenerator`. */ export interface Answers<T extends JsonMap> { /** Required. The set of default answers for the Interview of an `SfdxFalconGenerator`. */ default: T; /** Required. The set of answers provided by the user for the Interview of an `SfdxFalconGenerator`. */ user: T; /** Required. The set of final answers for the Interview of an `SfdxFalconGenerator`. In other words, the merging of User and Default answers in case the user did not supply some answers. */ final: T; /** Required. Special set of answers. Provides a means to send meta values (usually template tags) to EJS templates. */ meta: T; /** Required. The set of answers provided when the user is asked to proceed/retry/abort something. */ confirmation: ConfirmationAnswers; } /** * Interface. Collection of message strings that are displayed at various times during the execution * of an `SfdxFalconGenerator`. */ export interface GeneratorMessages { /** Required. Message that will be displayed by the opening Banner when the generator is loaded. */ opening: string; /** Required. Message shown to the user before the interview starts during the prompting() run-loop function. */ preInterview: string; /** Required. Message shown to the user to help them decide to exit the prompting() run-loop function. */ confirmation: string; /** Required. Message shown to the user after the interview ends but before the prompting() run-loop function exits. */ postInterview: string; /** Required. Message that will be displayed by the `end()` run-loop function upon successful completion of the Generator. */ success: string; /** Required. Message that will be displayed by the `end()` run-loop function upon failure of the Generator. */ failure: string; /** Required. Message that will be displayed by the `end()` run-loop function upon partial success of the Generator. */ warning: string; } /** * Interface. Collection of requirements for the initialization process of an `SfdxFalconGenerator`. */ export interface GeneratorRequirements { gitEnvReqs: object; sfdxEnvReqs: SfdxEnvironmentRequirements; localEnvReqs: object; } /** * Interface. Collection of status `boolean` variables that reflect the status of various Yeoman * run-loop functions. */ export interface RunLoopStatus { /** Required. Indicates that the `initializing()` run-loop function has completed successfully. */ initializingComplete: boolean; /** Required. Indicates that the `prompting()` run-loop function has completed successfully. */ promptingComplete: boolean; /** Required. Indicates that the `configuring()` run-loop function has completed successfully. */ configuringComplete: boolean; /** Required. Indicates that the `writing()` run-loop function has completed successfully. */ writingComplete: boolean; /** Required. Indicates that the `install()` run-loop function has completed successfully. */ installComplete: boolean; /** Required. Indicates that the `end()` run-loop function completed successfully. */ endComplete: boolean; } /** * @class SfdxFalconGenerator * @extends Generator * @summary Abstract base class class for building Yeoman Generators for SFDX-Falcon commands. * @description Classes that extend `SfdxFalconGenerator` must provide a type parameter to * ensure that the "answers" family of member variables (`defaultAnswers`, * `userAnswers`, `metaAnswers`, and `finalAnswers`) has the appropriate interface * type which defines the answers that are relevant to a concrete child class. * @public @abstract */ export declare abstract class SfdxFalconGenerator<T extends JsonMap> extends Generator { /** Debug namespace of the derived class. Makes it easier to debug superclass operations when extending `SfdxFalconGenerator`. */ protected readonly dbgNs: string; /** Name of the CLI command that kicked off this Generator. */ protected readonly commandName: string; /** External Context describing an instance of the derived class. Used by Builder-derived classes. */ protected readonly extCtx: ExternalContext; /** Reference to the package manifest (`package.json`) of the module that owns the class that implements the command entrypoint. */ protected readonly packageJson: JsonMap; /** Version of the plugin that's running this Generator. Taken dynamically from `package.json`. */ protected readonly pluginVersion: string; /** Custom `falcon` options key from `package.json`. Can be used to read package-global settings that a plugin developer chooses to add to `package.json`. */ protected readonly falcon: JsonMap; /** Specifies the various messages used by this Generator. */ protected readonly generatorMessages: GeneratorMessages; /** Tracks the name (type) of Generator being run, eg. `clone-appx-package-project`. */ protected readonly generatorType: string; /** Tracks the path to the of the source file containing the Generator being run, eg `../../generators`. */ protected readonly generatorPath: string; /** Used to keep track of status and to return messages to the caller. */ protected readonly generatorStatus: GeneratorStatus; /** Used to keep track of status and to return messages to the caller. */ protected readonly generatorResult: SfdxFalconResult; /** Determines which initialization tasks are performed during the Default Initialization process. */ protected readonly generatorReqs: GeneratorRequirements; /** Tracks the status of various run-loop functions. */ protected readonly runLoopStatus: RunLoopStatus; /** Collection of objects that represent the Answers to questions that will be asked during the Interview. */ protected readonly answers: Answers<T>; /** Used to share data between the Generator, Inqurirer Prompts, and Listr Tasks. */ protected readonly sharedData: object; /** Holds the `SfdxFalconInterview` object that will be run during the `prompting()` run-loop function. */ protected userInterview: SfdxFalconInterview<T>; /** Represents the SFDX Environment. */ protected sfdxEnv: SfdxEnvironment; /** * @constructs SfdxFalconGenerator * @param {string|string[]} args Required. Array of arguments that are * passed to this generator by Yeoman if the generator is being * invoked from the command line. Passed directly through to * the superclass constructor without modification. * @param {GeneratorOptions} opts Required. Object containing options * that help specify how a specific generator is run. These * options are set when external code uses a Yeoman Environment * to `run()` a Generator that's derived from this class. * @description Constructs an `SfdxFalconGenerator` object. * @public */ constructor(args: string | string[], opts: GeneratorOptions, reqs: GeneratorRequirements); abstract initializing(): Promise<void>; abstract prompting(): Promise<void>; abstract configuring(): Promise<void>; abstract writing(): Promise<void>; abstract install(): Promise<void>; abstract end(): Promise<void>; /** * @method _showOpener * @returns {Promise<void>} * @description Shows an opening message when the `initializing` run-loop * function is executed. Uses the string from * `this.generatorMessage.opening` as the source of the message * contents. Can be overridden by derived class to customize the * opener behavior. * @protected @async */ protected _showOpener(): Promise<void>; /** * @method __initializing * @returns {Promise<void>} * @description STEP ONE in the Yeoman run-loop. Intended to be executed as * part of Yeoman's `initializing` run-loop priority. Will call * the matching single-underscore method `_initializing()` from * the derived class after executing logic that's specialized * for `SfdxFalconGenerator` based Generators. This method must * be called by the `initializing()` method that's implemented * by the dervived class. * @protected @async */ protected __initializing(): Promise<void>; /** * @method __prompting * @returns {Promise<void>} * @description STEP TWO in the Yeoman run-loop. Interviews the User to get * information needed by the `writing` and `installing` phases. * Intended to be executed as part of Yeoman's `prompting` * run-loop priority. Will call the matching single-underscore * method `_prompting()` from the derived class after executing * logic that's specialized for `SfdxFalconGenerator` based * Generators. This method must be called by the `prompting()` * method that's implemented by the dervived class. * @protected @async */ protected __prompting(): Promise<void>; /** * @method __configuring * @returns {void} * @description STEP THREE in the Yeoman run-loop. Perform any pre-install * configuration steps based on the answers provided by the User. * Intended to be executed as part of Yeoman's `configuring` * run-loop priority. Will call the matching single-underscore * method `_configuring()` from the derived class after executing * logic that's specialized for `SfdxFalconGenerator` based * Generators. this method must be called by the `configuring()` * method that's implemented by the dervived class. * @protected @async */ protected __configuring(): Promise<void>; /** * @method __writing * @returns {Promise<void>} * @description __STEP FOUR in the Yeoman run-loop.__ Typically, this is where * you perform filesystem writes, git clone operations, etc. * Intended to be executed as part of Yeoman's `writing` run-loop * priority. Will call the matching single-underscore method * `_writing()` from the derived class after executing logic * that's specialized for `SfdxFalconGenerator` based Generators. * This method must] be called by the `writing()` method that's * implemented by the dervived class. * @protected @async */ protected __writing(): Promise<void>; /** * @method install * @returns {Promise<void>} * @description __STEP FIVE in the Yeoman run-loop.__ Typically, this is where * you perform operations that must happen AFTER files are * written to disk. For example, if the `writing` step downloaded * an app to install, the `install` step would run the * installation. Intended to be executed as part of Yeoman's * `install` run-loop priority. Will call the matching * single-underscore method `_install()` from the derived class * after executing logic that's specialized for `SfdxFalconGenerator` * based Generators. This method must be called by the `install()` * method that's implemented by the dervived class. * @protected @async */ protected __install(): Promise<void>; /** * @method __end * @returns {Promise<void>} * @description __STEP SIX in the Yeoman run-loop.__ This is the FINAL step * that Yeoman runs and it gives us a chance to do any post-Yeoman * updates and/or cleanup. Intended to be executed as part of the * `end` run-loop priority. Will call the matching single-underscore * method `_end()` from the derived class after executing logic * that's specialized for `SfdxFalconGenerator` based Generators. * This method must be called by the `end()` method that's * implemented by the dervived class. * @protected @async */ protected __end(): Promise<void>; /** Builds a complete `SfdxFalconInterview` object, which may include zero or more confirmation groupings. */ protected abstract _buildInterview(): SfdxFalconInterview<T>; /** Creates Interview Answers table data. Can be used to render an `SfdxFalconTable` object. */ protected abstract _buildInterviewAnswersTableData(userAnswers: T): Promise<SfdxFalconTableData>; /** STEP ONE in the Yeoman run-loop. Uses Yeoman's "initializing" run-loop priority. */ protected abstract _initializing(): Promise<void>; /** STEP TWO in the Yeoman run-loop. Interviews the User to get information needed by the `_writing()` and `_install()` functions. */ protected abstract _prompting(): Promise<void>; /** STEP THREE in the Yeoman run-loop. Perform any pre-install configuration steps based on the answers provided by the User. */ protected abstract _configuring(): Promise<void>; /** STEP FOUR in the Yeoman run-loop. Typically, this is where you perform filesystem writes, git clone operations, etc. */ protected abstract _writing(): Promise<void>; /** STEP FIVE in the Yeoman run-loop. Typically, this is where you perform operations that must happen AFTER files are written to disk. For example, if the `_writing()` step downloaded an app to install, the `_install()` step would run the installation. */ protected abstract _install(): Promise<void>; /** STEP SIX in the Yeoman run-loop. This is the FINAL step that Yeoman runs and it gives us a chance to do any post-Yeoman updates and/or cleanup. */ protected abstract _end(): Promise<void>; }