From d631bed8618d1f8ad9d0c52469fc13e428766ced Mon Sep 17 00:00:00 2001 From: HuSenlin Date: Wed, 30 Jul 2025 22:07:52 +0800 Subject: [PATCH] fix the progress bar Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICPWY3 Signed-off-by: HuSenlin --- .../src/lib/progress/FixedLineProgressBar.ts | 53 ++++++++++++++++--- .../src/lib/progress/ProgressPayload.ts | 20 +++++++ 2 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 ets2panda/linter/src/lib/progress/ProgressPayload.ts diff --git a/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts b/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts index 4dc9be4ab6..4eb68d553b 100644 --- a/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts +++ b/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts @@ -16,6 +16,7 @@ import chalk from 'chalk'; import * as cliProgress from 'cli-progress'; import type { CmdProgressInfo } from './CmdProgressInfo'; +import type { ProgressPayload } from './ProgressPayload'; export class FixedLineProgressBar { private readonly bar: cliProgress.SingleBar; @@ -24,19 +25,16 @@ export class FixedLineProgressBar { private isActive = false; private lastOutput = ''; private static fixedLinePosition = 0; + private readonly minBarWidth = 20; + private readonly fixedPartsWidth = 40; + private resizeListener: (() => void) | null = null; + private lastTerminalWidth: number = 0; constructor() { this.bar = new cliProgress.SingleBar( { format: (options, params, payload): string => { - const bar = options.barCompleteString!.substring(0, Math.round(params.progress * options.barsize!)); - const statusColor = - payload.status === 'scanning' ? chalk.blue : payload.status === 'fixing' ? chalk.yellow : chalk.green; - - return ( - `${chalk.bold(payload.task)} ${statusColor(payload.statusText)} [${bar}]` + - `${Math.round(params.progress * 100)}%` - ); + return this.generateBarString(params.progress, payload); }, barCompleteChar: '\u2588', barIncompleteChar: '\u2591', @@ -51,12 +49,46 @@ export class FixedLineProgressBar { }, cliProgress.Presets.shades_grey ); + + this.resizeListener = (): void => { + if (!this.isActive) { + return; + } + const currentWidth = process.stdout.columns || 80; + // Only redraw when width changes by more than 5 characters to avoid excessive refreshes + if (Math.abs(currentWidth - this.lastTerminalWidth) > 5) { + this.renderToFixedLine(); + this.lastTerminalWidth = currentWidth; + } + }; + process.stdout.on('resize', this.resizeListener); + this.lastTerminalWidth = process.stdout.columns || 80; + } + + private generateBarString(progress: number, payload: ProgressPayload): string { + const terminalWidth = process.stdout.columns || 80; + const availableWidth = terminalWidth - this.fixedPartsWidth; + const barWidth = Math.max(this.minBarWidth, availableWidth); + + const completedLength = Math.max(0, Math.min(barWidth, Math.floor(progress * barWidth))); + const remainingLength = Math.max(0, barWidth - completedLength); + + const completedBar = this.bar.options.barCompleteChar!.repeat(completedLength); + const remainingBar = this.bar.options.barIncompleteChar!.repeat(remainingLength); + const progressBar = `${completedBar}${remainingBar}`; + + const progressPercent = Math.round(progress * 100); + const statusColor = + payload.status === 'scanning' ? chalk.blue : payload.status === 'fixing' ? chalk.yellow : chalk.green; + + return `${chalk.bold(payload.task)} ${statusColor(payload.statusText)} [${progressBar}] ${progressPercent}%`; } startBar(taskName: string, total: number, initialStatus: 'scanning' | 'fixing'): void { this.isActive = true; this.currentTask = taskName; this.currentStatus = initialStatus; + this.lastTerminalWidth = process.stdout.columns || 80; this.bar.start(total, 0, { task: `${taskName.padEnd(12)}`, @@ -155,6 +187,11 @@ export class FixedLineProgressBar { this.isActive = false; process.stderr.write('\x1B[1F\x1B[0G\x1B[2K'); } + + if (this.resizeListener) { + process.stdout.off('resize', this.resizeListener); + this.resizeListener = null; + } } } diff --git a/ets2panda/linter/src/lib/progress/ProgressPayload.ts b/ets2panda/linter/src/lib/progress/ProgressPayload.ts new file mode 100644 index 0000000000..ae171ceba1 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/ProgressPayload.ts @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface ProgressPayload { + task: string; + status: 'scanning' | 'fixing' | 'completed' | 'skipped'; + statusText: string; +} -- Gitee