UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

115 lines (108 loc) 6.51 kB
/* jscpd:ignore-start */ import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core'; import { Messages, SfError } from '@salesforce/core'; import c from 'chalk'; import fs from 'fs-extra'; import * as path from 'path'; import { execCommand, uxLog } from '../../../../../common/utils/index.js'; import { promptOrg } from '../../../../../common/utils/orgUtils.js'; import { prompts } from '../../../../../common/utils/prompts.js'; import { PACKAGE_ROOT_DIR } from '../../../../../settings.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class DxSources2 extends SfCommand { static title = 'Retrieve sfdx sources from org (2)'; static description = ` ## Command Behavior **Retrieves Salesforce metadata from an org into SFDX source format, offering flexible input options for specifying metadata to retrieve.** This command provides an alternative and enhanced way to pull metadata from any Salesforce org into your local SFDX project. It's particularly useful when you need fine-grained control over which metadata components are retrieved, either by providing a custom \`package.xml\` or by using predefined templates. Key functionalities: - **\`package.xml\` Input:** You can specify the path to a \`package.xml\` file using the \`--packagexml\` flag, which defines the exact metadata components to retrieve. - **Template-Based Retrieval:** Use the \`--template\` flag to leverage predefined \`package.xml\` templates provided by sfdx-hardis (e.g., \`wave\` for CRM Analytics metadata), simplifying common retrieval scenarios. - **Interactive Input:** If neither \`--packagexml\` nor \`--template\` is provided, the command will interactively prompt you to select a \`package.xml\` file or a template. - **Target Org Selection:** Allows you to specify the Salesforce org from which to retrieve the sources. If not provided, it will prompt for selection. <details markdown="1"> <summary>Technical explanations</summary> The command's technical implementation involves: - **Org Selection:** It uses \`promptOrg\` to guide the user in selecting the target Salesforce org if not provided via flags. - **\`package.xml\` Resolution:** It determines the \`package.xml\` to use based on the provided flags (\`--packagexml\` or \`--template\`). If a template is used, it resolves the path to the corresponding template file within the sfdx-hardis installation. - **File System Operations:** It checks if the specified \`package.xml\` file exists. If the file is outside the current project directory, it copies it to a temporary location within the project to ensure proper handling by the Salesforce CLI. - **Salesforce CLI Retrieval:** It executes the \`sf project retrieve start\` command, passing the resolved \`package.xml\` path and the target username to retrieve the sources. - **User Feedback:** Provides clear messages to the user about the retrieval process and its success. </details> `; static examples = ['$ sf hardis:org:retrieve:sources:dx2']; static flags = { packagexml: Flags.string({ char: 'x', description: 'Path to package.xml file', }), template: Flags.string({ char: 't', description: 'sfdx-hardis package.xml Template name. ex: wave', }), debug: Flags.boolean({ char: 'd', default: false, description: messages.getMessage('debugMode'), }), websocket: Flags.string({ description: messages.getMessage('websocket'), }), skipauth: Flags.boolean({ description: 'Skip authentication check when a default username is required', }), 'target-org': requiredOrgFlagWithDeprecations, }; // Set this to true if your command requires a project workspace; 'requiresProject' is false by default static requiresProject = true; debugMode = false; /* jscpd:ignore-end */ async run() { const { flags } = await this.parse(DxSources2); let packageXml = flags.packagexml || null; let targetUsername = flags['target-org']?.getUsername() || null; const template = flags.template || null; this.debugMode = flags.debug || false; // Prompt for organization if not sent if (targetUsername == null) { const org = await promptOrg(this, { setDefault: false }); targetUsername = org.username; } // Use package.xml template provided by sfdx-hardis if (template) { packageXml = path.join(PACKAGE_ROOT_DIR, `ref`, `${template}-package.xml`); } // Prompt for package.xml if not sent if (packageXml === null) { const packageXmlRes = await prompts({ message: c.cyanBright('Please input the path to the package.xml file'), description: 'Specify the package.xml file that defines which metadata to retrieve from the org', placeholder: 'Ex: manifest/package.xml', type: 'text', name: 'value', }); packageXml = packageXmlRes.value; } // Check package.xml file exists if (!fs.existsSync(packageXml || '')) { throw new SfError(c.red('Package.xml file not found at ' + packageXml)); } // Copy package.xml in /tmp if provided value is not within project if (!path.resolve(packageXml || '').includes(path.resolve(process.cwd()))) { const packageXmlTmp = path.join(process.cwd(), 'tmp', 'retrievePackage.xml'); await fs.ensureDir(path.dirname(packageXmlTmp)); await fs.copy(packageXml || '', packageXmlTmp); uxLog("log", this, c.grey(`Copied ${packageXml} to ${packageXmlTmp}`)); packageXml = path.relative(process.cwd(), packageXmlTmp); } // Retrieve sources const retrieveCommand = 'sf project retrieve start' + ` -x "${packageXml}"` + ` -o ${targetUsername}`; await execCommand(retrieveCommand, this, { fail: false, debug: this.debugMode, output: true }); // Set bac initial cwd const message = `[sfdx-hardis] Successfully retrieved sfdx sources from ${c.bold(targetUsername)} using ${c.bold(packageXml)}`; uxLog("success", this, c.green(message)); return { outputString: message }; } } //# sourceMappingURL=dx2.js.map