diff --git a/src/cli/cli.controller.ts b/src/cli/cli.controller.ts index c53744c3..cfb33033 100644 --- a/src/cli/cli.controller.ts +++ b/src/cli/cli.controller.ts @@ -138,7 +138,11 @@ export class CliController { private initUi(): void { this.uiHeader = new HeaderUi(this.config); this.uiService.add(this.uiHeader); - this.uiResults = new ResultsUi(this.resultsService, this.consoleService); + this.uiResults = new ResultsUi( + this.resultsService, + this.consoleService, + this.config, + ); this.uiService.add(this.uiResults); this.uiStats = new StatsUi(this.config, this.resultsService, this.logger); this.uiService.add(this.uiStats); @@ -535,6 +539,10 @@ export class CliController { this.config.jsonSimple = true; } + if (options.isTrue('disable-size')) { + this.config.disableSize = true; + } + if (this.config.jsonStream && this.config.jsonSimple) { this.logger.error(ERROR_MSG.CANT_USE_BOTH_JSON_OPTIONS); this.exitWithError(); @@ -756,21 +764,31 @@ export class CliController { this.uiStatus.start(); this.searchStart = Date.now(); - this.scanSubscription = this.scanService + const scan$ = this.scanService .scan(this.config) - .pipe( - tap((nodeFolder) => this.processNodeFolderForUi(nodeFolder)), - mergeMap( - (nodeFolder) => this.scanService.calculateFolderStats(nodeFolder), - 10, // Limit to 10 concurrent stat calculations at a time - ), - tap((folder) => this.processFolderStatsForUi(folder)), - ) - .subscribe({ + .pipe(tap((nodeFolder) => this.processNodeFolderForUi(nodeFolder))); + + if (this.config.disableSize) { + this.scanSubscription = scan$.subscribe({ next: () => this.printFoldersSection(), error: (error) => this.newError(error), complete: () => this.completeSearch(), }); + } else { + this.scanSubscription = scan$ + .pipe( + mergeMap( + (nodeFolder) => this.scanService.calculateFolderStats(nodeFolder), + 10, // Limit to 10 concurrent stat calculations at a time + ), + tap((folder) => this.processFolderStatsForUi(folder)), + ) + .subscribe({ + next: () => this.printFoldersSection(), + error: (error) => this.newError(error), + complete: () => this.completeSearch(), + }); + } } private setupJsonModeSignalHandlers(): void { @@ -792,6 +810,10 @@ export class CliController { this.uiResults.clear(); } + if (this.config.disableSize && this.config.deleteAll) { + this.deleteFolder(nodeFolder); + } + this.uiResults.render(); } diff --git a/src/cli/interfaces/config.interface.ts b/src/cli/interfaces/config.interface.ts index ff6a6875..9bbae615 100644 --- a/src/cli/interfaces/config.interface.ts +++ b/src/cli/interfaces/config.interface.ts @@ -14,4 +14,5 @@ export interface IConfig { yes: boolean; jsonStream: boolean; jsonSimple: boolean; + disableSize: boolean; } diff --git a/src/cli/ui/components/results.ui.ts b/src/cli/ui/components/results.ui.ts index ee6ddae0..5bfa3532 100644 --- a/src/cli/ui/components/results.ui.ts +++ b/src/cli/ui/components/results.ui.ts @@ -47,7 +47,7 @@ export class ResultsUi extends HeavyUi implements InteractiveUi { private searchText = ''; private filteredResults: CliScanFoundFolder[] = []; - private readonly config: IConfig = DEFAULT_CONFIG; + private config: IConfig = DEFAULT_CONFIG; private readonly KEYS = { up: () => this.cursorUp(), down: () => this.cursorDown(), @@ -78,8 +78,12 @@ export class ResultsUi extends HeavyUi implements InteractiveUi { constructor( private readonly resultsService: ResultsService, private readonly consoleService: ConsoleService, + config?: IConfig, ) { super(); + if (config) { + this.config = config; + } } private openFolder(): void { @@ -512,7 +516,12 @@ export class ResultsUi extends HeavyUi implements InteractiveUi { // Only show "..." if size is exactly 0 AND modificationTime is -1 (not yet calculated) // If size is 0 but modificationTime is set, then it's a truly empty folder const isCalculating = folder.size === 0 && folder.modificationTime === -1; - const folderSizeText = isCalculating ? pc.gray(' .....') : folderSize; + let folderSizeText: string; + if (this.config.disableSize) { + folderSizeText = pc.gray(' ...'); + } else { + folderSizeText = isCalculating ? pc.gray(' .....') : folderSize; + } return { path: folderText, diff --git a/src/constants/cli.constants.ts b/src/constants/cli.constants.ts index 3ce4cf08..0075b804 100644 --- a/src/constants/cli.constants.ts +++ b/src/constants/cli.constants.ts @@ -96,6 +96,12 @@ export const OPTIONS: ICliOptions[] = [ description: 'Output results in a JSON format.', name: 'jsonSimple', }, + { + arg: ['--disable-size'], + description: + 'Skip size and age calculation. Useful for faster scanning and deletion when space info is not needed.', + name: 'disable-size', + }, { arg: ['-v', '--version'], description: 'Show version.', diff --git a/src/constants/main.constants.ts b/src/constants/main.constants.ts index cb79aa97..53a16a3a 100644 --- a/src/constants/main.constants.ts +++ b/src/constants/main.constants.ts @@ -24,6 +24,7 @@ export const DEFAULT_CONFIG: IConfig = { yes: false, jsonStream: false, jsonSimple: false, + disableSize: false, }; export const MARGINS = { diff --git a/tests/cli/services/scan.service.test.ts b/tests/cli/services/scan.service.test.ts index e9db7113..e7687d8a 100644 --- a/tests/cli/services/scan.service.test.ts +++ b/tests/cli/services/scan.service.test.ts @@ -35,6 +35,7 @@ describe('ScanService', () => { yes: false, jsonStream: false, jsonSimple: false, + disableSize: false, }; const mockScanFoundFolder: ScanFoundFolder = {