1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-12-03 04:02:42 +01:00
phorge-arcanist/src/workflow/ArcanistBranchWorkflow.php
vrana 0b45ec30be Move files in Arcanist one level up
Summary:
- `kill_init.php`
- Manually change library map.
- Manually rename `/data/` test dirs.
- [src/lint/linter] `git mv base/ArcanistLinterTestCase.php __tests__/`
- `arc liberate`

Test Plan: Browse around to make sure I like it better, especially `repository/api`, and `workflow`.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Koolvin

Maniphest Tasks: T1103

Differential Revision: https://secure.phabricator.com/D2637
2012-06-01 11:56:00 -07:00

175 lines
5 KiB
PHP

<?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.
*/
/**
* Displays user's git branches
*
* @group workflow
*/
final class ArcanistBranchWorkflow extends ArcanistBaseWorkflow {
private $branches;
public function getCommandSynopses() {
return phutil_console_format(<<<EOTEXT
**branch**
EOTEXT
);
}
public function getCommandHelp() {
return phutil_console_format(<<<EOTEXT
Supports: git
A wrapper on 'git branch'. It pulls data from Differential and
displays the revision status next to the branch name.
Branches are sorted in ascending order by the last commit time.
By default branches with closed/abandoned revisions
are not displayed.
EOTEXT
);
}
public function requiresConduit() {
return true;
}
public function requiresRepositoryAPI() {
return true;
}
public function requiresAuthentication() {
return true;
}
public function getArguments() {
return array(
'view-all' => array(
'help' =>
"Include closed and abandoned revisions",
),
'by-status' => array(
'help' => 'Group output by revision status.',
),
);
}
public function run() {
$repository_api = $this->getRepositoryAPI();
if (!($repository_api instanceof ArcanistGitAPI)) {
throw new ArcanistUsageException(
"arc branch is only supported under git."
);
}
$this->branches = BranchInfo::loadAll($repository_api);
$all_revisions = array_unique(
array_filter(mpull($this->branches, 'getRevisionId')));
$revision_status = $this->loadDifferentialStatuses($all_revisions);
$owner = $repository_api->getRepositoryOwner();
foreach ($this->branches as $branch) {
if ($branch->getCommitAuthor() != $owner) {
$branch->setStatus('Not Yours');
continue;
}
$rev_id = $branch->getRevisionID();
if ($rev_id) {
$status = idx($revision_status, $rev_id, 'Unknown Status');
$branch->setStatus($status);
} else {
$branch->setStatus('No Revision');
}
}
if (!$this->getArgument('view-all')) {
$this->filterOutFinished();
}
$this->printInColumns();
}
/**
* Makes a conduit call to differential to find out revision statuses
* based on their IDs
*/
private function loadDifferentialStatuses($rev_ids) {
$conduit = $this->getConduit();
$revisions = $conduit->callMethodSynchronous(
'differential.query',
array(
'ids' => $rev_ids,
));
$statuses = ipull($revisions, 'statusName', 'id');
return $statuses;
}
/**
* Removes the branches with status either closed or abandoned.
*/
private function filterOutFinished() {
foreach ($this->branches as $id => $branch) {
if ($branch->isCurrentHead() ) {
continue; //never filter the current branch
}
$status = $branch->getStatus();
if ($status == 'Closed' || $status == 'Abandoned') {
unset($this->branches[$id]);
}
}
}
public function printInColumns() {
$longest_name = 0;
$longest_status = 0;
foreach ($this->branches as $branch) {
$longest_name = max(strlen($branch->getFormattedName()), $longest_name);
$longest_status = max(strlen($branch->getStatus()), $longest_status);
}
if ($this->getArgument('by-status')) {
$by_status = mgroup($this->branches, 'getStatus');
foreach (array('Accepted', 'Needs Revision',
'Needs Review', 'No Revision') as $status) {
$branches = idx($by_status, $status);
if (!$branches) {
continue;
}
echo reset($branches)->getFormattedStatus()."\n";
foreach ($branches as $branch) {
$name_markdown = $branch->getFormattedName();
$subject = $branch->getCommitDisplayName();
$name_markdown = str_pad($name_markdown, $longest_name + 4, ' ');
echo " $name_markdown $subject\n";
}
}
} else {
foreach ($this->branches as $branch) {
$name_markdown = $branch->getFormattedName();
$status_markdown = $branch->getFormattedStatus();
$subject = $branch->getCommitDisplayName();
$subject_pad = $longest_status - strlen($branch->getStatus()) + 4;
$name_markdown =
str_pad($name_markdown, $longest_name + 4, ' ');
$subject =
str_pad($subject, strlen($subject) + $subject_pad, ' ', STR_PAD_LEFT);
echo "$name_markdown $status_markdown $subject\n";
}
}
}
}