Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 140 additions & 1 deletion features/updatepo.feature
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ Feature: Update existing PO files from a POT file
When I run `wp i18n update-po foo-plugin/foo-plugin.pot`
Then STDOUT should be:
"""
Success: Updated 1 file.
Success: Updated 0 files. 1 file unchanged.
"""
And STDERR should be empty
And the foo-plugin/foo-plugin-de_DE.po file should contain:
Expand All @@ -527,3 +527,142 @@ Feature: Update existing PO files from a POT file
"""
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"""

Scenario: Reports unchanged files when POT hasn't changed
Given an empty foo-plugin directory
And a foo-plugin/foo-plugin.pot file:
"""
# Copyright (C) 2018 Foo Plugin
# This file is distributed under the same license as the Foo Plugin package.
msgid ""
msgstr ""
"Project-Id-Version: Foo Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foo-plugin\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2018-05-02T22:06:24+00:00\n"
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"X-Domain: foo-plugin\n"

#: foo-plugin.php:1
msgid "Some string"
msgstr ""
"""
And a foo-plugin/foo-plugin-de_DE.po file:
"""
# Copyright (C) 2018 Foo Plugin
# This file is distributed under the same license as the Foo Plugin package.
msgid ""
msgstr ""
"Project-Id-Version: Foo Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foo-plugin\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2018-05-02T22:06:24+00:00\n"
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"X-Domain: foo-plugin\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: foo-plugin.php:1
msgid "Some string"
msgstr "Some translated string"
"""

When I run `wp i18n update-po foo-plugin/foo-plugin.pot`
Then STDOUT should be:
"""
Success: Updated 0 files. 1 file unchanged.
"""
And STDERR should be empty

Scenario: Reports both updated and unchanged files
Given an empty foo-plugin directory
And a foo-plugin/foo-plugin.pot file:
"""
# Copyright (C) 2018 Foo Plugin
# This file is distributed under the same license as the Foo Plugin package.
msgid ""
msgstr ""
"Project-Id-Version: Foo Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foo-plugin\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2018-05-02T22:06:24+00:00\n"
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"X-Domain: foo-plugin\n"

#: foo-plugin.php:1
msgid "Some string"
msgstr ""

#: foo-plugin.php:15
msgid "Another new string"
msgstr ""
"""
And a foo-plugin/foo-plugin-de_DE.po file:
"""
# Copyright (C) 2018 Foo Plugin
# This file is distributed under the same license as the Foo Plugin package.
msgid ""
msgstr ""
"Project-Id-Version: Foo Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foo-plugin\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2018-05-02T22:06:24+00:00\n"
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"X-Domain: foo-plugin\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: foo-plugin.php:10
msgid "Some string"
msgstr "Some translated string"
"""
And a foo-plugin/foo-plugin-es_ES.po file:
"""
# Copyright (C) 2018 Foo Plugin
# This file is distributed under the same license as the Foo Plugin package.
msgid ""
msgstr ""
"Project-Id-Version: Foo Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/foo-plugin\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2018-05-02T22:06:24+00:00\n"
"PO-Revision-Date: 2018-05-02T22:06:24+00:00\n"
"X-Domain: foo-plugin\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: foo-plugin.php:1
msgid "Some string"
msgstr "Some translated string"

#: foo-plugin.php:15
msgid "Another new string"
msgstr "Otra nueva cadena"
"""

When I run `wp i18n update-po foo-plugin/foo-plugin.pot`
Then STDOUT should be:
"""
Success: Updated 1 file. 1 file unchanged.
"""
And STDERR should be empty
104 changes: 100 additions & 4 deletions src/UpdatePoCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class UpdatePoCommand extends WP_CLI_Command {
* $ wp i18n update-po example-plugin.pot languages
* Success: Updated 2 files.
*
* # Shows message when some files don't need updating.
* $ wp i18n update-po example-plugin.pot languages
* Success: Updated 2 files. 1 file unchanged.
*
* @when before_wp_load
*
* @throws WP_CLI\ExitException
Expand Down Expand Up @@ -69,7 +73,8 @@ public function __invoke( $args, $assoc_args ) {

$pot_translations = Translations::fromPoFile( $source );

$result_count = 0;
$updated_count = 0;
$unchanged_count = 0;
/** @var DirectoryIterator $file */
foreach ( $files as $file ) {
if ( 'po' !== $file->getExtension() ) {
Expand All @@ -81,12 +86,17 @@ public function __invoke( $args, $assoc_args ) {
continue;
}

$po_translations = Translations::fromPoFile( $file->getPathname() );
$po_translations = Translations::fromPoFile( $file->getPathname() );
$original_translations = clone $po_translations;

$po_translations->mergeWith(
$pot_translations,
Merge::ADD | Merge::REMOVE | Merge::COMMENTS_THEIRS | Merge::EXTRACTED_COMMENTS_THEIRS | Merge::REFERENCES_THEIRS | Merge::DOMAIN_OVERRIDE
);

// Check if the translations actually changed by comparing the objects.
$has_changes = $this->translations_differ( $original_translations, $po_translations );

// Update PO-Revision-Date to current date and time in UTC.
// Uses gmdate() for consistency across different server timezones.
$po_translations->setHeader( 'PO-Revision-Date', gmdate( 'Y-m-d\TH:i:sP' ) );
Expand All @@ -96,9 +106,95 @@ public function __invoke( $args, $assoc_args ) {
continue;
}

++$result_count;
if ( $has_changes ) {
++$updated_count;
} else {
++$unchanged_count;
}
}

// Build the success message.
$message_parts = array();
$message_parts[] = sprintf( 'Updated %d %s', $updated_count, Utils\pluralize( 'file', $updated_count ) );
if ( $unchanged_count > 0 ) {
$message_parts[] = sprintf( '%d %s unchanged', $unchanged_count, Utils\pluralize( 'file', $unchanged_count ) );
}

WP_CLI::success( implode( '. ', $message_parts ) . '.' );
}

/**
* Check if two Translations objects differ.
*
* @param Translations $original Original translations.
* @param Translations $updated Updated translations.
* @return bool True if translations differ, false otherwise.
*/
private function translations_differ( Translations $original, Translations $updated ) {
// Quick check: if counts differ, they're different.
if ( count( $original ) !== count( $updated ) ) {
return true;
}

// Compare each translation entry.
foreach ( $original as $translation ) {
$context = $translation->getContext();
$original_str = $translation->getOriginal();

// Find the corresponding translation in the updated set.
$updated_translation = $updated->find( $context, $original_str );

// If translation doesn't exist in updated set, they differ.
if ( ! $updated_translation ) {
return true;
}

// Compare translation strings.
if ( $translation->getTranslation() !== $updated_translation->getTranslation() ) {
return true;
}

// Compare plural translations if they exist.
$original_plurals = $translation->getPluralTranslations();
$updated_plurals = $updated_translation->getPluralTranslations();

if ( $original_plurals !== $updated_plurals ) {
return true;
}

// Compare references (source code locations).
$original_refs = $translation->getReferences();
$updated_refs = $updated_translation->getReferences();

sort( $original_refs );
sort( $updated_refs );

if ( $original_refs !== $updated_refs ) {
return true;
}

// Compare comments.
if ( $translation->getExtractedComments() !== $updated_translation->getExtractedComments() ) {
return true;
}

if ( $translation->getComments() !== $updated_translation->getComments() ) {
return true;
}
}

// Check if updated has any translations not in original.
foreach ( $updated as $translation ) {
$context = $translation->getContext();
$original_str = $translation->getOriginal();

$original_translation = $original->find( $context, $original_str );

if ( ! $original_translation ) {
return true;
}
}

WP_CLI::success( sprintf( 'Updated %d %s.', $result_count, Utils\pluralize( 'file', $result_count ) ) );
return false;
}
}