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