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

111 lines (104 loc) 5.29 kB
/* jscpd:ignore-start */ import { SfCommand, Flags } from '@salesforce/sf-plugins-core'; import { Messages } from '@salesforce/core'; import c from 'chalk'; import { glob } from 'glob'; import * as path from 'path'; import { uxLog } from '../../../../common/utils/index.js'; import fs from 'fs-extra'; import { GLOB_IGNORE_PATTERNS } from '../../../../common/utils/projectUtils.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class CleanSystemDebug extends SfCommand { static title = 'Clean System debug'; static description = ` ## Command Behavior **Removes or comments out \`System.debug()\` statements from Apex classes and triggers in your Salesforce DX project.** This command helps maintain clean and optimized Apex code by eliminating debug statements that are often left in production code. While \`System.debug()\` is invaluable during development, it can impact performance and expose sensitive information if left in deployed code. Key functionalities: - **Targeted File Scan:** Scans all Apex class (.cls) and trigger (.trigger) files within the specified root folder (defaults to \`force-app\`). - **Conditional Action:** - **Comment Out (default):** By default, it comments out \`System.debug()\` lines by prepending // to them. - **Delete (\`--delete\` flag):** If the \`--delete\` flag is used, it completely removes the lines containing \`System.debug()\`. - **Exclusion:** Lines containing \`NOPMD\` are ignored, allowing developers to intentionally keep specific debug statements. <details markdown="1"> <summary>Technical explanations</summary> The command's technical implementation involves: - **File Discovery:** Uses \`glob\` to find all Apex class and trigger files. - **Content Reading:** Reads the content of each Apex file line by line. - **Pattern Matching:** Checks each line for the presence of \`System.debug\` (case-insensitive). - **Line Modification:** - If \`System.debug\` is found and the \`--delete\` flag is not used, it modifies the line to comment out the debug statement. - If \`System.debug\` is found and the \`--delete\` flag is used, it removes the line entirely. - **File Writing:** If any changes are made to a file, the modified content is written back to the file using \`fs.writeFile\`. - **Logging:** Provides a summary of how many files were cleaned. </details> `; static examples = ['$ sf hardis:project:clean:systemdebug']; static flags = { folder: Flags.string({ char: 'f', default: 'force-app', description: 'Root folder', }), websocket: Flags.string({ description: messages.getMessage('websocket'), }), skipauth: Flags.boolean({ description: 'Skip authentication check when a default username is required', }), delete: Flags.boolean({ char: 'd', default: false, description: 'Delete lines with System.debug', }), }; // Set this to true if your command requires a project workspace; 'requiresProject' is false by default static requiresProject = true; folder; del = false; async run() { const { flags } = await this.parse(CleanSystemDebug); this.folder = flags.folder || './force-app'; this.del = flags.delete || false; // Delete standard files when necessary uxLog("action", this, c.cyan(`Comment or delete System.debug line in apex classes and triggers`)); /* jscpd:ignore-end */ const rootFolder = path.resolve(this.folder); const findManagedPattern = rootFolder + `/**/*.{cls,trigger}`; const matchingFiles = await glob(findManagedPattern, { cwd: process.cwd(), ignore: GLOB_IGNORE_PATTERNS }); let countFiles = 0; for (const apexFile of matchingFiles) { const fileText = await fs.readFile(apexFile, 'utf8'); const fileLines = fileText.split('\n'); let counter = 0; let writeF = false; for (const line of fileLines) { if ((line.includes('System.debug') || line.includes('system.debug')) && !line.includes('NOPMD')) { if (!this.del && line.trim().substring(0, 2) != '//') { fileLines[counter] = line .replace('System.debug', '// System.debug') .replace('system.debug', '// system.debug'); writeF = true; } else if (this.del) { delete fileLines[counter]; writeF = true; } } counter++; } if (writeF) { const joinLines = fileLines.join('\n'); await fs.writeFile(apexFile, joinLines, 'utf8'); countFiles++; } } // Summary const msg = `Cleaned ${c.green(c.bold(countFiles))} class(es) and trigger(s)`; uxLog("action", this, c.cyan(msg)); // Return an object to be displayed with --json return { outputString: msg }; } } //# sourceMappingURL=systemdebug.js.map