2012-02-19 05:16:35 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright 2012 Facebook, Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Render some distracting statistics on revisions
|
|
|
|
*/
|
|
|
|
final class DifferentialRevisionStatsView extends AphrontView {
|
|
|
|
private $comments;
|
|
|
|
private $revisions;
|
|
|
|
private $user;
|
|
|
|
|
|
|
|
public function setRevisions(array $revisions) {
|
2012-04-04 22:13:08 +02:00
|
|
|
assert_instances_of($revisions, 'DifferentialRevision');
|
2012-02-19 05:16:35 +01:00
|
|
|
$this->revisions = $revisions;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setComments(array $comments) {
|
2012-04-04 22:13:08 +02:00
|
|
|
assert_instances_of($comments, 'DifferentialComment');
|
2012-02-19 05:16:35 +01:00
|
|
|
$this->comments = $comments;
|
|
|
|
return $this;
|
|
|
|
}
|
2012-04-04 22:13:08 +02:00
|
|
|
|
2012-02-19 05:16:35 +01:00
|
|
|
public function setUser($user) {
|
|
|
|
$this->user = $user;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function render() {
|
|
|
|
$user = $this->user;
|
|
|
|
if (!$user) {
|
|
|
|
throw new Exception("Call setUser() before render()!");
|
|
|
|
}
|
|
|
|
|
|
|
|
$id_to_revision_map = array();
|
|
|
|
foreach ($this->revisions as $rev) {
|
|
|
|
$id_to_revision_map[$rev->getID()] = $rev;
|
|
|
|
}
|
|
|
|
$revisions_seen = array();
|
|
|
|
|
|
|
|
$dates = array();
|
|
|
|
$counts = array();
|
|
|
|
$lines = array();
|
|
|
|
$boosts = array();
|
|
|
|
$days_with_diffs = array();
|
|
|
|
$count_active = array();
|
|
|
|
$now = time();
|
|
|
|
$row_array = array();
|
|
|
|
|
|
|
|
foreach (array(
|
|
|
|
'1 week', '2 weeks', '3 weeks',
|
|
|
|
'1 month', '2 months', '3 months', '6 months', '9 months',
|
|
|
|
'1 year', '18 months',
|
|
|
|
'2 years', '3 years', '4 years', '5 years',
|
|
|
|
) as $age) {
|
2012-06-26 23:56:45 +02:00
|
|
|
$dates[$age] = strtotime($age . ' ago 23:59:59');
|
2012-02-19 05:16:35 +01:00
|
|
|
$counts[$age] = 0;
|
|
|
|
$lines[$age] = 0;
|
|
|
|
$count_active[$age] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($this->comments as $comment) {
|
|
|
|
$rev_date = $comment->getDateCreated();
|
|
|
|
|
|
|
|
$day = phabricator_date($rev_date, $user);
|
|
|
|
$old_daycount = idx($days_with_diffs, $day, 0);
|
|
|
|
$days_with_diffs[$day] = $old_daycount + 1;
|
|
|
|
|
|
|
|
$rev_id = $comment->getRevisionID();
|
|
|
|
|
|
|
|
if (idx($revisions_seen, $rev_id)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$rev = $id_to_revision_map[$rev_id];
|
|
|
|
$revisions_seen[$rev_id] = true;
|
|
|
|
|
|
|
|
foreach ($dates as $age => $cutoff) {
|
2012-06-27 01:20:41 +02:00
|
|
|
if ($cutoff >= $rev_date) {
|
2012-02-19 05:16:35 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ($rev) {
|
|
|
|
$lines[$age] += $rev->getLineCount();
|
|
|
|
}
|
|
|
|
$counts[$age]++;
|
|
|
|
if (!$old_daycount) {
|
|
|
|
$count_active[$age]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$old_count = 0;
|
2012-03-02 01:32:31 +01:00
|
|
|
foreach (array_reverse($dates) as $age => $cutoff) {
|
2012-06-27 01:20:41 +02:00
|
|
|
$weeks = ceil(($now - $cutoff) / (60 * 60 * 24)) / 7;
|
2012-03-02 01:32:31 +01:00
|
|
|
if ($old_count == $counts[$age] && count($row_array) == 1) {
|
2012-06-27 01:20:41 +02:00
|
|
|
unset($dates[last_key($row_array)]);
|
2012-03-02 01:32:31 +01:00
|
|
|
$row_array = array();
|
2012-02-19 05:16:35 +01:00
|
|
|
}
|
|
|
|
$old_count = $counts[$age];
|
|
|
|
|
|
|
|
$row_array[$age] = array(
|
|
|
|
'Revisions per week' => number_format($counts[$age] / $weeks, 2),
|
|
|
|
'Lines per week' => number_format($lines[$age] / $weeks, 1),
|
|
|
|
'Active days per week' =>
|
|
|
|
number_format($count_active[$age] / $weeks, 1),
|
|
|
|
'Revisions' => number_format($counts[$age]),
|
|
|
|
'Lines' => number_format($lines[$age]),
|
|
|
|
'Lines per diff' => number_format($lines[$age] /
|
|
|
|
($counts[$age] + 0.0001)),
|
|
|
|
'Active days' => number_format($count_active[$age]),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$rows = array();
|
|
|
|
$row_names = array_keys(head($row_array));
|
|
|
|
foreach ($row_names as $row_name) {
|
|
|
|
$rows[] = array($row_name);
|
|
|
|
}
|
|
|
|
foreach (array_keys($dates) as $age) {
|
|
|
|
$i = 0;
|
|
|
|
foreach ($row_names as $row_name) {
|
|
|
|
$rows[$i][] = idx(idx($row_array, $age), $row_name, '-');
|
|
|
|
++$i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$table = new AphrontTableView($rows);
|
|
|
|
$table->setColumnClasses(
|
|
|
|
array(
|
|
|
|
'wide pri',
|
|
|
|
));
|
|
|
|
|
|
|
|
$table->setHeaders(
|
|
|
|
array_merge(
|
|
|
|
array(
|
|
|
|
'Metric',
|
|
|
|
),
|
|
|
|
array_keys($dates)));
|
|
|
|
|
|
|
|
return $table->render();
|
|
|
|
}
|
|
|
|
}
|