diff --git a/CHANGELOG.md b/CHANGELOG.md index 49bfc827..eb804c22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +## [4.2.2] + +### Added + +- improved progress bar and status bar message + ## [4.2.1] - 2022-05-21 ### Added diff --git a/src/ConfigOfExecGroup.ts b/src/ConfigOfExecGroup.ts index 9cc4f332..e69b064e 100644 --- a/src/ConfigOfExecGroup.ts +++ b/src/ConfigOfExecGroup.ts @@ -22,6 +22,7 @@ import { debugBreak } from './util/DevelopmentHelper'; import { FrameworkType } from './framework/Framework'; import { readFileSync } from 'fs'; import { getModiTime } from './Util'; +import { SubProgressReporter } from './util/ProgressReporter'; /// @@ -57,7 +58,7 @@ export class ConfigOfExecGroup implements vscode.Disposable { private readonly _executables: Map = new Map(); - async load(): Promise { + async load(progressReporter: SubProgressReporter): Promise { const pattern = await this._pathProcessor(this._pattern); this._shared.log.info('pattern', this._pattern, this._shared.workspaceFolder.uri.fsPath, pattern); @@ -99,6 +100,7 @@ export class ConfigOfExecGroup implements vscode.Disposable { this._shared.log.exceptionS(e, "Couldn't watch pattern"); } + progressReporter.setMax(filePaths.length); const suiteCreationAndLoadingTasks: Promise[] = []; for (let i = 0; i < filePaths.length; i++) { @@ -145,6 +147,7 @@ export class ConfigOfExecGroup implements vscode.Disposable { } catch (reason) { this._shared.log.debug('Not an executable:', file, reason); } + progressReporter.incrementBy1(); })(), ); } diff --git a/src/WorkspaceManager.ts b/src/WorkspaceManager.ts index ff32fb1f..8bf2b864 100644 --- a/src/WorkspaceManager.ts +++ b/src/WorkspaceManager.ts @@ -10,6 +10,7 @@ import { ConfigOfExecGroup } from './ConfigOfExecGroup'; import { generateId } from './Util'; import { AbstractTest } from './framework/AbstractTest'; import { TestItemManager } from './TestItemManager'; +import { ProgressReporter } from './util/ProgressReporter'; //TODO:release if workspace contains ".vscode/testMate.cpp.json" we have to start loading the tests export class WorkspaceManager implements vscode.Disposable { @@ -209,10 +210,12 @@ export class WorkspaceManager implements vscode.Disposable { async load(): Promise { this._executableConfig.forEach(c => c.dispose()); + const sbm = vscode.window.setStatusBarMessage('TestMate C++: loading tests...'); + return vscode.window.withProgress( { location: { viewId: 'workbench.view.extension.test' } }, async ( - _progress: vscode.Progress<{ message?: string; increment?: number }>, + progress: vscode.Progress<{ message?: string; increment?: number }>, _token: vscode.CancellationToken, ): Promise => { await new Promise(r => setTimeout(r, 500)); // there are some race condition, this fixes it: maybe async dispose would fix it too? @@ -220,8 +223,15 @@ export class WorkspaceManager implements vscode.Disposable { const configuration = this._getConfiguration(this.log); const executableConfig = configuration.getExecutableConfigs(this._shared); this._executableConfig = executableConfig; + const progressReporter = new ProgressReporter(progress); - await Promise.allSettled(executableConfig.map(x => x.load().catch(e => this.log.errorS(e)))); + await Promise.allSettled( + executableConfig.map(x => { + const subProgressReporter = progressReporter.createSubProgressReporter(); + return x.load(subProgressReporter).catch(e => this.log.errorS(e)); + }), + ); + sbm.dispose(); }, ); } diff --git a/src/util/ProgressReporter.ts b/src/util/ProgressReporter.ts new file mode 100644 index 00000000..03b0b7d4 --- /dev/null +++ b/src/util/ProgressReporter.ts @@ -0,0 +1,46 @@ +import * as vscode from 'vscode'; + +export class ProgressReporter { + constructor(private readonly progress: vscode.Progress<{ message?: string; increment?: number }>) {} + + private readonly subs: SubProgressReporter[] = []; + private alreadySetCount = 0; + private maxValue = 0; + private currentValue = 0; + private reportedPercent = 0; + + createSubProgressReporter(): SubProgressReporter { + const s = new SubProgressReporter(this); + this.subs.push(s); + return s; + } + + _setMax(_sub: SubProgressReporter, max: number): void { + this.alreadySetCount++; + this.maxValue += max; + } + + _incrementBy1(_sub: SubProgressReporter): void { + this.currentValue++; + + if (this.alreadySetCount === this.subs.length) { + const currentPercent = Math.floor((100 * this.currentValue) / this.maxValue); + if (currentPercent > this.reportedPercent) { + this.progress.report({ increment: currentPercent - this.reportedPercent }); + this.reportedPercent = currentPercent; + } + } + } +} + +export class SubProgressReporter { + constructor(private readonly parent: ProgressReporter) {} + + setMax(max: number): void { + this.parent._setMax(this, max); + } + + incrementBy1(): void { + this.parent._incrementBy1(this); + } +}