From 5465166de58efecb1f726ed71f8315b5e9ec9c0b Mon Sep 17 00:00:00 2001 From: "Vivek M. Chawla" Date: Sat, 6 Apr 2019 05:00:26 -0700 Subject: [PATCH] chore(cleanup): Minor cleanup in Generator files Minor cleanup in files related to Yeoman Generator logic. Most of these files already had their big refactoring moments. This commit is mostly small cleanup items discovered while refactoring the falcon:apk:create command. Related to: #22 #139 --- src/commands/falcon/adk/clone.ts | 2 - src/commands/falcon/adk/create.ts | 55 ++++++++-------- src/commands/falcon/adk/install.ts | 16 ++--- src/commands/falcon/apk/clone.ts | 66 ++++++++++++------- src/generators/clone-appx-demo-project.ts | 41 +++++------- src/modules/sfdx-falcon-command/index.ts | 4 +- src/modules/sfdx-falcon-util/listr-tasks.ts | 13 ++-- .../sfdx-falcon-yeoman-command/index.ts | 2 +- 8 files changed, 99 insertions(+), 100 deletions(-) diff --git a/src/commands/falcon/adk/clone.ts b/src/commands/falcon/adk/clone.ts index eac2c12..95907be 100644 --- a/src/commands/falcon/adk/clone.ts +++ b/src/commands/falcon/adk/clone.ts @@ -44,7 +44,6 @@ const commandMessages = Messages.loadMessages('sfdx-falcon', 'falconAdkClone'); * existing project that's based on the AppExchange Demo Kit (ADK) template. After * the project is cloned, the user is taken through an interview to help set up * developer-specific project variables. - * @version 1.0.0 * @public */ //─────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -111,7 +110,6 @@ export default class FalconAdkClone extends SfdxFalconYeomanCommand { * @returns {Promise} Resolves with a JSON object that the CLI * will pass to the user as stdout if the --json flag was set. * @description Entrypoint function for "sfdx falcon:adk:clone". - * @version 1.0.0 * @public @async */ //───────────────────────────────────────────────────────────────────────────┘ diff --git a/src/commands/falcon/adk/create.ts b/src/commands/falcon/adk/create.ts index 91bc065..6aebf75 100644 --- a/src/commands/falcon/adk/create.ts +++ b/src/commands/falcon/adk/create.ts @@ -6,7 +6,7 @@ * @summary Implements the CLI command "falcon:adk:create" * @description Salesforce CLI Plugin command (falcon:adk:create) that allows a Salesforce DX * developer to create an empty project based on the AppExchange Demo Kit (ADK) - * template. Once the ADK project is created, the user is guided through an + * template. Once the ADK project is created, the user is guided through an * interview where they define key ADK project settings which are then used to * customize the ADK project scaffolding that gets created on their local machine. * @version 1.0.0 @@ -17,17 +17,17 @@ import {flags} from '@salesforce/command'; // Allows creation of flags for CLI commands. import {Messages} from '@salesforce/core'; // Messages library that simplifies using external JSON for string reuse. import {SfdxError} from '@salesforce/core'; // Generalized SFDX error which also contains an action. +import {AnyJson} from '@salesforce/ts-types'; // Safe type for use where "any" might otherwise be used. // Import Local Modules -import {SfdxFalconYeomanCommand} from '../../../modules/sfdx-falcon-yeoman-command'; // Base class that CLI commands in this project that use Yeoman should use. import {SfdxFalconError} from '../../../modules/sfdx-falcon-error'; // Extends SfdxError to provide specialized error structures for SFDX-Falcon modules. +import {SfdxFalconYeomanCommand} from '../../../modules/sfdx-falcon-yeoman-command'; // Base class that CLI commands in this project that use Yeoman should use. // Import Internal Types import {SfdxFalconCommandType} from '../../../modules/sfdx-falcon-command'; // Enum. Represents the types of SFDX-Falcon Commands. // Set the File Local Debug Namespace -//const dbgNs = 'COMMAND:falcon-demo-create:'; -//const clsDbgNs = 'FalconDemoCreate:'; +//const dbgNs = 'COMMAND:falcon-adk-create:'; // Use SfdxCore's Messages framework to get the message bundle for this command. Messages.importMessagesDirectory(__dirname); @@ -36,17 +36,16 @@ const commandMessages = Messages.loadMessages('sfdx-falcon', 'falconAdkCreate'); //─────────────────────────────────────────────────────────────────────────────────────────────────┐ /** - * @class FalconDemoCreate + * @class FalconAdkCreate * @extends SfdxFalconYeomanCommand * @summary Implements the CLI Command "falcon:adk:create" * @description The command "falcon:adk:create" creates a local AppExchange Demo Kit (ADK) - * project using the ADK template found at ???. Uses Yeoman to create customized ADK - * project scaffolding on the user's local machine. - * @version 1.0.0 + * the project at https://github.com/sfdx-isv/sfdx-falcon-appx-demo-kit as a template. + * Uses Yeoman to create customized ADK project scaffolding on the user's machine. * @public */ //─────────────────────────────────────────────────────────────────────────────────────────────────┘ -export default class FalconDemoCreate extends SfdxFalconYeomanCommand { +export default class FalconAdkCreate extends SfdxFalconYeomanCommand { // Define the basic properties of this CLI command. public static description = commandMessages.getMessage('commandDescription'); @@ -56,13 +55,6 @@ export default class FalconDemoCreate extends SfdxFalconYeomanCommand { `$ sfdx falcon:adk:create --outputdir ~/ADK-Projects` ]; - // Identify the core SFDX arguments/features required by this command. - protected static requiresProject = false; // True if an SFDX Project workspace is REQUIRED. - protected static requiresUsername = false; // True if an org username is REQUIRED. - protected static requiresDevhubUsername = false; // True if a hub org username is REQUIRED. - protected static supportsUsername = false; // True if an org username is OPTIONAL. - protected static supportsDevhubUsername = false; // True if a hub org username is OPTIONAL. - //───────────────────────────────────────────────────────────────────────────┐ // Define the flags used by this command. // -d --OUTPUTDIR Directory where the AppX Demo Kit project will be created. @@ -70,7 +62,7 @@ export default class FalconDemoCreate extends SfdxFalconYeomanCommand { //───────────────────────────────────────────────────────────────────────────┘ protected static flagsConfig = { outputdir: flags.directory({ - char: 'd', + char: 'd', required: false, description: commandMessages.getMessage('outputdir_FlagDescription'), default: '.', @@ -81,17 +73,23 @@ export default class FalconDemoCreate extends SfdxFalconYeomanCommand { ...SfdxFalconYeomanCommand.falconBaseflagsConfig }; + // Identify the core SFDX arguments/features required by this command. + protected static requiresProject = false; // True if an SFDX Project workspace is REQUIRED. + protected static requiresUsername = false; // True if an org username is REQUIRED. + protected static requiresDevhubUsername = false; // True if a hub org username is REQUIRED. + protected static supportsUsername = false; // True if an org username is OPTIONAL. + protected static supportsDevhubUsername = false; // True if a hub org username is OPTIONAL. + //───────────────────────────────────────────────────────────────────────────┐ /** * @function run - * @returns {Promise} Resolves with a JSON object that the CLI will - * pass to the user as stdout if the --json flag was set. + * @returns {Promise} Resolves with a JSON object that the CLI + * will pass to the user as stdout if the --json flag was set. * @description Entrypoint function for "sfdx falcon:adk:create". - * @version 1.0.0 * @public @async */ //───────────────────────────────────────────────────────────────────────────┘ - public async run(): Promise { + public async run():Promise { // Initialize the SfdxFalconCommand (required by ALL classes that extend SfdxFalconCommand). this.sfdxFalconCommandInit('falcon:adk:create', SfdxFalconCommandType.APPX_DEMO); @@ -102,30 +100,31 @@ export default class FalconDemoCreate extends SfdxFalconYeomanCommand { outputDir: this.outputDirectory, options: [] }) - .then(statusReport => {this.onSuccess(statusReport)}) // <-- Preps this.falconJsonResponse for return - .catch(error => {this.onError(error)}); // <-- Wraps any errors and displays to user + .then(generatorResult => this.onSuccess(generatorResult)) // Implemented by parent class + .catch(generatorResult => this.onError(generatorResult)); // Implemented by parent class // Return the JSON Response that was created by onSuccess() - return this.falconJsonResponse; + return this.falconJsonResponse as unknown as AnyJson; } //───────────────────────────────────────────────────────────────────────────┐ /** * @method buildFinalError - * @param {SfdxFalconError} cmdError Required. Error object used as - * the basis for the "friendly error message" being created + * @param {SfdxFalconError} cmdError Required. Error object used as + * the basis for the "friendly error message" being created * by this method. * @returns {SfdxError} * @description Builds a user-friendly error message that is appropriate to * the CLI command that's being implemented by this class. The * output of this method will always be used by the onError() - * method from the base class to communicate the end-of-command + * method from the base class to communicate the end-of-command * error state. * @protected */ //───────────────────────────────────────────────────────────────────────────┘ protected buildFinalError(cmdError:SfdxFalconError):SfdxError { + // If not implementing anything special here, simply return cmdError. return cmdError; } -} \ No newline at end of file +} diff --git a/src/commands/falcon/adk/install.ts b/src/commands/falcon/adk/install.ts index 4d5c3f6..c92d265 100644 --- a/src/commands/falcon/adk/install.ts +++ b/src/commands/falcon/adk/install.ts @@ -65,13 +65,6 @@ export default class FalconDemoInstall extends SfdxFalconCommand { ` --configfile my-alternate-demo-config.json` ]; - // Identify the core SFDX arguments/features required by this command. - protected static requiresProject = false; // True if an SFDX Project workspace is REQUIRED. - protected static requiresUsername = false; // True if an org username is REQUIRED. - protected static requiresDevhubUsername = false; // True if a hub org username is REQUIRED. - protected static supportsUsername = false; // True if an org username is OPTIONAL. - protected static supportsDevhubUsername = false; // True if a hub org username is OPTIONAL. - //───────────────────────────────────────────────────────────────────────────┐ // -d --PROJECTDIR Directory where a fully configured AppX Demo Kit (ADK) // project exists. All commands for deployment must be @@ -106,10 +99,17 @@ export default class FalconDemoInstall extends SfdxFalconCommand { ...SfdxFalconCommand.falconBaseflagsConfig }; + // Identify the core SFDX arguments/features required by this command. + protected static requiresProject = false; // True if an SFDX Project workspace is REQUIRED. + protected static requiresUsername = false; // True if an org username is REQUIRED. + protected static requiresDevhubUsername = false; // True if a hub org username is REQUIRED. + protected static supportsUsername = false; // True if an org username is OPTIONAL. + protected static supportsDevhubUsername = false; // True if a hub org username is OPTIONAL. + //───────────────────────────────────────────────────────────────────────────┐ /** * @function run - * @returns {Promise} This should resolve by returning a JSON object + * @returns {Promise} This should resolve by returning a JSON object * that the CLI will then forward to the user if the --json flag * was set when this command was called. * @description Entrypoint function used by the CLI when the user wants to diff --git a/src/commands/falcon/apk/clone.ts b/src/commands/falcon/apk/clone.ts index 198191d..a060d30 100644 --- a/src/commands/falcon/apk/clone.ts +++ b/src/commands/falcon/apk/clone.ts @@ -16,23 +16,25 @@ import {flags} from '@salesforce/command'; // Allows creation of flags for CLI commands. import {Messages} from '@salesforce/core'; // Messages library that simplifies using external JSON for string reuse. import {SfdxError} from '@salesforce/core'; // Generalized SFDX error which also contains an action. +import {AnyJson} from '@salesforce/ts-types'; // Safe type for use where "any" might otherwise be used. // Import Internal Modules -import {SfdxFalconYeomanCommand} from '../../../modules/sfdx-falcon-yeoman-command'; // Base class that CLI commands in this project that use Yeoman should use. import {SfdxFalconError} from '../../../modules/sfdx-falcon-error'; // Extends SfdxError to provide specialized error structures for SFDX-Falcon modules. +import {isGitUriValid} from '../../../modules/sfdx-falcon-util/git'; // Function. Validates a Git URI. +import {SfdxFalconYeomanCommand} from '../../../modules/sfdx-falcon-yeoman-command'; // Base class that CLI commands in this project that use Yeoman should use. // Import Internal Types import {SfdxFalconCommandType} from '../../../modules/sfdx-falcon-command'; // Enum. Represents the types of SFDX-Falcon Commands. // Set the File Local Debug Namespace -//const dbgNs = 'COMMAND:falcon-apk-clone:'; -//const clsDbgNs = 'FalconApkClone:'; +const dbgNs = 'COMMAND:falcon-apk-clone:'; // Use SfdxCore's Messages framework to get the message bundle for this command. Messages.importMessagesDirectory(__dirname); const baseMessages = Messages.loadMessages('sfdx-falcon', 'sfdxFalconCommand'); const commandMessages = Messages.loadMessages('sfdx-falcon', 'falconApkClone'); + //─────────────────────────────────────────────────────────────────────────────────────────────────┐ /** * @class FalconApkClone @@ -42,7 +44,6 @@ const commandMessages = Messages.loadMessages('sfdx-falcon', 'falconApkClone'); * existing project based on the SFDX-Falcon template. After the project is cloned, * the user is taken through an interview to help set up developer-specific project * variables. - * @version 1.0.0 * @public */ //─────────────────────────────────────────────────────────────────────────────────────────────────┘ @@ -58,15 +59,8 @@ export default class FalconApkClone extends SfdxFalconYeomanCommand { ` --outputdir ~/projects/appexchange-package-kit-projects` ]; - // Identify the core SFDX arguments/features required by this command. - protected static requiresProject = false; // True if an SFDX Project workspace is REQUIRED. - protected static requiresUsername = false; // True if an org username is REQUIRED. - protected static requiresDevhubUsername = false; // True if a hub org username is REQUIRED. - protected static supportsUsername = false; // True if an org username is OPTIONAL. - protected static supportsDevhubUsername = false; // True if a hub org username is OPTIONAL. - //───────────────────────────────────────────────────────────────────────────┐ - // Define the ARGUMENTS used by this command. + // Define the ARGUMENTS used by this command. // Position 1 (GIT_REMOTE_URI) - URI of the git repository being cloned. // Position 2 (GIT_CLONE_DIR) - Name of the locally cloned repo directory. //───────────────────────────────────────────────────────────────────────────┘ @@ -92,7 +86,7 @@ export default class FalconApkClone extends SfdxFalconYeomanCommand { //───────────────────────────────────────────────────────────────────────────┘ protected static flagsConfig = { outputdir: flags.directory({ - char: 'd', + char: 'd', required: false, description: commandMessages.getMessage('outputdir_FlagDescription'), default: '.', @@ -103,21 +97,42 @@ export default class FalconApkClone extends SfdxFalconYeomanCommand { ...SfdxFalconYeomanCommand.falconBaseflagsConfig }; + // Identify the core SFDX arguments/features required by this command. + protected static requiresProject = false; // True if an SFDX Project workspace is REQUIRED. + protected static requiresUsername = false; // True if an org username is REQUIRED. + protected static requiresDevhubUsername = false; // True if a hub org username is REQUIRED. + protected static supportsUsername = false; // True if an org username is OPTIONAL. + protected static supportsDevhubUsername = false; // True if a hub org username is OPTIONAL. + //───────────────────────────────────────────────────────────────────────────┐ /** * @function run - * @returns {Promise} Resolves with a JSON object that the CLI will - * pass to the user as stdout if the --json flag was set. + * @returns {Promise} Resolves with a JSON object that the CLI + * will pass to the user as stdout if the --json flag was set. * @description Entrypoint function for "sfdx falcon:apk:clone". - * @version 1.0.0 * @public @async */ //───────────────────────────────────────────────────────────────────────────┘ - public async run(): Promise { + public async run():Promise { // Initialize the SfdxFalconCommand (required by ALL classes that extend SfdxFalconCommand). this.sfdxFalconCommandInit('falcon:apk:clone', SfdxFalconCommandType.APPX_PACKAGE); + // Validate the gitRemoteUri passed in by the CLI Command + if (isGitUriValid(this.gitRemoteUri) === false) { + throw new SfdxFalconError( `The value '${this.gitRemoteUri}' is not a valid Git Remote URI.` + , `InvalidGitUri` + , `${dbgNs}run`); + } + + // Make sure the gitRemoteUri uses the https protocol. + // Makes it less likey the user will hang on SSH messages. + if (this.gitRemoteUri.substr(0, 8) !== 'https://') { + throw new SfdxFalconError( `Git Remote URI must use the https protocol (ex. 'https://github.com/GitHubUser/my-repository.git')` + , `InvalidGitUriProtocol` + , `${dbgNs}run`); + } + // Run a Yeoman Generator to interact with and run tasks for the user. await super.runYeomanGenerator({ generatorType: 'clone-appx-package-project', @@ -126,30 +141,31 @@ export default class FalconApkClone extends SfdxFalconYeomanCommand { gitCloneDir: this.gitCloneDirectory, options: [] }) - .then(statusReport => {this.onSuccess(statusReport)}) // <-- Preps this.falconJsonResponse for return - .catch(error => {this.onError(error)}); // <-- Wraps any errors and displays to user + .then(generatorResult => this.onSuccess(generatorResult)) // Implemented by parent class + .catch(generatorResult => this.onError(generatorResult)); // Implemented by parent class // Return the JSON Response that was created by onSuccess() - return this.falconJsonResponse; + return this.falconJsonResponse as unknown as AnyJson; } //───────────────────────────────────────────────────────────────────────────┐ /** * @method buildFinalError - * @param {SfdxFalconError} cmdError Required. Error object used as - * the basis for the "friendly error message" being created + * @param {SfdxFalconError} cmdError Required. Error object used as + * the basis for the "friendly error message" being created * by this method. * @returns {SfdxError} * @description Builds a user-friendly error message that is appropriate to * the CLI command that's being implemented by this class. The * output of this method will always be used by the onError() - * method from the base class to communicate the end-of-command + * method from the base class to communicate the end-of-command * error state. * @protected */ //───────────────────────────────────────────────────────────────────────────┘ protected buildFinalError(cmdError:SfdxFalconError):SfdxError { + // If not implementing anything special here, simply return cmdError. return cmdError; - } -} \ No newline at end of file + } +} diff --git a/src/generators/clone-appx-demo-project.ts b/src/generators/clone-appx-demo-project.ts index 1684f5b..2ae65f8 100644 --- a/src/generators/clone-appx-demo-project.ts +++ b/src/generators/clone-appx-demo-project.ts @@ -32,7 +32,7 @@ import {GeneratorOptions} from '../modules/sfdx-falcon-yeoman-com import {SfdxFalconYeomanGenerator} from '../modules/sfdx-falcon-yeoman-generator'; // Class. Abstract base class class for building Yeoman Generators for SFDX-Falcon commands. // Requires -const chalk = require('chalk'); // Utility for creating colorful console output. +const chalk = require('chalk'); // Utility for creating colorful console output. // Set the File Local Debug Namespace const dbgNs = 'GENERATOR:clone-appx-demo:'; @@ -67,10 +67,10 @@ interface InterviewAnswers { export default class CloneAppxDemoProject extends SfdxFalconYeomanGenerator { // Define class members specific to this Generator. - private devHubAliasChoices: YeomanChoice[]; // Array of DevOrg aliases/usernames in the form of Yeoman choices. - private envHubAliasChoices: YeomanChoice[]; // Array of EnvHub aliases/usernames in the form of Yeoman choices. - private gitRemoteUri: string; // URI of the Git repo to clone. - private gitCloneDirectory: string; // Name of the Git repo directory once cloned to local storage. + protected devHubAliasChoices: YeomanChoice[]; // Array of DevOrg aliases/usernames in the form of Yeoman choices. + protected envHubAliasChoices: YeomanChoice[]; // Array of EnvHub aliases/usernames in the form of Yeoman choices. + protected gitRemoteUri: string; // URI of the Git repo to clone. + protected gitCloneDirectory: string; // Name of the Git repo directory once cloned to local storage. //───────────────────────────────────────────────────────────────────────────┐ /** @@ -122,11 +122,11 @@ export default class CloneAppxDemoProject extends SfdxFalconYeomanGenerator { // Call the default initializing() function. Replace with custom behavior if desired. - return super.default_initializing(); + return super._default_initializing(); } //───────────────────────────────────────────────────────────────────────────┐ @@ -228,7 +228,7 @@ export default class CloneAppxDemoProject extends SfdxFalconYeomanGenerator { // Call the default prompting() function. Replace with custom behavior if desired. - return super.default_prompting(); + return super._default_prompting(); } //───────────────────────────────────────────────────────────────────────────┐ @@ -240,10 +240,10 @@ export default class CloneAppxDemoProject extends SfdxFalconYeomanGenerator