r75327 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r75326‎ | r75327 | r75328 >
Date:18:16, 24 October 2010
Author:catrope
Status:resolved (Comments)
Tags:
Comment:
CodeReview: (bug 24380) Add sign-off feature where any coder can sign off on a revision as either having inspected or testing it (or both). This is still pretty basic and needs more features, but I just wanted to get a bare-bones implementation in for now
Modified paths:
  • /trunk/extensions/CodeReview/CodeReview.i18n.php (modified) (history)
  • /trunk/extensions/CodeReview/CodeReview.php (modified) (history)
  • /trunk/extensions/CodeReview/backend/CodeRevision.php (modified) (history)
  • /trunk/extensions/CodeReview/codereview.sql (modified) (history)
  • /trunk/extensions/CodeReview/ui/CodeRevisionCommitter.php (modified) (history)
  • /trunk/extensions/CodeReview/ui/CodeRevisionView.php (modified) (history)

Diff [purge]

Index: trunk/extensions/CodeReview/CodeReview.i18n.php
@@ -99,6 +99,14 @@
100100 'code-status-desc-deferred' => 'Revision does not require review.',
101101 'code-status-old' => 'old',
102102 'code-status-desc-old' => 'Old revision with potential bugs but which are not worth the effort of reviewing them.',
 103+ 'code-signoffs' => 'Sign-offs',
 104+ 'code-signoff-legend' => 'Add sign-off',
 105+ 'code-signoff-submit' => 'Sign off',
 106+ 'code-signoff-flag-inspected' => 'Inspected',
 107+ 'code-signoff-flag-tested' => 'Tested',
 108+ 'code-signoff-field-user' => 'User',
 109+ 'code-signoff-field-flag' => 'Flag',
 110+ 'code-signoff-field-date' => 'Date',
103111 'code-pathsearch-legend' => 'Search revisions in this repo by path',
104112 'code-pathsearch-path' => 'Path:',
105113 'code-pathsearch-filter' => 'Filter applied:',
@@ -189,6 +197,7 @@
190198 'right-codereview-remove-tag' => 'Remove tags from revisions',
191199 'right-codereview-post-comment' => 'Add comments on revisions',
192200 'right-codereview-set-status' => 'Change revisions status',
 201+ 'right-codereview-signoff' => 'Sign off on revisions',
193202 'right-codereview-link-user' => 'Link authors to wiki users',
194203
195204 'specialpages-group-developer' => 'Developer tools',
Index: trunk/extensions/CodeReview/CodeReview.php
@@ -52,6 +52,7 @@
5353 $wgAutoloadClasses['CodeCommentLinkerHtml'] = $dir . 'backend/CodeCommentLinker.php';
5454 $wgAutoloadClasses['CodeCommentLinkerWiki'] = $dir . 'backend/CodeCommentLinker.php';
5555 $wgAutoloadClasses['CodePropChange'] = $dir . 'backend/CodePropChange.php';
 56+$wgAutoloadClasses['CodeSignoff'] = $dir . 'backend/CodeSignoff.php';
5657 $wgAutoloadClasses['RepoStats'] = $dir . 'backend/RepoStats.php';
5758
5859 $wgAutoloadClasses['CodeRepoListView'] = $dir . 'ui/CodeRepoListView.php';
@@ -93,6 +94,7 @@
9495 $wgAvailableRights[] = 'codereview-remove-tag';
9596 $wgAvailableRights[] = 'codereview-post-comment';
9697 $wgAvailableRights[] = 'codereview-set-status';
 98+$wgAvailableRights[] = 'codereview-signoff';
9799 $wgAvailableRights[] = 'codereview-link-user';
98100
99101 $wgGroupPermissions['*']['codereview-use'] = true;
@@ -102,6 +104,7 @@
103105 $wgGroupPermissions['user']['codereview-post-comment'] = true;
104106 $wgGroupPermissions['user']['codereview-set-status'] = true;
105107 $wgGroupPermissions['user']['codereview-link-user'] = true;
 108+$wgGroupPermissions['user']['codereview-signoff'] = true;
106109
107110 $wgGroupPermissions['steward']['repoadmin'] = true; // temp
108111
@@ -178,6 +181,7 @@
179182 }
180183
181184 $updater->addExtensionUpdate( array( 'addTable', 'code_bugs', "$base/archives/code_bugs.sql", true ) );
 185+ $updater->addExtensionUpdate( array( 'addTable', 'code_signoffs', "$base/archives/code_signoffs.sql", true ) );
182186 break;
183187 case 'sqlite':
184188 $updater->addExtensionUpdate( array( 'addTable', 'code_rev', "$base/codereview.sql", true ) );
Index: trunk/extensions/CodeReview/backend/CodeRevision.php
@@ -141,6 +141,10 @@
142142 public static function getPossibleStates() {
143143 return array( 'new', 'fixme', 'reverted', 'resolved', 'ok', 'verified', 'deferred', 'old' );
144144 }
 145+
 146+ public static function getPossibleFlags() {
 147+ return array( 'inspected', 'tested' );
 148+ }
145149
146150 public function isValidStatus( $status ) {
147151 return in_array( $status, self::getPossibleStates(), true );
@@ -628,6 +632,40 @@
629633 return $refs;
630634 }
631635
 636+ public function getSignoffs( $from = DB_SLAVE ) {
 637+ $db = wfGetDB( $from );
 638+ $result = $db->select( 'code_signoffs',
 639+ array( 'cs_user_text', 'cs_flag', 'cs_timestamp' ),
 640+ array(
 641+ 'cs_repo_id' => $this->mRepoId,
 642+ 'cs_rev_id' => $this->mId,
 643+ ),
 644+ __METHOD__,
 645+ array( 'ORDER BY' => 'cs_timestamp' )
 646+ );
 647+
 648+ $signoffs = array();
 649+ foreach ( $result as $row ) {
 650+ $signoffs[] = CodeSignoff::newFromRow( $this, $row );
 651+ }
 652+ return $signoffs;
 653+ }
 654+
 655+ public function addSignoff( $user, $flags ) {
 656+ $dbw = wfGetDB( DB_MASTER );
 657+ $rows = array();
 658+ foreach ( $flags as $flag ) {
 659+ $rows[] = array(
 660+ 'cs_repo_id' => $this->mRepoId,
 661+ 'cs_rev_id' => $this->mId,
 662+ 'cs_user_text' => $user->getName(),
 663+ 'cs_flag' => $flag,
 664+ 'cs_timestamp' => $dbw->timestamp(),
 665+ );
 666+ }
 667+ $dbw->insert( 'code_signoffs', $rows, __METHOD__ );
 668+ }
 669+
632670 public function getTags( $from = DB_SLAVE ) {
633671 $db = wfGetDB( $from );
634672 $result = $db->select( 'code_tags',
Index: trunk/extensions/CodeReview/codereview.sql
@@ -54,7 +54,7 @@
5555 -- 'verified': Reviewed and tested, no issues spotted
5656 -- 'deferred': Not reviewed at this time (usually non-Wikimedia extension)
5757 -- 'old': Predates the extension/doesn't require review
58 - -- See CodeRevision::getPossibleStates() (in backend\CodeRevision.php) for most up to date list
 58+ -- See CodeRevision::getPossibleStates() (in backend/CodeRevision.php) for most up to date list
5959 cr_status varchar(25) not null default 'new',
6060
6161 -- Base path of this revision :
@@ -221,3 +221,21 @@
222222
223223 CREATE INDEX /*i*/cpc_repo_rev_time ON /*_*/code_prop_changes (cpc_repo_id, cpc_rev_id, cpc_timestamp);
224224 CREATE INDEX /*i*/cpc_repo_time ON /*_*/code_prop_changes (cpc_repo_id, cpc_timestamp);
 225+
 226+CREATE TABLE /*_*/code_signoffs (
 227+ -- Repository ID and revision ID
 228+ cs_repo_id int not null,
 229+ cs_rev_id int not null,
 230+
 231+ -- User that signed off
 232+ cs_user_text varchar(255) not null,
 233+
 234+ -- Type of signoff. Current values: 'inspected', 'tested'
 235+ -- See CodeRevision::getPossibleFlags() (in backend/CodeRevision.php) for most up to date list
 236+ cs_flag varchar(25) not null,
 237+
 238+ -- Timestamp of the sign-off
 239+ cs_timestamp binary(14) not null default ''
 240+) /*$wgDBTableOptions*/;
 241+CREATE UNIQUE INDEX /*i*/cs_repo_rev_user_flag ON /*_*/code_signoffs (cs_repo_id, cs_rev_id, cs_user_text, cs_flag);
 242+CREATE INDEX /*i*/cs_repo_repo_rev_timestamp ON /*_*/code_signoffs (cs_repo_id, cs_rev_id, cs_timestamp);
Index: trunk/extensions/CodeReview/ui/CodeRevisionCommitter.php
@@ -40,6 +40,10 @@
4141 if ( count( $addTags ) || count( $removeTags ) ) {
4242 $this->mRev->changeTags( $addTags, $removeTags, $wgUser );
4343 }
 44+ // Add any signoffs
 45+ if ( $this->validPost( 'codereview-signoff' ) && count( $this->mSignoffFlags ) ) {
 46+ $this->mRev->addSignoff( $wgUser, $this->mSignoffFlags );
 47+ }
4448 // Add any comments
4549 $commentAdded = false;
4650 if ( $this->validPost( 'codereview-post-comment' ) && strlen( $this->text ) ) {
Index: trunk/extensions/CodeReview/ui/CodeRevisionView.php
@@ -28,6 +28,7 @@
2929 # Make tag arrays
3030 $this->mAddTags = $this->splitTags( $this->mAddTags );
3131 $this->mRemoveTags = $this->splitTags( $this->mRemoveTags );
 32+ $this->mSignoffFlags = $wgRequest->getArray( 'wpSignoffFlags' );
3233 }
3334
3435 function execute() {
@@ -108,6 +109,15 @@
109110 "<div class='mw-codereview-diff' id='mw-codereview-diff'>" . $diffHtml . "</div>\n";
110111 $html .= $this->formatImgDiff();
111112 }
 113+ # Show sign-offs
 114+ $signoffs = $this->formatSignoffs();
 115+ if ( $signoffs ) {
 116+ $html .= "<h2 id='code-signoffs'>" . wfMsgHtml( 'code-signoffs' ) .
 117+ "</h2>\n" . $signoffs;
 118+ }
 119+ if( $this->canSignoff() ) {
 120+ $html .= $this->signoffForm();
 121+ }
112122 # Show code relations
113123 $relations = $this->formatReferences();
114124 if ( $relations ) {
@@ -193,6 +203,11 @@
194204 return $wgUser->isAllowed( 'codereview-post-comment' ) && !$wgUser->isBlocked();
195205 }
196206
 207+ protected function canSignoff() {
 208+ global $wgUser;
 209+ return $wgUser->isAllowed( 'codereview-signoff' ) && !$wgUser->isBlocked();
 210+ }
 211+
197212 protected function formatPathLine( $path, $action ) {
198213 // Uses messages 'code-rev-modified-a', 'code-rev-modified-r', 'code-rev-modified-d', 'code-rev-modified-m'
199214 $desc = wfMsgHtml( 'code-rev-modified-' . strtolower( $action ) );
@@ -396,6 +411,19 @@
397412 );" );
398413 return wfMsg( 'code-load-diff' );
399414 }
 415+
 416+ protected function formatSignoffs() {
 417+ $signoffs = implode( "\n",
 418+ array_map( array( $this, 'formatSignoffInline' ), $this->mRev->getSignoffs() )
 419+ );
 420+ if ( !$signoffs ) {
 421+ return false;
 422+ }
 423+ $header = '<th>' . wfMsg( 'code-signoff-field-user' ) . '</th>';
 424+ $header .= '<th>' . wfMsg( 'code-signoff-field-flag' ). '</th>';
 425+ $header .= '<th>' . wfMsg( 'code-signoff-field-date' ). '</th>';
 426+ return "<table border='1' class='TablePager'><tr>$header</tr>$signoffs</table>";
 427+ }
400428
401429 protected function formatComments() {
402430 $comments = implode( "\n",
@@ -434,6 +462,15 @@
435463 return "<table border='1' class='TablePager'><tr>{$header}</tr>{$refs}</table>";
436464 }
437465
 466+ protected function formatSignoffInline( $signoff ) {
 467+ global $wgLang;
 468+ $user = htmlspecialchars( $signoff->user );
 469+ $flag = htmlspecialchars( $signoff->flag );
 470+ $date = $wgLang->timeanddate( $signoff->timestamp, true );
 471+ $class = "mw-codereview-signoff-$flag";
 472+ return "<tr class='$class'><td>$user</td><td>$flag</td><td>$date</td></tr>";
 473+ }
 474+
438475 protected function formatCommentInline( $comment ) {
439476 if ( $comment->id === $this->mReplyTarget ) {
440477 return $this->formatComment( $comment,
@@ -593,6 +630,16 @@
594631 '</div>';
595632 }
596633
 634+ protected function signoffForm() {
 635+ $form = Xml::element( 'legend', array(), wfMsg( 'code-signoff-legend' ) );
 636+ foreach ( CodeRevision::getPossibleFlags() as $flag ) {
 637+ $form .= Html::input( 'wpSignoffFlags[]', $flag, 'checkbox', array( 'id' => "wpSignoffFlags-$flag" ) ) .
 638+ Xml::label( wfMsg( "code-signoff-flag-$flag" ), "wpSignoffFlags-$flag" ) . "\n";
 639+ }
 640+ $form .= Xml::submitButton( wfMsg( 'code-signoff-submit' ) );
 641+ return Xml::tags( 'fieldset', array(), $form );
 642+ }
 643+
597644 protected function addActionButtons() {
598645 return '<div>' .
599646 Xml::submitButton( wfMsg( 'code-rev-submit' ),

Follow-up revisions

RevisionCommit summaryAuthorDate
r75329Follow-up r75327: add forgotten patch file, register it for SQLite.maxsem18:33, 24 October 2010
r75430Add forgotten file in r75327catrope15:27, 26 October 2010
r77326Document functions added in r75327, r77302 (sign-off feature), fix comments a...catrope12:18, 26 November 2010

Comments

#Comment by Reedy (talk | contribs)   23:18, 24 October 2010

Are you going to log a bug (or many) for the TODO's for this stuff? As you've closed the bug ;)

#Comment by Catrope (talk | contribs)   15:32, 26 October 2010

Will file some bugs for the TODOs, yeah. Was just trying to get the bare-bones implementation out there before my flight back home and the subsequent jetlag recovery.

#Comment by Bryan (talk | contribs)   04:32, 25 October 2010

backend/CodeSignoff.php is missing

#Comment by Nikerabbit (talk | contribs)   12:57, 28 October 2010
#Comment by Catrope (talk | contribs)   15:02, 28 October 2010

Added some message docs.

#Comment by Reedy (talk | contribs)   22:10, 21 November 2010

Fixme per bug 26042

#Comment by Catrope (talk | contribs)   10:21, 26 November 2010

Fixed

Status & tagging log