Skip to content

Conversation

@tsanders-rh
Copy link
Contributor

@tsanders-rh tsanders-rh commented Oct 31, 2025

Add ProgressBarReporter for improved CLI user experience

Summary

This PR adds a new ProgressBarReporter that displays visual progress bars during rule execution, enabling consistent user experience between containerless and containerized Kantra deployments.

Background

Kantra uses analyzer-lsp in two different modes:

  • Containerless mode: Imports analyzer-lsp as a Go library, creates a ChannelReporter, and renders progress bars in Kantra code
  • Containerized mode: Runs the konveyor-analyzer binary as a container and streams its output

Current Problem

These two modes provide inconsistent user experiences:

  • Containerless mode: Shows visual progress bar during rule execution ✅
  • Containerized mode: Only outputs structured INFO logs (which are filtered), resulting in no progress feedback ❌

This creates confusion for users who expect the same experience regardless of deployment mode.

Solution

This PR adds a ProgressBarReporter that:

  • Displays a visual progress bar with real-time updates to stderr
  • Updates in-place using carriage returns (\r) for clean terminal experience
  • Becomes the new default format (via --progress-format=bar)
  • Maintains full backward compatibility with existing text/json formats

Example Output

Provider java ready
Loaded 235 rules
Processing rules  42% |██████████░░░░░░░░░░░░░░░| 99/235  hibernate-6.2-00280

The progress bar updates in-place during rule execution, providing real-time feedback.

Changes

New Files

  • progress/progress_bar_reporter.go - ProgressBarReporter implementation with in-place updates

Modified Files

  • cmd/analyzer/main.go - Updated CLI to support --progress-format=bar (now default)
  • progress/progress_test.go - Added comprehensive tests for ProgressBarReporter

Key Features

  1. Visual Progress Bar: Shows percentage, visual bar with block characters (█/░), count, and current rule
  2. In-place Updates: Uses carriage returns to update progress without scrolling
  3. Thread-safe: Mutex-protected for concurrent use
  4. Rule Name Truncation: Long rule names (>50 chars) are truncated with "..."
  5. Stage Handling: Different output for provider init, rule parsing, dependency analysis, completion

CLI Flags

The analyzer binary now supports:

  • --progress-output=stderr|stdout|<file> - Where to write progress (default: none)
  • --progress-format=bar|text|json - Output format (default: bar)

Testing

Unit Tests (7 test cases + benchmark)

  • TestProgressBarReporter - Basic functionality
  • TestProgressBarReporterProgressPercentages - 0%, 50%, 100% scenarios
  • TestProgressBarReporterStages - All stages (init, parsing, execution, completion)
  • TestProgressBarReporterRuleNameTruncation - Long rule names
  • TestProgressBarReporterMultipleUpdates - Progress updates with carriage returns
  • TestProgressBarReporterConcurrency - Thread safety
  • BenchmarkProgressBarReporter - Performance validation

Benchmark Results

BenchmarkProgressBarReporter-14    2167490    531.1 ns/op    927 B/op    14 allocs/op

Performance overhead: ~531ns per event × 235 rules = ~125µs total (negligible)

Integration Testing

  • ✅ Tested in Kantra containerized mode with real analysis workloads
  • ✅ Verified progress bar displays correctly in containerized environment
  • ✅ Confirmed backward compatibility with existing text/json formats

Backward Compatibility

  • ✅ Existing users can continue using --progress-format=text or --progress-format=json
  • ✅ No changes to core analysis functionality
  • ✅ No breaking changes to API or behavior
  • ✅ Default format change is opt-out (can specify --progress-format=text for old behavior)

Benefits

  1. Consistent UX: Users get same visual feedback in both containerless and containerized modes
  2. Better CLI experience: Visual progress bars are more intuitive than text logs
  3. Low overhead: Minimal performance impact (~125µs for 235 rules)
  4. Well tested: Comprehensive test coverage following existing patterns
  5. Future-proof: Extensible design allows for future enhancements

Related Issues

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated (godoc comments)
  • Tests added with good coverage
  • All tests pass locally
  • No new warnings introduced
  • DCO sign-off included in commits
  • Backward compatibility maintained

Screenshots / Demo

Notes for Reviewers

  • The implementation follows the same pattern as existing reporters (TextReporter, JSONReporter)
  • The mutex locking ensures thread safety without performance impact
  • The default format change to "bar" provides better UX but can be reverted if needed
  • All private methods have clear documentation for maintainability

Ready for review! Happy to address any feedback or make adjustments.

Summary by CodeRabbit

  • New Features

    • Added visual progress bar display for analyzer operations showing percentage completion, current/total counts, and visual fill indicators.
    • Added "bar" format option to progress reporting; now defaults to visual bar instead of text output.
  • Improvements

    • Enhanced progress reporting visibility across all analyzer stages (initialization, rule parsing, execution, and dependency analysis).

This commit adds a new ProgressBarReporter that displays a visual
progress bar with real-time updates during rule execution. This
enables containerized kantra to display the same progress experience
as containerless mode.

Changes:
- Add ProgressBarReporter with in-place progress bar updates
- Update CLI to support --progress-format=bar (now default)
- Add comprehensive tests for ProgressBarReporter
- Add benchmark for performance validation

The progress bar format:
  Processing rules  42% |██████████░░░░░░░░░░░░░░░| 99/235  rule-name

The reporter is thread-safe and updates in-place using carriage
returns (\r), printing a final newline when analysis completes.

Performance: ~531ns/op with minimal overhead (~125µs for 235 rules)
Signed-off-by: tsanders <[email protected]>
Add more detailed documentation to the Report method to match the
level of detail in other reporters. Documents the output format for
each stage and clarifies the in-place update behavior during rule
execution.

Signed-off-by: tsanders <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Oct 31, 2025

Walkthrough

This pull request introduces a new ProgressBarReporter component to the progress subsystem and changes the CLI's default progress format from "text" to "bar". The reporter provides thread-safe, in-place updating visual progress bars with stage-specific output handling and comprehensive test coverage.

Changes

Cohort / File(s) Summary
CLI Progress Configuration
cmd/analyzer/main.go
Changes the default progress-format flag from "text" to "bar" and updates createProgressReporter to instantiate ProgressBarReporter for "bar" format and return a ProgressBar reporter as default for unknown formats (instead of Text).
Progress Bar Reporter Implementation
progress/progress_bar_reporter.go
Adds new ProgressBarReporter type with thread-safe in-place progress bar rendering using carriage returns. Includes stage-specific handling (ProviderInit, RuleParsing, RuleExecution, DependencyAnalysis, Complete), visual bar rendering with filled/empty characters, percentage and count display, and rule name truncation logic.
Progress Bar Reporter Tests
progress/progress_test.go
Adds comprehensive test suite covering basic rendering, boundary percentages (0%, 50%, 100%), stage-specific output, rule name truncation, in-place updates with carriage returns, concurrency safety, and performance benchmarks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • The new ProgressBarReporter introduces new logic with multiple internal helpers (updateProgressBar, buildProgressBar, clearLine) and state management (mutex, tracking line length, in-progress flag) that warrants careful review
  • Stage-specific output logic and edge cases (truncation, newline handling, boundary conditions) should be verified
  • Test coverage is comprehensive, but the concurrency and performance aspects may require additional attention
  • Integration point in main.go is straightforward but depends on correct ProgressBarReporter implementation

Possibly related PRs

Suggested reviewers

  • shawn-hurley
  • dymurray

Poem

🐰 A progress bar hops through the output stream,
Filling with blocks in a visual dream,
From zero to hundred, the stages advance,
Thread-safe and steady, they move in a dance!
With carriage returns and that perfect newline,
Our analyzer now shows progress so fine!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Add ProgressBarReporter for improved CLI user experience" is directly and fully related to the main change in this pull request. The primary modifications include adding a new ProgressBarReporter component in progress/progress_bar_reporter.go with supporting methods and tests, along with updating cmd/analyzer/main.go to make this new progress bar the default format. The title clearly summarizes the core objective—introducing the ProgressBarReporter—and would be easily understood by someone scanning the commit history. While the sparkles emoji could be considered stylistic noise, the textual portion is concise, specific, and directly conveys the changeset's purpose.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
cmd/analyzer/main.go (1)

468-472: Consider simplifying the default case.

Both the "bar" case and the default case return the same reporter type. While this works correctly, the explicit case at lines 468-469 makes the default case slightly redundant.

Optionally, you could simplify by removing the explicit "bar" case and relying on the default, or make the default more explicit:

 	switch progressFormat {
 	case "json":
 		return progress.NewJSONReporter(writer), cleanup
 	case "text":
 		return progress.NewTextReporter(writer), cleanup
-	case "bar":
-		return progress.NewProgressBarReporter(writer), cleanup
 	default:
-		// Default to progress bar
+		// Default to progress bar for "bar" or unknown formats
 		return progress.NewProgressBarReporter(writer), cleanup
 	}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 370b419 and d234c40.

📒 Files selected for processing (3)
  • cmd/analyzer/main.go (2 hunks)
  • progress/progress_bar_reporter.go (1 hunks)
  • progress/progress_test.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
cmd/analyzer/main.go (1)
progress/progress_bar_reporter.go (1)
  • NewProgressBarReporter (39-44)
progress/progress_test.go (2)
progress/progress_bar_reporter.go (1)
  • NewProgressBarReporter (39-44)
progress/progress.go (7)
  • ProgressEvent (64-88)
  • Stage (112-112)
  • StageRuleExecution (128-128)
  • StageProviderInit (120-120)
  • StageRuleParsing (124-124)
  • StageDependencyAnalysis (131-131)
  • StageComplete (134-134)
progress/progress_bar_reporter.go (1)
progress/progress.go (7)
  • ProgressEvent (64-88)
  • Stage (112-112)
  • StageProviderInit (120-120)
  • StageRuleParsing (124-124)
  • StageRuleExecution (128-128)
  • StageDependencyAnalysis (131-131)
  • StageComplete (134-134)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: e2e / e2e-api-integration-tests
🔇 Additional comments (8)
cmd/analyzer/main.go (1)

399-399: LGTM! Default format change aligns with PR objectives.

The change to "bar" as the default progress format matches the PR's goal of providing improved CLI user experience with visual progress bars.

progress/progress_test.go (1)

604-894: Excellent test coverage for ProgressBarReporter!

The test suite is comprehensive and well-structured, covering:

  • Basic functionality and output format verification
  • Boundary conditions (0%, 50%, 100% completion)
  • Stage-specific output across all stages
  • Long message truncation behavior
  • In-place updates with carriage returns and final newline
  • Thread safety under concurrent access
  • Performance benchmarking

The tests appropriately verify the presence of expected strings, special characters (█, ░), and proper line endings.

progress/progress_bar_reporter.go (6)

22-28: LGTM! Well-designed struct for thread-safe progress reporting.

The struct includes appropriate fields for tracking state (lastLineLen, inProgress) and uses a sync.Mutex for safe concurrent access.


39-44: LGTM! Simple and correct constructor.

The constructor properly initializes the reporter with a fixed bar width of 25 characters, which is appropriate for typical terminal widths.


60-104: LGTM! Report method correctly handles all stages.

The implementation properly:

  • Uses mutex for thread safety
  • Normalizes events before processing
  • Clears previous progress bars before printing new messages
  • Handles stage-specific formatting appropriately
  • Updates progress bar in place only for rule execution stage

109-134: LGTM! Progress bar update logic is correct.

The method properly:

  • Clears previous output using carriage returns and spaces
  • Updates the bar in place during progress
  • Adds a final newline at 100% completion
  • Maintains state for subsequent updates

139-174: LGTM! Progress bar construction is well-implemented.

The method correctly:

  • Calculates filled/empty portions based on percentage
  • Clamps values to prevent overflow
  • Uses appropriate Unicode box-drawing characters (█, ░)
  • Formats the output clearly with percentage, visual bar, count, and rule name
  • Truncates long rule names at 50 characters with a "..." indicator

177-186: LGTM! Line clearing logic is correct.

The method properly clears any existing progress bar by:

  • Checking if there's content to clear
  • Using carriage returns and spaces to overwrite the line
  • Resetting state variables

Copy link
Contributor

@dymurray dymurray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this locally and looks great. Much better improvement

@dymurray dymurray merged commit 3248bdd into konveyor:main Oct 31, 2025
20 checks passed
@tsanders-rh tsanders-rh deleted the feature/stderr-progress-bar branch November 1, 2025 01:26
tsanders-rh added a commit to tsanders-rh/editor-extensions that referenced this pull request Nov 16, 2025
This commit implements real-time progress reporting in the VS Code extension
for kai analysis operations, providing users with detailed progress updates.

**Changes:**

1. **Progress Parser** (progressParser.ts)
   - Created ProgressParser class to parse NDJSON progress events from stderr
   - TypeScript types for ProgressEvent matching kai-analyzer-rpc format
   - Handles all progress stages: init, provider_init, rule_parsing,
     rule_execution, dependency_analysis, complete
   - Robust parsing with error handling for non-JSON stderr content

2. **Analyzer Client Updates** (analyzerClient.ts)
   - Added progress CLI flags to kai-analyzer-rpc spawn:
     --progress-output=stderr --progress-format=json
   - Integrated ProgressParser with stderr stream
   - Added currentProgressCallback field for dynamic callback management
   - Updated runAnalysis() to set progress callback during analysis
   - Maps progress events to VS Code progress UI messages

**Progress UI Messages:**
- "Initializing analysis..." (init)
- "Provider: nodejs" (provider_init with message)
- "Loaded 45 rules" (rule_parsing with count)
- "Processing rules: 23/45 (51.1%)" (rule_execution with progress)
- "Analysis complete!" (complete)

**Implementation Details:**
- Progress parser feeds from stderr while preserving logging
- Callback is set when analysis starts, cleared in finally block
- Per-rule progress updates via rule_execution events
- Automatic percentage calculation from current/total

**Requirements:**
Requires kai-analyzer-rpc with progress reporting support
(konveyor/kai#895)

Related to: konveyor/analyzer-lsp#949, konveyor/analyzer-lsp#950

Signed-off-by: tsanders <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants