jenkins-bot has submitted this change and it was merged.

Change subject: Update sync-group.php to use Maintenance class
......................................................................


Update sync-group.php to use Maintenance class

Change-Id: I8d7647d5bbb179c8d469437a450a166890b676bf
---
M scripts/sync-group.php
1 file changed, 220 insertions(+), 146 deletions(-)

Approvals:
  Nikerabbit: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/scripts/sync-group.php b/scripts/sync-group.php
index a3473fd..9325a6b 100644
--- a/scripts/sync-group.php
+++ b/scripts/sync-group.php
@@ -11,161 +11,235 @@
  * @file
  */
 
-/// @cond
-
-$options = array( 'git' );
-$optionsWithArgs = array( 'group', 'lang', 'start', 'end' );
-require __DIR__ . '/cli.inc';
+// Standard boilerplate to define $IP
+if ( getenv( 'MW_INSTALL_PATH' ) !== false ) {
+       $IP = getenv( 'MW_INSTALL_PATH' );
+} else {
+       $dir = __DIR__;
+       $IP = "$dir/../../..";
+}
+require_once "$IP/maintenance/Maintenance.php";
 
 # Override the memory limit for wfShellExec, 100 MB seems to be too little for 
svn
 $wgMaxShellMemory = 1024 * 200;
 
-function showUsage() {
-       STDERR( <<<EOT
-Options:
-  --group       Comma separated list of group IDs (can use * as wildcard)
-  --git         Use git to retrieve last modified date of i18n files. Will use
-                subversion by default and fallback on filesystem timestamp
-  --lang        Comma separated list of language codes or *
-  --norc        Do not add entries to recent changes table
-  --help        This help message
-  --noask       Skip all conflicts
-  --start       Start of the last export (changes in wiki after will conflict)
-  --end         End of the last export (changes in source after will conflict)
-  --nocolor     Without colors
-EOT
-       );
-       exit( 1 );
-}
-
-if ( isset( $options['help'] ) ) {
-       showUsage();
-}
-
-if ( !isset( $options['group'] ) ) {
-       STDERR( "ESG1: Message group id must be supplied with group parameter." 
);
-       exit( 1 );
-}
-
-$groupIds = explode( ',', trim( $options['group'] ) );
-$groupIds = MessageGroups::expandWildcards( $groupIds );
-$groups = MessageGroups::getGroupsById( $groupIds );
-
-if ( !count( $groups ) ) {
-       STDERR( "ESG2: No valid message groups identified." );
-       exit( 1 );
-}
-
-if ( !isset( $options['lang'] ) || strval( $options['lang'] ) === '' ) {
-       STDERR( "ESG3: List of language codes must be supplied with lang 
parameter." );
-       exit( 1 );
-}
-
-$start = isset( $options['start'] ) ? strtotime( $options['start'] ) : false;
-$end = isset( $options['end'] ) ? strtotime( $options['end'] ) : false;
-
-STDOUT( "Conflict times: " . wfTimestamp( TS_ISO_8601, $start ) . " - " .
-       wfTimestamp( TS_ISO_8601, $end ) );
-
-$codes = array_filter( array_map( 'trim', explode( ',', $options['lang'] ) ) );
-
-$supportedCodes = array_keys( TranslateUtils::getLanguageNames( 'en' ) );
-ksort( $supportedCodes );
-
-if ( $codes[0] === '*' ) {
-       $codes = $supportedCodes;
-}
-
-/**
- * @var MessageGroup $group
- */
-foreach ( $groups as &$group ) {
-       // No sync possible for meta groups
-       if ( $group->isMeta() ) {
-               continue;
+class SyncGroup extends Maintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = 'Import or update source messages and 
translations into ' .
+                       'the wiki database.';
+               $this->addOption(
+                       'git',
+                       '(optional) Use git to retrieve last modified date of 
i18n files. Will use subversion ' .
+                       'by default and fallback on filesystem timestamp',
+                       false, /*required*/
+                       false /*has arg*/
+               );
+               $this->addOption(
+                       'group',
+                       'Comma separated list of group IDs (can use * as 
wildcard).',
+                       true, /*required*/
+                       true /*has arg*/
+               );
+               $this->addOption(
+                       'lang',
+                       '(optional) Comma separated list of language codes or 
*',
+                       false, /*required*/
+                       true /*has arg*/
+               );
+               $this->addOption(
+                       'norc',
+                       '(optional) Do not add entries to recent changes table',
+                       false, /*required*/
+                       false /*has arg*/
+               );
+               $this->addOption(
+                       'noask',
+                       '(optional) Skip all conflicts',
+                       false, /*required*/
+                       false /*has arg*/
+               );
+               $this->addOption(
+                       'start',
+                       '(optional) Start of the last export (changes in wiki 
after will conflict)',
+                       false, /*required*/
+                       true /*has arg*/
+               );
+               $this->addOption(
+                       'end',
+                       '(optional) End of the last export (changes in source 
after will conflict)',
+                       false, /*required*/
+                       true /*has arg*/
+               );
+               $this->addOption(
+                       'nocolor',
+                       '(optional) Without colors',
+                       false, /*required*/
+                       false /*has arg*/
+               );
+               $this->addOption(
+                       'core-meta',
+                       '(optional) Allow export of specific MediaWiki core 
meta groups ' .
+                       '(translatewiki.net specific)',
+                       false, /*required*/
+                       false /*has arg*/
+               );
        }
 
-       STDOUT( "{$group->getLabel()} ", $group );
+       public function execute() {
+               $groupIds = explode( ',', trim( $this->getOption( 'group' ) ) );
+               $groupIds = MessageGroups::expandWildcards( $groupIds );
+               $groups = MessageGroups::getGroupsById( $groupIds );
 
-       foreach ( $codes as $code ) {
-               // No sync possible for unsupported language codes.
-               if ( !in_array( $code, $supportedCodes ) ) {
-                       STDOUT( "Unsupported code " . $code . ": skipping." );
-                       continue;
+               if ( !count( $groups ) ) {
+                       $this->error( "ESG2: No valid message groups 
identified.", 1 );
                }
 
-               if ( $group instanceof FileBasedMessageGroup ) {
-                       /**
-                        * @var FileBasedMessageGroup $group
-                        */
-                       $file = $group->getSourceFilePath( $code );
-               } else {
-                       /**
-                        * @var MessageGroupOld $group
-                        */
-                       $file = $group->getMessageFileWithPath( $code );
+               $start = $this->getOption( 'start' ) ? strtotime( 
$this->getOption( 'start' ) ) : false;
+               $end = $this->getOption( 'end' ) ? strtotime( $this->getOption( 
'end' ) ) : false;
+
+               $this->output( "Conflict times: " . wfTimestamp( TS_ISO_8601, 
$start ) . " - " .
+                       wfTimestamp( TS_ISO_8601, $end ) . "\n" );
+
+               $codes = array_filter( array_map( 'trim', explode( ',', 
$this->getOption( 'lang' ) ) ) );
+
+               $supportedCodes = array_keys( TranslateUtils::getLanguageNames( 
'en' ) );
+               ksort( $supportedCodes );
+
+               if ( $codes[0] === '*' ) {
+                       $codes = $supportedCodes;
                }
 
-               if ( !$file ) {
-                       continue;
-               }
+               $coreMeta = $this->hasOption( 'core-meta' );
 
-               if ( !file_exists( $file ) ) {
-                       continue;
-               }
+               /** @var MessageGroup $group */
+               foreach ( $groups as $groupId => &$group ) {
+                       if ( $group->isMeta() ) {
+                               if ( !$coreMeta ) {
+                                       $this->output( "Skipping meta message 
group $groupId.\n" );
+                                       continue;
+                               }
 
-               $cs = new ChangeSyncer( $group );
-               if ( isset( $options['norc'] ) ) {
-                       $cs->norc = true;
-               }
+                               // Special case for MediaWiki core branches 
with pattern "core-1*"
+                               if ( strstr( $group->getId(), 'core-1', true ) 
!== '' ) {
+                                       $this->output( "Skipping meta message 
group $groupId.\n" );
+                                       continue;
+                               }
+                       }
 
-               if ( isset( $options['noask'] ) ) {
-                       $cs->interactive = false;
-               }
+                       $this->output( "{$group->getLabel()} ", $group );
 
-               if ( isset( $options['nocolor'] ) ) {
-                       $cs->nocolor = true;
-               }
+                       foreach ( $codes as $code ) {
+                               // No sync possible for unsupported language 
codes.
+                               if ( !in_array( $code, $supportedCodes ) ) {
+                                       $this->output( "Unsupported code " . 
$code . ": skipping.\n" );
+                                       continue;
+                               }
 
-               # Guess last modified date of the file from either git, svn or 
filesystem
-               $ts = false;
-               if ( isset( $options['git'] ) ) {
-                       $ts = $cs->getTimestampsFromGit( $file );
-               } else {
-                       $ts = $cs->getTimestampsFromSvn( $file );
-               }
-               if ( !$ts ) {
-                       $ts = $cs->getTimestampsFromFs( $file );
-               }
+                               if ( $group instanceof FileBasedMessageGroup ) {
+                                       /** @var FileBasedMessageGroup $group */
+                                       $file = $group->getSourceFilePath( 
$code );
+                               } else {
+                                       /** @var MessageGroupOld $group */
+                                       $file = $group->getMessageFileWithPath( 
$code );
+                               }
 
-               STDOUT( "Modify time for $code: " . wfTimestamp( TS_ISO_8601, 
$ts ) );
+                               if ( !$file ) {
+                                       continue;
+                               }
 
-               $cs->checkConflicts( $code, $start, $end, $ts );
+                               if ( !file_exists( $file ) ) {
+                                       continue;
+                               }
+
+                               $cs = new ChangeSyncer( $group, $this );
+                               $cs->setProgressCallback( array( $this, 
'myOutput' ) );
+                               $cs->interactive = !$this->hasOption( 'noask' );
+                               $cs->nocolor = $this->hasOption( 'nocolor' );
+                               $cs->norc = $this->hasOption( 'norc' );
+
+                               # @todo FIXME: Make this auto detect.
+                               # Guess last modified date of the file from 
either git, svn or filesystem
+                               if ( $this->hasOption( 'git' ) ) {
+                                       $ts = $cs->getTimestampsFromGit( $file 
);
+                               } else {
+                                       $ts = $cs->getTimestampsFromSvn( $file 
);
+                               }
+                               if ( !$ts ) {
+                                       $ts = $cs->getTimestampsFromFs( $file );
+                               }
+
+                               $this->output( "Modify time for $code: " . 
wfTimestamp( TS_ISO_8601, $ts ) . "\n" );
+
+                               $cs->checkConflicts( $code, $start, $end, $ts );
+                       }
+
+                       unset( $group );
+               }
+               // Print timestamp if the user wants to store it
+               $this->output( wfTimestamp( TS_RFC2822 ) . "\n" );
        }
 
-       unset( $group );
+       /**
+        * Public alternative for protected Maintenance::output() as we need to 
get
+        * messages from the ChangeSyncer class to the commandline.
+        * @param string $text The text to show to the user
+        * @param string $channel Unique identifier for the channel.
+        * @param bool $error Whether this is an error message
+        */
+       public function myOutput( $text, $channel = null, $error = false ) {
+               if ( $error ) {
+                       $this->error( $text, $channel );
+               } else {
+                       $this->output( $text, $channel );
+               }
+       }
 }
-
-/// @endcond
 
 /**
  * Simple external changes syncer and conflict resolution.
  */
 class ChangeSyncer {
-       public $group; ///< \type{MessageGroup}
-       public $norc = false; ///< \bool Don't list changes in recent changes 
table.
-       public $interactive = true; ///< \bool Whether the script can ask 
questions.
-       public $nocolor = false; ///< \bool Disable color output.
+       /** @var callable Function to report progress updates */
+       protected $progressCallback;
 
+       /** @var bool  Don't list changes in recent changes table. */
+       public $norc = false;
+
+       /** @var bool Whether the script can ask questions. */
+       public $interactive = true;
+
+       /** @var bool Disable color output. */
+       public $nocolor = false;
+
+       /** @var MessageGroup */
+       protected $group;
+
+       /**
+        * @param MessageGroup $group Message group to synchronise.
+        * can be relayed back.
+        */
        public function __construct( MessageGroup $group ) {
                $this->group = $group;
+       }
+
+       public function setProgressCallback( $callback ) {
+               $this->progressCallback = $callback;
+       }
+
+       /// @see Maintenance::output for param docs
+       protected function reportProgress( $text, $channel, $severity = 
'status' ) {
+               if ( is_callable( $this->progressCallback ) ) {
+                       $useErrorOutput = $severity === 'error';
+                       call_user_func( $this->progressCallback, $text, 
$channel, $useErrorOutput );
+               }
        }
 
        // svn component from pecl doesn't seem to have this in quick sight
        /**
         * Fetch last changed timestamp for a versioned file for conflict 
resolution.
-        * @param $file \string Filename with full path.
-        * @return \string Timestamp or false.
+        * @param string $file Filename with full path.
+        * @return string Timestamp or false.
         */
        public function getTimestampsFromSvn( $file ) {
                $file = escapeshellarg( $file );
@@ -192,8 +266,8 @@
 
        /**
         * Fetch last changed timestamp for a versioned file for conflict 
resolution.
-        * @param $file \string Filename with full path.
-        * @return \string Timestamp or false.
+        * @param string $file Filename with full path.
+        * @return string|bool Timestamp or false.
         */
        public function getTimestampsFromGit( $file ) {
                $file = escapeshellarg( $file );
@@ -209,8 +283,8 @@
 
        /**
         * Fetch last changed timestamp for any file for conflict resolution.
-        * @param $file \string Filename with full path.
-        * @return \string Timestamp or false.
+        * @param string $file Filename with full path.
+        * @return string Timestamp or false.
         */
        public function getTimestampsFromFs( $file ) {
                if ( !file_exists( $file ) ) {
@@ -244,7 +318,6 @@
 
                foreach ( $messages as $key => $translation ) {
                        if ( !isset( $collection[$key] ) ) {
-                               // STDOUT( "Unknown key $key" );
                                continue;
                        }
 
@@ -258,7 +331,7 @@
                        $page = $title->getPrefixedText();
 
                        if ( $collection[$key]->translation() === null ) {
-                               STDOUT( "Importing $page as a new translation" 
);
+                               $this->reportProgress( "Importing $page as a 
new translation\n", 'importing' );
                                $this->import( $title, $translation, 'Importing 
a new translation' );
                                continue;
                        }
@@ -269,7 +342,7 @@
                                continue;
                        }
 
-                       STDOUT( "Conflict in " . $this->color( 'bold', $page ) 
. "!", $page );
+                       $this->reportProgress( "Conflict in " . $this->color( 
'bold', $page ) . "!", $page );
 
                        $iso = 'xnY-xnm-xnd"T"xnH:xni:xns';
                        $lang = RequestContext::getMain()->getLanguage();
@@ -300,10 +373,10 @@
 
                        if ( $changeTs ) {
                                if ( $wikiTs > $startTs && $changeTs <= $endTs 
) {
-                                       STDOUT( " →Changed in wiki after 
export: IGNORE", $page );
+                                       $this->reportProgress( " →Changed in 
wiki after export: IGNORE", $page );
                                        continue;
                                } elseif ( !$wikiTs || ( $changeTs > $endTs && 
$wikiTs < $startTs ) ) {
-                                       STDOUT( " →Changed in source after 
export: IMPORT", $page );
+                                       $this->reportProgress( " →Changed in 
source after export: IMPORT", $page );
                                        $this->import(
                                                $title,
                                                $translation,
@@ -317,14 +390,15 @@
                                continue;
                        }
 
-                       STDOUT( " →Needs manual resolution", $page );
-                       STDOUT( "Source translation at $changeDate:" );
-                       STDOUT( $this->color( 'blue', $translation ) . "\n" );
-                       STDOUT( "Wiki translation at $wikiDate:" );
-                       STDOUT( $this->color( 'green', $current ) . "\n" );
+                       $this->reportProgress( " →Needs manual resolution", 
$page );
+                       $this->reportProgress( "Source translation at 
$changeDate:", 'source' );
+                       $this->reportProgress( $this->color( 'blue', 
$translation ), 'source' );
+                       $this->reportProgress( "Wiki translation at 
$wikiDate:", 'translation' );
+                       $this->reportProgress( $this->color( 'green', $current 
), 'translation' );
 
                        do {
-                               STDOUT( "Resolution: [S]kip [I]mport 
[C]onflict: ", 'foo' );
+                               $this->reportProgress( "Resolution: [S]kip 
[I]mport [C]onflict: ", 'foo' );
+                               // @todo Find an elegant way to use 
Maintenance::readconsole().
                                $action = fgets( STDIN );
                                $action = strtoupper( trim( $action ) );
 
@@ -355,9 +429,9 @@
 
        /**
         * Colors text for shell output
-        * @param $color \string Either blue, green or bold.
-        * @param $text \string
-        * @return \string
+        * @param string $color Either blue, green or bold.
+        * @param string $text
+        * @return string
         */
        public function color( $color, $text ) {
                switch ( $color ) {
@@ -403,9 +477,9 @@
 
        /**
         * Does the actual edit.
-        * @param $title Title
-        * @param $translation \string
-        * @param $comment \string Edit summary.
+        * @param Title $title
+        * @param string $translation
+        * @param string $comment Edit summary.
         */
        public function import( $title, $translation, $comment ) {
                $flags = EDIT_FORCE_BOT;
@@ -414,14 +488,14 @@
                }
 
                $wikipage = new WikiPage( $title );
-               STDOUT( "Importing {$title->getPrefixedText()}: ", $title );
+               $this->reportProgress( "Importing {$title->getPrefixedText()}: 
", $title );
                $status = $wikipage->doEdit(
                        $translation, $comment, $flags, false, 
FuzzyBot::getUser()
                );
                $success = $status === true || ( is_object( $status ) && 
$status->isOK() );
-               STDOUT( $success ? 'OK' : 'FAILED', $title );
+               $this->reportProgress( $success ? 'OK' : 'FAILED', $title );
        }
 }
 
-// Print timestamp if the user wants to store it
-STDOUT( wfTimestamp( TS_RFC2822 ) );
+$maintClass = 'SyncGroup';
+require_once RUN_MAINTENANCE_IF_MAIN;

-- 
To view, visit https://gerrit.wikimedia.org/r/88985
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I8d7647d5bbb179c8d469437a450a166890b676bf
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/extensions/Translate
Gerrit-Branch: master
Gerrit-Owner: Siebrand <siebr...@wikimedia.org>
Gerrit-Reviewer: Nikerabbit <niklas.laxst...@gmail.com>
Gerrit-Reviewer: Siebrand <siebr...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to