@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.
273 lines (272 loc) • 15.5 kB
TypeScript
/**
* @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/project-generator.ts
* @summary Exports `SfdxFalconProjectGenerator` for use with custom Yeoman generators that
* focus on standing up local projects.
* @description Exports an abstract class that extends the SFDX-Falcon Library's `SfdxFalconGenerator`
* class, adding customized support for tools and capabilities that make it easier
* to stand up a local git-based project.
*/
import * as Generator from 'yeoman-generator';
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 { JsonMap } from '@sfdx-falcon/types';
import { StyledMessage } 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;
/** Optional. Special set of answers. Provides a means to send meta values (usually template tags) to EJS templates. */
meta?: T;
}
/**
* Interface. Collection of message strings that are displayed at various times during the execution
* of an `SfdxFalconGenerator`.
*/
export interface GeneratorMessage {
/** Required. Message shown to the user before exiting the initializing() run-loop function. */
confirmation: string;
/** Required. Message that will be displayed by the yosay "Yeoman" ASCII art when the generator is loaded. */
opening: 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 {
/** Name of the CLI command that kicked off this Generator. */
protected readonly commandName: string;
/** 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 generatorMessage: GeneratorMessage;
/** 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);
/**
* @method initializing
* @returns {Promise<void>}
* @description STEP ONE in the Yeoman run-loop. Uses Yeoman's "initializing"
* run-loop priority. This is a "default" implementation and
* should work for most SFDX-Falcon use cases. It must be called
* from inside the initializing() method of the child class.
* @public @async
*/
/**
* @method prompting
* @param {StyledMessage} [preInterviewMessage] Optional. Message to
* display to the user before the Interview starts.
* @param {StyledMessage} [postInterviewMessage] Optional. Message to
* display to the user after the Interview ends.
* @returns {Promise<void>}
* @description STEP TWO in the Yeoman run-loop. Interviews the User to get
* information needed by the "writing" and "installing" phases.
* This is a "default" implementation and should work for most
* SFDX-Falcon use cases. It must be called from inside the
* prompting() method of the child class.
* @public @async
*/
prompting(preInterviewMessage?: StyledMessage, postInterviewMessage?: StyledMessage): 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.
* This is a "default" implementation and should work for most
* SFDX-Falcon use cases. It must be called from inside the
* configuring() method of the child class.
* @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.
* This is a "default" implementation and should work for most
* SFDX-Falcon use cases. It must be called from inside the
* writing() method of the child class.
* @public @async
*/
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. This is a "default" implementation and should
* work for most SFDX-Falcon use cases. It must be called from
* inside the install() method of the child class.
* @public @async
*/
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. This is a "default" implementation
* and should work for most SFDX-Falcon use cases. It must be
* called from inside the end() method of the child class.
* @public @async
*/
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>;
/**
* @method _cloneRepository
* @returns {Promise<string>} Local path into which the Git Repository
* was cloned. If the clone operation is unsuccessful, this
* will return an empty string.
* @description Clones a remote Git Repository per information specified
* during by the command and/or during their interview. Returns
* the local path to which the Git Repository was cloned, or
* an empty string otherwise.
* @protected @async
*/
/**
* @method _executeInitializationTasks
* @returns {Promise<void>}
* @description Runs a series of initialization tasks using the Listr UX/Task
* Runner module. Listr provides a framework for executing tasks
* while also providing an attractive, realtime display of task
* status (running, successful, failed, etc.).
* @protected @async
*/
/**
* @method _finalizeGitActions
* @param {string} destinationRoot Required.
* @param {boolean} isInitializingGit Required.
* @param {string} gitRemoteUri Required.
* @param {string} projectAlias Required.
* @returns {Promise<void>}
* @description Intended to run after _finalizeProjectCreation() during the
* Yeoman "writing" phase. Initializes local Git repo, and will
* even try to attach a Git remote if specified by the user.
* @protected @async
*/
/**
* @method _finalizeProjectCloning
* @returns {boolean} Returns FALSE if the project was aborted.
* @description Intended to run after the Yeoman "writing" phase. Has logic
* that ensures the Generator wasn't aborted, and then carries
* out finalization tasks that are generic to "cloning"
* Generators. Returns a boolean so the calling class can decide
* whether or not to perform additional actions.
* @protected
*/
protected _finalizeProjectCloning(): boolean;
/**
* @method _finalizeProjectCreation
* @returns {boolean} Returns FALSE if the project was aborted.
* @description Intended to run after the Yeoman "writing" phase. Has logic
* that ensures the Generator wasn't aborted, and then carries
* out finalization tasks that are generic to "creation"
* Generators. Returns a boolean so the calling class can decide
* whether or not to perform additional actions.
* @protected
*/
protected _finalizeProjectCreation(): boolean;
}