Index: trunk/extensions/CodeReview/CodeReview.php |
— | — | @@ -241,6 +241,13 @@ |
242 | 242 | $wgCodeReviewAutoTagPath = array(); |
243 | 243 | |
244 | 244 | /** |
| 245 | + * Key is repository name. Value is an array of key value pairs of the paths to get fixme list for |
| 246 | + * |
| 247 | + * $wgCodeReviewFixmePerPath = array( 'RepoName' => array( '%^/path/to/use%', '%^/another/path/to/use%' ) ) |
| 248 | + */ |
| 249 | +$wgCodeReviewFixmePerPath = array(); |
| 250 | + |
| 251 | +/** |
245 | 252 | * UDP comment and status changes notification |
246 | 253 | */ |
247 | 254 | $wgCodeReviewUDPAddress = false; |
Index: trunk/extensions/CodeReview/backend/RepoStats.php |
— | — | @@ -16,6 +16,8 @@ |
17 | 17 | $fixmes, |
18 | 18 | $new; |
19 | 19 | |
| 20 | + public $fixmesPerPath; |
| 21 | + |
20 | 22 | /** |
21 | 23 | * @param CodeRepository $repo |
22 | 24 | * @return RepoStats |
— | — | @@ -74,7 +76,13 @@ |
75 | 77 | |
76 | 78 | $this->fixmes = $this->getAuthorStatusCounts( 'fixme' ); |
77 | 79 | $this->new = $this->getAuthorStatusCounts( 'new' ); |
78 | | - |
| 80 | + $this->fixmesPerPath = array(); |
| 81 | + global $wgCodeReviewFixmePerPath; |
| 82 | + if ( isset( $wgCodeReviewFixmePerPath[ $this->repo->getName() ] ) ) { |
| 83 | + foreach( $wgCodeReviewFixmePerPath[ $this->repo->getName() ] as $path ) { |
| 84 | + $this->fixmesPerPath[$path] = $this->getPathFixmes( $path ); |
| 85 | + } |
| 86 | + } |
79 | 87 | wfProfileOut( __METHOD__ ); |
80 | 88 | } |
81 | 89 | |
— | — | @@ -101,4 +109,35 @@ |
102 | 110 | } |
103 | 111 | return $array; |
104 | 112 | } |
| 113 | + |
| 114 | + /** |
| 115 | + * @param $path path to get fixmes for |
| 116 | + * @return array |
| 117 | + */ |
| 118 | + private function getPathFixmes( $path ) { |
| 119 | + $array = array(); |
| 120 | + $dbr = wfGetDB( DB_SLAVE ); |
| 121 | + $res = $dbr->select( |
| 122 | + array( 'code_paths', 'code_rev' ), |
| 123 | + array( 'COUNT(*) AS revs', 'cr_author' ), |
| 124 | + array( |
| 125 | + 'cr_repo_id' => $this->repo->getId(), |
| 126 | + 'cp_path' => $path, |
| 127 | + 'cr_status' => 'fixme', |
| 128 | + ), |
| 129 | + __METHOD__, |
| 130 | + array( |
| 131 | + 'GROUP BY' => 'cr_author', |
| 132 | + 'ORDER BY' => 'revs DESC', |
| 133 | + 'LIMIT' => 500, |
| 134 | + ), |
| 135 | + array( |
| 136 | + 'code_rev' => array( 'INNER JOIN', 'cr_repo_id = cp_repo_id AND cr_id = cp_rev_id' ) |
| 137 | + ) |
| 138 | + ); |
| 139 | + foreach ( $res as $row ) { |
| 140 | + $array[$row->cr_author] = $row->revs; |
| 141 | + } |
| 142 | + return $array; |
| 143 | + } |
105 | 144 | } |
\ No newline at end of file |
Index: trunk/extensions/CodeReview/CodeReview.i18n.php |
— | — | @@ -208,6 +208,8 @@ |
209 | 209 | 'code-stats-main' => 'As of $1, the repository has $2 {{PLURAL:$2|revision|revisions}} by [[Special:Code/$3/author|$4 {{PLURAL:$4|author|authors}}]].', |
210 | 210 | 'code-stats-status-breakdown' => 'Number of revisions per state', |
211 | 211 | 'code-stats-fixme-breakdown' => 'Breakdown of fixme revisions per author', |
| 212 | + 'code-stats-fixme-breakdown-path' => 'Breakdown of fixme revisions per path', |
| 213 | + 'code-stats-fixme-path' => 'Fixme revisions for path: $1', |
212 | 214 | 'code-stats-new-breakdown' => 'Breakdown of new revisions per author', |
213 | 215 | 'code-stats-count' => 'Number of revisions', |
214 | 216 | |
Index: trunk/extensions/CodeReview/ui/CodeRepoStatsView.php |
— | — | @@ -47,6 +47,15 @@ |
48 | 48 | if ( !empty( $stats->new ) ) { |
49 | 49 | $this->writeAuthorStatusTable( 'new', $stats->new ); |
50 | 50 | } |
| 51 | + |
| 52 | + if ( !empty( $stats->fixmesPerPath ) ) { |
| 53 | + $wgOut->wrapWikiMsg( "<h3 id=\"stats-fixme-path\">$1</h3>", 'code-stats-fixme-breakdown-path' ); |
| 54 | + |
| 55 | + foreach ( $stats->fixmesPerPath as $path => $fixmes ) { |
| 56 | + $wgOut->wrapWikiMsg( "<h4 id=\"stats-fixme-path\">$1</h4>", 'code-stats-fixme-path', $path ); |
| 57 | + $this->writeAuthorTable( 'fixme', $fixmes, array( 'path' => $path ) ); |
| 58 | + } |
| 59 | + } |
51 | 60 | } |
52 | 61 | |
53 | 62 | /** |
— | — | @@ -54,20 +63,32 @@ |
55 | 64 | * @param $array array |
56 | 65 | */ |
57 | 66 | function writeAuthorStatusTable( $status, $array ) { |
| 67 | + global $wgOut; |
| 68 | + $wgOut->wrapWikiMsg( "<h3 id=\"stats-{$status}\">$1</h3>", "code-stats-{$status}-breakdown" ); |
| 69 | + $this->writeAuthorTable( $status, $array ); |
| 70 | + } |
| 71 | + |
| 72 | + /** |
| 73 | + * @param $status string |
| 74 | + * @param $array array |
| 75 | + * @param $options array |
| 76 | + */ |
| 77 | + function writeAuthorTable( $status, $array, $options = array() ) { |
58 | 78 | global $wgOut, $wgLang; |
| 79 | + |
59 | 80 | $repoName = $this->mRepo->getName(); |
60 | | - $wgOut->wrapWikiMsg( "<h3 id=\"stats-{$status}\">$1</h3>", "code-stats-{$status}-breakdown" ); |
61 | 81 | $wgOut->addHTML( '<table class="wikitable">' |
62 | 82 | . '<tr><th>' . wfMsgHtml( 'code-field-author' ) . '</th><th>' |
63 | 83 | . wfMsgHtml( 'code-stats-count' ) . '</th></tr>' ); |
64 | 84 | $title = SpecialPage::getTitleFor( 'Code', $repoName . "/status/{$status}" ); |
| 85 | + |
65 | 86 | foreach ( $array as $user => $count ) { |
66 | 87 | $count = htmlspecialchars( $wgLang->formatNum( $count ) ); |
67 | 88 | $link = $this->skin->link( |
68 | 89 | $title, |
69 | 90 | htmlspecialchars( $user ), |
70 | 91 | array(), |
71 | | - array( 'author' => $user ) |
| 92 | + array_merge( $options, array( 'author' => $user ) ) |
72 | 93 | ); |
73 | 94 | $wgOut->addHTML( "<tr><td>$link</td>" |
74 | 95 | . "<td>$count</td></tr>" ); |