Skip to content

Conversation

@AhmarZaidi
Copy link

Fixes: #5978

This PR adds a new utility function, get_size_string_from_bytes, to the WP-CLI codebase.

The function converts a size in bytes to a human-readable format (units such as B, KB, MB, GB, and TB) and return string output. Allows for optional specification of decimal precision and unit preference.

Unit Tests: Added unit tests for the new function.

@AhmarZaidi AhmarZaidi marked this pull request as ready for review October 17, 2024 10:39
@AhmarZaidi AhmarZaidi requested a review from a team as a code owner October 17, 2024 10:39
Comment on lines 922 to 932
[ 0, 2, '', '0 B' ],
[ 500, 2, '', '500 B' ],
[ 1000, 2, '', '1 KB' ],
[ 1500, 2, '', '1.5 KB' ],
[ 1000000, 2, '', '1 MB' ],
[ 1000000000, 2, '', '1 GB' ],
[ 1000000000000, 2, '', '1 TB' ],
[ 1000, 0, 'KB', '1 KB' ],
[ 1000000, 0, 'MB', '1 MB' ],
[ 1000000000, 0, 'GB', '1 GB' ],
[ 1000000000000, 0, 'TB', '1 TB' ],
Copy link
Member

Choose a reason for hiding this comment

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

These test scenarios are not really testing the decimals properly. Please include non-rounded numbers as well, to make sure the decimals cut off at the right place.

Copy link
Author

Choose a reason for hiding this comment

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

@schlessera
Thanks for the review.

I've added tests for non-rounded numbers.

make sure the decimals cut off at the right place

Can you clarify on this a bit.
For test case: get_size_string_from_bytes( 1500, 2, '') should it return to 1.5 KB or 1.50 KB?
Currently it returns 1.5 KB removing the extra zero at the end.

@AhmarZaidi AhmarZaidi requested a review from schlessera November 4, 2024 13:26
@swissspidy swissspidy requested a review from Copilot November 2, 2025 14:09
@codecov
Copy link

codecov bot commented Nov 2, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds a new utility function get_size_string_from_bytes() to convert byte sizes into human-readable format (e.g., "1.5 KB", "1.07 GB").

  • Adds get_size_string_from_bytes() function with support for decimal precision and optional unit specification
  • Includes comprehensive test coverage with 13 test cases covering various byte sizes and formatting options

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
php/utils.php Implements the new get_size_string_from_bytes() function with auto-detection and manual unit specification
tests/UtilsTest.php Adds testGetSizeStringFromBytes() with test cases validating the function's output across different inputs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2143 to +2155
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Backfilling WP native constants.
if ( ! defined( 'KB_IN_BYTES' ) ) {
define( 'KB_IN_BYTES', 1024 );
}
if ( ! defined( 'MB_IN_BYTES' ) ) {
define( 'MB_IN_BYTES', 1024 * KB_IN_BYTES );
}
if ( ! defined( 'GB_IN_BYTES' ) ) {
define( 'GB_IN_BYTES', 1024 * MB_IN_BYTES );
}
if ( ! defined( 'TB_IN_BYTES' ) ) {
define( 'TB_IN_BYTES', 1024 * GB_IN_BYTES );
}
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

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

The constants KB_IN_BYTES, MB_IN_BYTES, GB_IN_BYTES, and TB_IN_BYTES are defined but never used in the function. These constants use a base of 1024, but the actual calculations on lines 2161 and 2168 use a base of 1000. Either remove these unused constants or use them consistently throughout the function.

Suggested change
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- Backfilling WP native constants.
if ( ! defined( 'KB_IN_BYTES' ) ) {
define( 'KB_IN_BYTES', 1024 );
}
if ( ! defined( 'MB_IN_BYTES' ) ) {
define( 'MB_IN_BYTES', 1024 * KB_IN_BYTES );
}
if ( ! defined( 'GB_IN_BYTES' ) ) {
define( 'GB_IN_BYTES', 1024 * MB_IN_BYTES );
}
if ( ! defined( 'TB_IN_BYTES' ) ) {
define( 'TB_IN_BYTES', 1024 * GB_IN_BYTES );
}

Copilot uses AI. Check for mistakes.
$size_key = 0;

if ( empty( $unit ) ) {
$size_key = floor( log( $bytes ) / log( 1000 ) );
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

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

The function uses a base of 1000 for unit calculation, but defines constants with a base of 1024 (binary). This creates an inconsistency between decimal (KB = 1000 bytes) and binary (KiB = 1024 bytes) standards. Based on test cases expecting '1 KB' for 1000 bytes, the implementation appears correct for decimal units, so the unused binary constants (1024-based) should be removed.

Copilot uses AI. Check for mistakes.
}

$divisor = pow( 1000, $size_key );
$size_format_display = preg_replace( '/IB$/u', 'iB', $unit );
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

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

The regex pattern /IB$/u will never match the units defined in $sizes array ('B', 'KB', 'MB', 'GB', 'TB'), which end with 'B' not 'IB'. This makes the preg_replace call ineffective. If the intent is to format binary units (e.g., 'KIB' → 'KiB'), this logic should be removed or the units array should include binary unit names.

Suggested change
$size_format_display = preg_replace( '/IB$/u', 'iB', $unit );
$size_format_display = $unit;

Copilot uses AI. Check for mistakes.
$size_key = array_search( $unit, $sizes, true );
}

$divisor = pow( 1000, $size_key );
Copy link

Copilot AI Nov 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The divisor calculation uses 1000 as the base, which is hardcoded in both this line and line 2161. Consider extracting this as a constant (e.g., BYTES_DIVISOR_BASE = 1000) for better maintainability and to make the decimal unit standard explicit.

Copilot uses AI. Check for mistakes.
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.

Introduce utility function to get size string from bytes

3 participants