@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.
647 lines (618 loc) • 38.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
//─────────────────────────────────────────────────────────────────────────────────────────────────┐
/**
* @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 External Libraries, Modules, and Types
//import chalk from 'chalk'; // Helps write colored text to the console.
//import * as path from 'path'; // Library. Helps resolve local paths at runtime.
const Generator = require("yeoman-generator"); // Class. Custom Generator classes must extend this.
// Import SFDX-Falcon Libraries
//import {GitUtil} from '@sfdx-falcon/util'; // Library. Git Helper functions specific to SFDX-Falcon.
//import listrTasks from '@sfdx-falcon/util'; // Library. Helper functions that make using Listr with SFDX-Falcon easier.
const validator_1 = require("@sfdx-falcon/validator"); // Library of Type Validation helper functions.
// Import SFDX-Falcon Classes & Functions
const debug_1 = require("@sfdx-falcon/debug"); // Class. Provides custom "debugging" services (ie. debug-style info to console.log()).
const status_1 = require("@sfdx-falcon/status"); // Class. Implements a framework for creating results-driven, informational objects with a concept of heredity (child results) and the ability to "bubble up" both Errors (thrown exceptions) and application-defined "failures".
const status_2 = require("@sfdx-falcon/status"); // Function. Prints a Styled Message to the console using Chalk.
//import {SfdxFalconKeyValueTable} from '@sfdx-falcon/status'; // Class. Uses table creation code borrowed from the SFDX-Core UX library to make it easy to build "Key/Value" tables.
const status_3 = require("@sfdx-falcon/status"); // Class. Status tracking object for use with Yeoman Generators.
//import {InquirerChoices} from '@sfdx-falcon/types'; // Type. Represents a single "choice" option in an Inquirer multi-choice/multi-select question.
//import {ListrContextFinalizeGit} from '@sfdx-falcon/types'; // Interface. Represents the Listr Context variables used by the "finalizeGit" task collection.
//import {ListrTaskBundle} from '@sfdx-falcon/types'; // Interface. Represents the suite of information required to run a Listr Task Bundle.
const types_1 = require("@sfdx-falcon/types"); // Enum. Represents the various types/states of a Status Message.
// Set the File Local Debug Namespace
const dbgNs = '@sfdx-falcon:project-generator';
debug_1.SfdxFalconDebug.msg(`${dbgNs}:`, `Debugging initialized for ${dbgNs}`);
//─────────────────────────────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//─────────────────────────────────────────────────────────────────────────────────────────────────┘
class SfdxFalconGenerator extends Generator {
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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, opts, reqs) {
// Define function-local debug namespace and debug incoming arguments.
const funcName = `constructor`;
const dbgNsLocal = `${dbgNs}:${funcName}`;
debug_1.SfdxFalconDebug.obj(`${dbgNsLocal}:arguments:`, arguments);
// Validate core options.
validator_1.TypeValidator.throwOnEmptyNullInvalidObject(reqs, `${dbgNsLocal}`, `GeneratorRequirements`);
validator_1.TypeValidator.throwOnEmptyNullInvalidObject(reqs.gitEnvReqs, `${dbgNsLocal}`, `GeneratorRequirements.gitEnvReqs`);
validator_1.TypeValidator.throwOnEmptyNullInvalidObject(reqs.localEnvReqs, `${dbgNsLocal}`, `GeneratorRequirements.localEnvReqs`);
validator_1.TypeValidator.throwOnEmptyNullInvalidObject(reqs.sfdxEnvReqs, `${dbgNsLocal}`, `GeneratorRequirements.sfdxEnvReqs`);
validator_1.TypeValidator.throwOnEmptyNullInvalidObject(opts, `${dbgNsLocal}`, `GeneratorOptions`);
validator_1.TypeValidator.throwOnEmptyNullInvalidString(opts.commandName, `${dbgNsLocal}`, `GeneratorOptions.commandName`);
validator_1.TypeValidator.throwOnEmptyNullInvalidString(opts.generatorType, `${dbgNsLocal}`, `GeneratorOptions.generatorType`);
validator_1.TypeValidator.throwOnEmptyNullInvalidString(opts.generatorPath, `${dbgNsLocal}`, `GeneratorOptions.generatorPath`);
validator_1.TypeValidator.throwOnNullInvalidInstance(opts.generatorResult, status_1.SfdxFalconResult, `${dbgNsLocal}`, `GeneratorOptions.generatorType`);
// Call the parent constructor to initialize the Yeoman Generator.
super(args, opts);
// Resolve Generator Requirements
const generatorReqs = {
sfdxEnvReqs: {
standardOrgs: (reqs.sfdxEnvReqs.standardOrgs === true ? true : false),
scratchOrgs: (reqs.sfdxEnvReqs.scratchOrgs === true ? true : false),
devHubOrgs: (reqs.sfdxEnvReqs.devHubOrgs === true ? true : false),
envHubOrgs: (reqs.sfdxEnvReqs.envHubOrgs === true ? true : false),
managedPkgOrgs: (reqs.sfdxEnvReqs.managedPkgOrgs === true ? true : false),
unmanagedPkgOrgs: (reqs.sfdxEnvReqs.unmanagedPkgOrgs === true ? true : false)
},
gitEnvReqs: {
// TODO: Implement once Git Environment is fleshed out.
},
localEnvReqs: {
// TODO: Implement once Local Environment is fleshed out.
}
};
// Determine the path to the package.json file for the currently running package.
const pkgDotJsonPath = '../../../package.json';
// Attempt to pull the VERSION key from package.json.
let pkgVersion = `??.??.??`;
try {
const { version } = require(pkgDotJsonPath);
pkgVersion = validator_1.TypeValidator.isNotEmptyNullInvalidString(version) ? version : pkgVersion;
}
catch (pkgVersionJsonError) {
debug_1.SfdxFalconDebug.obj(`${dbgNsLocal}:pkgVersionJsonError:`, pkgVersionJsonError);
}
debug_1.SfdxFalconDebug.str(`${dbgNsLocal}:pkgVersion:`, pkgVersion);
// Attempt to pull the FALCON key from package.json.
let pkgFalcon = {};
try {
const { falcon } = require(pkgDotJsonPath);
pkgFalcon = validator_1.TypeValidator.isNotNullInvalidObject(falcon) ? falcon : pkgFalcon;
}
catch (pkgFalconJsonError) {
debug_1.SfdxFalconDebug.obj(`${dbgNsLocal}:pkgFalconJsonError:`, pkgFalconJsonError);
}
debug_1.SfdxFalconDebug.obj(`${dbgNsLocal}:pkgFalcon:`, pkgFalcon);
// Initialize class members.
this.commandName = opts.commandName; // Name of the command that's executing the Generator (eg. 'falcon:adk:clone').
this.generatorType = opts.generatorType; // Type (ie. file name minus the .ts extension) of the Generator being run.
this.generatorResult = opts.generatorResult; // Used for activity tracking and communication back to the calling command.
this.generatorReqs = generatorReqs; // Generator Requirements. Should be modified by the derived class.
this.generatorStatus = new status_3.GeneratorStatus(); // Tracks status and build messages to the user.
this.pluginVersion = pkgVersion; // Version of the plugin, taken from package.json.
this.falcon = pkgFalcon; // Falcon global JsonMap, taken from package.json.
this.sharedData = {}; // Special context for sharing data between Generator, Inquirer Questions, and Listr Tasks.
// Initialize all Run-Loop Status booleans to `null`.
// In practice, `null` will mean an unset value, `false` means failure, `true` means success.
this.runLoopStatus = {
initializingComplete: null,
promptingComplete: null,
configuringComplete: null,
writingComplete: null,
installComplete: null,
endComplete: null
};
// Initialize all Answer objects.
this.answers = {
default: {},
final: {},
user: {},
meta: {}
};
// Set defaults for all Generator messages.
this.generatorMessage = {
opening: `SFDX-Falcon Powered Plugin\n${this.commandName}\nv${this.pluginVersion}`,
confirmation: `Would you like to proceed based on the above settings?`,
success: `${this.commandName} completed successfully`,
failure: `${this.commandName} exited without completing the expected tasks`,
warning: `${this.commandName} completed successfully, but with some warnings (see above)`
};
// Start the GeneratorStatus object and add it to the detail of the GENERATOR Result.
this.generatorStatus.start();
this.generatorResult.setDetail({
commandName: this.commandName,
generatorType: this.generatorType,
generatorPath: this.generatorPath,
generatorReqs: this.generatorReqs,
generatorMsgs: this.generatorMessage,
interviewAnswers: this.answers,
runLoopStatus: this.runLoopStatus,
generatorStatus: this.generatorStatus
});
this.generatorResult.debugResult(`After setting Detail in constructor`, `${dbgNsLocal}`);
// Initialize Shared Data.
this.sharedData['cliCommandName'] = this.commandName;
// this.sharedData['generatorRequirements'] = this.generatorRequirements;
this.sharedData['generatorStatus'] = this.generatorStatus;
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
/*
public async initializing():Promise<void> {
// Do nothing if the Generator has been aborted.
if (this.generatorStatus.aborted) {
SfdxFalconDebug.msg(`${dbgNs}_default_initializing:`, `Generator has been aborted.`);
return;
}
// Show the Yeoman to announce that the generator is running.
this.log(yosay(this.generatorMessage.opening));
// Execute the initialization tasks for this generator
try {
await this._executeInitializationTasks();
}
catch (initializationError) {
SfdxFalconDebug.obj(`${dbgNs}default_initializing:`, initializationError, `initializationError: `);
// Add an "abort" item to the Generator Status object.
this.generatorStatus.abort({
type: StatusMessageType.ERROR,
title: 'Initialization Error',
message: `${this.commandName} command aborted because one or more initialization tasks failed`
});
// Throw an Initialization Error.
throw new SfdxFalconError( `Command initialization failed. ${initializationError.message}`
, `InitializationError`
, `${dbgNs}default_initializing`
, SfdxFalconError.wrap(initializationError));
}
// Add a line break to separate this section from the next in the console.
console.log('');
}//*/
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
async prompting(preInterviewMessage, postInterviewMessage) {
// Do nothing if the Generator has been aborted.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}:prompting:`, `Generator has been aborted.`);
return;
}
// Show the pre-interview message.
status_2.printStyledMessage(preInterviewMessage);
// Build the User Interview.
this.userInterview = this._buildInterview();
// Start the User Interview.
this.answers.final = await this.userInterview.start();
// Extract the "User Answers" from the Interview for inclusion in the GENERATOR Result's detail.
this.generatorResult.detail['userAnswers'] = this.userInterview.userAnswers;
// Check if the user aborted the Interview.
if (this.userInterview.status.aborted) {
this.generatorStatus.abort({
type: types_1.StatusMessageType.ERROR,
title: 'Command Aborted',
message: `${this.commandName} canceled by user. ${this.userInterview.status.reason}`
});
}
// Show the post-interview message.
status_2.printStyledMessage(postInterviewMessage);
// Done
return;
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
async configuring() {
// Do nothing if the Generator has been aborted.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_default_configuring:`, `Generator has been aborted.`);
return;
}
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
async writing() {
// Do nothing if the Generator has been aborted.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_default_writing:`, `Generator has been aborted.`);
return;
}
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
async install() {
// Do nothing if the Generator has been aborted.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_default_install:`, `Generator has been aborted.`);
return;
}
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
async end() {
// Check if the Yeoman interview/installation process was aborted.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}end:`, `generatorStatus.aborted found as TRUE inside end()`);
// Add a final error message
this.generatorStatus.addMessage({
type: types_1.StatusMessageType.ERROR,
title: 'Command Failed',
message: `${this.generatorMessage.failure}\n`
});
}
else {
// Generator completed successfully. Final message depends on presence of Generator Status Warnings.
this.generatorStatus.complete([
{
type: types_1.StatusMessageType.SUCCESS,
title: 'Command Succeded',
message: this.generatorStatus.hasWarning
? `${this.generatorMessage.warning}\n`
: `${this.generatorMessage.success}\n`
}
]);
}
// Print the final status table.
this.generatorStatus.printStatusMessages();
return;
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
/*
protected async _cloneRepository():Promise<string> {
// Determine a number of Path/Git related strings required by this step.
const targetDirectory = this.answers.final['targetDirectory'] as string;
const gitRemoteUri = this['gitRemoteUri'];
const gitCloneDirectory = this['gitCloneDirectory'] || GitUtil.getRepoNameFromUri(gitRemoteUri);
const localProjectPath = path.join(targetDirectory, gitCloneDirectory);
// Quick message saying we're going to start cloning.
this.log(chalk`{yellow Cloning Project...}`);
// Run a Listr Task that will clone the Remote Git Repo.
return await listrTasks.cloneGitRemote.call(this, gitRemoteUri, targetDirectory, gitCloneDirectory).run()
.then((_listrContext:unknown) => {
// Add a message that the cloning was successful.
this.generatorStatus.addMessage({
type: StatusMessageType.SUCCESS,
title: `Project Cloned Successfully`,
message: `Project cloned to ${localProjectPath}`
});
return localProjectPath;
})
.catch(gitCloneError => {
this.generatorStatus.abort({
type: StatusMessageType.ERROR,
title: `Git Clone Error`,
message: gitCloneError.cause ? String(gitCloneError.cause.message).trim() : gitCloneError.message
});
return '';
});
}//*/
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
/*
protected async _executeInitializationTasks():Promise<void> {
// Define the first group of tasks (Git Initialization).
const gitInitTasks = listrTasks.gitEnvironmentCheck.call(this, this.generatorRequirements.gitRemoteUri);
// Define the second group of tasks (SFDX Initialization).
const sfdxInitTasks = listrTasks.sfdxInitTasks.call(this);
// Show a message to the User letting them know we're going to initialize this command.
console.log(chalk`{yellow Initializing ${this.cliCommandName}...}`);
// If required, run the Git Init Tasks.
if (this.generatorRequirements.git || this.generatorRequirements.gitRemoteUri) {
const gitInitResults = await gitInitTasks.run();
SfdxFalconDebug.obj(`${dbgNs}_executeInitializationTasks:`, gitInitResults, `gitInitResults: `);
}
// If required, run the SFDX Init Tasks.
if ( this.generatorRequirements.standardOrgs === true
|| this.generatorRequirements.scratchOrgs === true
|| this.generatorRequirements.devHubOrgs === true
|| this.generatorRequirements.envHubOrgs === true
|| this.generatorRequirements.managedPkgOrgs === true
|| this.generatorRequirements.unmanagedPkgOrgs === true
) {
const sfdxInitResults = await sfdxInitTasks.run();
SfdxFalconDebug.obj(`${dbgNs}_executeInitializationTasks:`, sfdxInitResults, `sfdxInitResults: `);
}
}//*/
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
/*
protected async _finalizeGitActions(destinationRoot:string, isInitializingGit:boolean, gitRemoteUri:string, projectAlias:string):Promise<void> {
// Make sure that the caller really WANTS to initialize Git.
if (isInitializingGit !== true) {
this.generatorStatus.addMessage({
type: StatusMessageType.SUCCESS,
title: `Git Initialization`,
message: `Skipped - Git initialization skipped at user's request`
});
return;
}
// Tell the user that we are adding their project to Git
this.log(chalk`{yellow Adding project to Git...}`);
// Construct a Listr Task Object for the "Finalize Git" tasks.
const finalizeGit = listrTasks.finalizeGit.call(this, destinationRoot, gitRemoteUri);
// Try to run the "Finalize Git" tasks. Catch any errors so we can exit the broader Falcon command gracefully.
let finalizeGitCtx = {} as ListrContextFinalizeGit;
try {
finalizeGitCtx = await finalizeGit.run() as ListrContextFinalizeGit;
}
catch (listrError) {
SfdxFalconDebug.obj(`${dbgNs}_finalizeGitActions:listrError:`, listrError, `listrError: `);
finalizeGitCtx = listrError.context;
}
// DEBUG
SfdxFalconDebug.obj(`${dbgNs}_finalizeGitActions:finalizeGitCtx:`, finalizeGitCtx, `finalizeGitCtx: `);
// Separate the end of the "Finalize Git" Listr tasks from following output.
console.log('');
// Check if Git was installed in the local environment.
if (finalizeGitCtx.gitInstalled !== true) {
this.generatorStatus.addMessage({
type: StatusMessageType.WARNING,
title: `Initializing Git`,
message: `Warning - git executable not found in your environment - no Git operations attempted`
});
// Skip the remaining checks and message builds.
return;
}
// Check if the project was successfully initialized (ie. "git init" was run in the project directory).
if (finalizeGitCtx.gitInitialized) {
this.generatorStatus.addMessage({
type: StatusMessageType.SUCCESS,
title: `Git Initialization`,
message: `Success - Repository created successfully (${projectAlias})`
});
}
else {
this.generatorStatus.addMessage({
type: StatusMessageType.WARNING,
title: `Git Initialization`,
message: `Warning - Git could not be initialized in your project folder`
});
// Skip the remaining checks and message builds.
return;
}
// Check if the files were staged and committed successfully.
if (finalizeGitCtx.projectFilesStaged && finalizeGitCtx.projectFilesCommitted) {
this.generatorStatus.addMessage({
type: StatusMessageType.SUCCESS,
title: `Git Commit`,
message: `Success - Staged all project files and executed the initial commit`
});
}
else {
this.generatorStatus.addMessage({
type: StatusMessageType.WARNING,
title: `Git Commit`,
message: `Warning - Attempt to stage and commit project files failed - Nothing to commit`
});
}
// If the user specified a Git Remote, check for success there.
if (gitRemoteUri) {
// Check if the Git Remote is valid/reachable
if (finalizeGitCtx.gitRemoteIsValid !== true) {
this.generatorStatus.addMessage({
type: StatusMessageType.WARNING,
title: `Git Remote`,
message: `Warning - Could not add Git Remote - ${gitRemoteUri} is invalid/unreachable`
});
}
else {
if (finalizeGitCtx.gitRemoteAdded) {
this.generatorStatus.addMessage({
type: StatusMessageType.SUCCESS,
title: `Git Remote`,
message: `Success - Remote repository ${gitRemoteUri} added as "origin"`
});
}
else {
this.generatorStatus.addMessage({
type: StatusMessageType.WARNING,
title: `Git Remote`,
message: `Warning - Could not add Git Remote - A remote named "origin" already exists`
});
}
}
}
// All done.
return;
}//*/
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
_finalizeProjectCloning() {
// Check if we need to abort the Yeoman interview/installation process.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_finalizeProjectCloning:`, `generatorStatus.aborted found as TRUE inside install()`);
return false;
}
// Make sure that a Destination Root was set.
if (!this.destinationRoot()) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_finalizeProjectCloning:`, `No value returned by this.destinationRoot(). Skipping finalization tasks.`);
return false;
}
// If we get here, it means that a local SFDX-Falcon config file was likely created.
this.generatorStatus.addMessage({
type: types_1.StatusMessageType.SUCCESS,
title: `Local Config Created`,
message: `.sfdx-falcon/sfdx-falcon-config.json created and customized successfully`
});
// Add a line break to separate the end of the "writing" phase from any output in the "install" phase.
console.log('');
// All done.
return true;
}
//───────────────────────────────────────────────────────────────────────────┐
/**
* @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
*/
//───────────────────────────────────────────────────────────────────────────┘
_finalizeProjectCreation() {
// Check if we need to abort the Yeoman interview/installation process.
if (this.generatorStatus.aborted) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_finalizeProjectCreation:`, `generatorStatus.aborted found as TRUE inside install()`);
return false;
}
// Make sure that a Destination Root was set.
if (!this.destinationRoot()) {
debug_1.SfdxFalconDebug.msg(`${dbgNs}_finalizeProjectCreation:`, `No value returned by this.destinationRoot(). Skipping finalization tasks.`);
return false;
}
// Add a "project creation" success message to Generator Status.
this.generatorStatus.addMessage({
type: types_1.StatusMessageType.SUCCESS,
title: `Project Creation`,
message: `Success - Project created at ${this.destinationRoot()}`
});
// Add a line break to separate the end of the "writing" phase from any output in the "install" phase.
console.log('');
// If we get this far, return TRUE so additional finalization code knows it should run.
return true;
}
}
exports.SfdxFalconGenerator = SfdxFalconGenerator;
//# sourceMappingURL=project-generator.js.map