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

140 lines (138 loc) 6.8 kB
/* jscpd:ignore-start */ import { SfCommand, Flags } from '@salesforce/sf-plugins-core'; import { Messages } from '@salesforce/core'; import c from "chalk"; import * as path from "path"; import { ensureGitRepository, git, isCI, uxLog, } from '../../../../common/utils/index.js'; import { prompts } from '../../../../common/utils/prompts.js'; import moment from 'moment'; import { generateFlowVisualGitDiff, generateHistoryDiffMarkdown } from '../../../../common/utils/mermaidUtils.js'; import { MetadataUtils } from '../../../../common/metadata-utils/index.js'; import { WebSocketClient } from '../../../../common/websocketClient.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class GenerateFlowGitDiff extends SfCommand { static title = 'Generate Flow Visual Gif Diff'; static description = `Generate Flow Visual Git Diff markdown between 2 commits Note: This command might requires @mermaid-js/mermaid-cli to be installed. Run \`npm install @mermaid-js/mermaid-cli --global\` `; static examples = [ '$ sf hardis:project:generate:flow-git-diff', '$ sf hardis:project:generate:flow-git-diff --flow "force-app/main/default/flows/Opportunity_AfterUpdate_Cloudity.flow-meta.xml" --commit-before 8bd290e914c9dbdde859dad7e3c399776160d704 --commit-after e0835251bef6e400fb91e42f3a31022f37840f65' ]; static flags = { flow: Flags.string({ description: 'Path to flow file (will be prompted if not set)', }), "commit-before": Flags.string({ description: 'Hash of the commit of the previous flow state, or "allStates" (will be prompted if not set)', default: "" }), "commit-after": Flags.string({ description: 'Hash of the commit of the new flow state (will be prompted if not set)', default: "", }), 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', }), }; // Set this to true if your command requires a project workspace; 'requiresProject' is false by default static requiresProject = true; flowFile; flowLabel; commitBefore = ""; commitAfter = ""; debugMode = false; /* jscpd:ignore-end */ async run() { const { flags } = await this.parse(GenerateFlowGitDiff); this.flowFile = flags.flow || ""; this.commitBefore = flags["commit-before"] || ""; this.commitAfter = flags["commit-after"] || ""; this.debugMode = flags.debug || false; // Check git repo await ensureGitRepository(); // Prompt flow file if not send as input param if (this.flowFile == "" && !isCI) { this.flowFile = await MetadataUtils.promptFlow(); } this.flowLabel = path.basename(this.flowFile, ".flow-meta.xml"); // List states of flow file using git const fileHistory = await git().log({ file: this.flowFile }); if (fileHistory.all.length === 1) { uxLog("success", this, c.green(`There is only one state for Flow ${this.flowFile}`)); return {}; } // Build prompt choices let allChoices = []; if ((this.commitBefore === "" || this.commitAfter === "") && !isCI) { allChoices = fileHistory.all.map(log => { return { value: log.hash, title: `${moment(log.date).format("ll")}: ${log.message}`, description: `By ${log.author_name}(${log.author_email}) in ${log.refs}` }; }); } // Prompt commits if not sent as input parameter if (this.commitBefore === "" && !isCI) { const commitBeforeSelectRes = await prompts({ type: 'select', name: 'before', message: 'Please select BEFORE UPDATE commit', description: 'Choose the commit representing the state before your changes', placeholder: 'Select a commit', choices: [...allChoices, ...[ { title: "Calculate for all Flow states", value: "allStates", description: "Requires mkdocs-material to be read correctly. If you do not have it, we advise to select 2 commits for comparison." } ]] }); this.commitBefore = commitBeforeSelectRes.before; } let diffMdFile; if (this.commitBefore === "allStates") { diffMdFile = await generateHistoryDiffMarkdown(this.flowFile, this.debugMode); } else { if (this.commitAfter === "" && !isCI) { // Compute between 2 commits: prompt for the second one const commitAfterSelectRes = await prompts({ type: 'select', name: 'after', message: 'Please select AFTER UPDATE commit', description: 'Choose the commit representing the state after your changes', placeholder: 'Select a commit', choices: allChoices }); this.commitAfter = commitAfterSelectRes.after; } // Generate diff const { outputDiffMdFile } = await generateFlowVisualGitDiff(this.flowFile, this.commitBefore, this.commitAfter, { svgMd: true, pngMd: false, mermaidMd: this.debugMode, debug: this.debugMode }); diffMdFile = outputDiffMdFile; } // Open file in a new VS Code tab if available WebSocketClient.requestOpenFile(path.relative(process.cwd(), diffMdFile)); WebSocketClient.sendReportFileMessage(diffMdFile, path.basename(diffMdFile).replace(".md", "") + " Documentation", 'report'); uxLog("action", this, c.green(`Markdown Flow diff documentation generated for ${path.basename(diffMdFile).replace(".md", "")}.`)); if (this.commitBefore === "allStates") { uxLog("warning", this, c.yellow(`It is recommended to use mkdocs-material to read it correctly (see https://sfdx-hardis.cloudity.com/hardis/doc/project2markdown/#doc-html-pages)`)); } // Return an object to be displayed with --json return { diffMdFile: diffMdFile }; } } //# sourceMappingURL=flow-git-diff.js.map