diff --git a/src/commands/force/source/delete.ts b/src/commands/force/source/delete.ts index b3103e90b..6db09a427 100644 --- a/src/commands/force/source/delete.ts +++ b/src/commands/force/source/delete.ts @@ -5,6 +5,7 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import * as os from 'os'; +import * as path from 'path'; import { confirm } from 'cli-ux/lib/prompt'; import { flags, FlagsConfig } from '@salesforce/command'; import { fs, Messages } from '@salesforce/core'; @@ -192,10 +193,40 @@ export class Delete extends DeployCommand { } } + // TODO: maybe move to fs in sfdx-core? + private readDirectoryRecursively(directory: string): string[] { + const files: string[] = []; + + const filesInDirectory = fs.readdirSync(directory); + for (const file of filesInDirectory) { + const absolute = path.join(directory, file); + if (fs.statSync(absolute).isDirectory()) { + files.push(...this.readDirectoryRecursively(absolute)); + } else { + files.push(absolute); + } + } + return files; + } + private async handlePrompt(): Promise { if (!this.getFlag('noprompt')) { - const paths = this.sourceComponents.map((component) => component.content + '\n' + component.xml).join('\n'); - const promptMessage = messages.getMessage('prompt', [paths]); + const paths: string[] = []; + this.sourceComponents.map((component) => { + if (component.content) { + if (fs.lstatSync(component.content).isDirectory()) { + // display all paths in the folder to be deleted + paths.push(...this.readDirectoryRecursively(component.content)); + } else { + paths.push(component.content); + } + } + // this will prevent displaying the xml file twice in the confirmation + if (component.xml && !paths.includes(component.xml)) { + paths.push(component.xml); + } + }); + const promptMessage = messages.getMessage('prompt', [paths.join('\n')]); return confirm(promptMessage); } diff --git a/src/formatters/deleteResultFormatter.ts b/src/formatters/deleteResultFormatter.ts index b1b468135..6076bd2f8 100644 --- a/src/formatters/deleteResultFormatter.ts +++ b/src/formatters/deleteResultFormatter.ts @@ -35,4 +35,25 @@ export class DeleteResultFormatter extends DeployResultFormatter { this.ux.styledHeader(chalk.blue('Deleted Source')); this.ux.log('No results found'); } + + protected displaySuccesses(): void { + if (this.isSuccess() && this.fileResponses?.length) { + const successes = this.fileResponses.filter((f) => f.state !== 'Failed'); + if (!successes.length) { + return; + } + this.sortFileResponses(successes); + this.asRelativePaths(successes); + + this.ux.log(''); + this.ux.styledHeader(chalk.blue('Deleted Source')); + this.ux.table(successes, { + columns: [ + { key: 'fullName', label: 'FULL NAME' }, + { key: 'type', label: 'TYPE' }, + { key: 'filePath', label: 'PROJECT PATH' }, + ], + }); + } + } }