Skip to content

Add progress bar for search-replace operations#206

Draft
Copilot wants to merge 18 commits intomainfrom
copilot/add-progress-bar-indicator
Draft

Add progress bar for search-replace operations#206
Copilot wants to merge 18 commits intomainfrom
copilot/add-progress-bar-indicator

Conversation

Copy link
Contributor

Copilot AI commented Nov 10, 2025

Addresses lack of feedback during long-running search-replace operations on large tables (e.g., 1M+ rows in postmeta).

Description

Adds a progress bar using \WP_CLI\Utils\make_progress_bar() for PHP-based row processing and table exports. The progress bar displays when:

  • Processing serialized data, regex patterns, or using --precise
  • Exporting tables to file

Automatically suppressed when conflicting with existing output modes (--verbose, --quiet, --format=count, logging enabled, or when exporting to STDOUT).

Progress bar initialization is deferred until the first batch of rows is fetched from the database, ensuring it displays even in edge cases where a pre-check COUNT query might return 0.

Changes

  • Added should_show_progress_bar() helper checking output mode compatibility
  • Modified php_handle_col(): progress bar is initialized inside the while loop on the first iteration when rows are actually fetched, labelled "Processing table.column", ticks once per batch after processing each batch, and finishes on completion
  • Modified php_export_table(): similar integration with a "Processing table" progress bar label
  • Added Behat tests verifying progress bar visibility (checked on STDERR) with and without --verbose
  • Fixed: progress bar is suppressed when logging is enabled to prevent interference with log output
  • Updated test data: uses wp option set to ensure the search string is present, so the progress bar is triggered with --precise

How It Works

For regular search-replace operations (when export_handle is false):

  • Progress bar is implemented in php_handle_col()
  • Initialized inside the while loop on the first iteration when rows are actually being fetched
  • Called during normal processing flow when using PHP mode (--precise, regex, or serialized data)

For export operations (when export_handle is a file handle):

  • Progress bar is implemented in php_export_table()
  • Called only when exporting to a file

Example

# Shows progress bar: "Processing wp_postmeta.meta_value"
wp search-replace '\/old-path\/(.+)' '/new-path/$1' --regex wp_postmeta

# Verbose mode shows row-by-row output instead (no progress bar)
wp search-replace 'foo' 'bar' --verbose

# No progress bar when logging is enabled
wp search-replace 'foo' 'bar' --log

Notes

Progress bar initialization is deferred until the first iteration of the while loop when rows are actually fetched. This handles edge cases where a pre-check COUNT query might return 0 but rows are still processed.

Progress bar advances by batch size (typically 1000 rows) rather than per individual row, providing accurate progress tracking aligned with database query batches.

Progress bar is suppressed whenever logging is enabled to ensure clean, parseable log output.

Original prompt

This section details on the original issue you should resolve

<issue_title>Progress bar</issue_title>
<issue_description>Issue: I can't see the status of any search-replace commands as they are executing

Right now I'm running a search-replace command (as a regular expression) against the postmeta table which has around 1 million rows. This is pretty slow (which obviously has nothing to do with this command in itself) but I'd love some kind of feedback as to the progress of the command.

For reference the command is:

wp search-replace '\/vid-dodsfall\/(.)+' '/begravning/$1' --regex wp_postmeta

Solution: I'd love to see a progress bar indicator for this command

I would guess that the majority of use cases for search-replace are something along the lines of

wp search-replace https://live.com https://local.com

This can take a wee while on a larger database and I'd love to have some indication of progress.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 4 commits November 10, 2025 18:45
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Add progress bar for search-replace command Add progress bar for search-replace operations Nov 10, 2025
Copilot AI requested a review from swissspidy November 10, 2025 19:05

This comment was marked as resolved.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
@swissspidy

This comment was marked as resolved.

Fixes logging test by suppressing progress bar whenever logging is enabled (not just when logging to STDOUT), as the progress bar output can interfere with clean log output.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

Modified the "Progress bar shows when not in verbose mode" test to generate posts with content containing http://example.com. This ensures the progress bar has matching rows to process and display when using the --precise flag.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

Added WP_CLI::log() call to output "Updating table.column (X rows)" message before creating progress bar. This ensures users see feedback even if the progress bar doesn't display properly, and provides clear indication of what's being processed. Also reverted test back to checking STDOUT as requested.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

Copilot AI changed the title Add progress bar for search-replace operations Add progress feedback for search-replace operations Nov 14, 2025
@swissspidy

This comment was marked as resolved.

Fixed sprintf format strings for make_progress_bar() calls. Changed from 'Progress' (which ignored table/col parameters) to 'Processing table.column' for regular processing and 'Processing table' for exports. This ensures the progress bar displays with meaningful labels.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

This comment was marked as resolved.

@swissspidy

This comment was marked as resolved.

Moved progress bar setup from before the while loop to inside the loop on first iteration. This ensures the progress bar is created when rows are actually fetched, even if the initial COUNT query returns 0. Addresses issue where COUNT might return 0 but the while loop still fetches rows to process.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>

This comment was marked as resolved.

Remove extra log messages before the progress bar ('Updating table.column (X rows)' and 'Exporting table (X rows)'). The progress bar label already includes the table and column names. Update Behat tests to check STDERR for 'Processing' (progress bar output) instead of STDOUT for 'Updating'.

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title Add progress feedback for search-replace operations Add progress bar for search-replace operations Mar 11, 2026
Copilot AI requested a review from swissspidy March 11, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Progress bar

3 participants