1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-29 02:02:40 +01:00

Add Phrequent workflows to Arcanist

Summary:
Depends on D9906.

This adds `arc start`, `arc stop` and `arc tracking` for tracking tasks, diffs and other objects in Phrequent.

Test Plan: Tested this against a local install.

Reviewers: skyronic, #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: maxhodak, hach-que, aran, epriestley, Korvin

Maniphest Tasks: T3569, T3969

Differential Revision: https://secure.phabricator.com/D7327
This commit is contained in:
James Rhodes 2014-07-17 11:58:22 +10:00
parent 76cba9d46b
commit f658f17080
5 changed files with 355 additions and 0 deletions

View file

@ -134,6 +134,7 @@ phutil_register_library_map(array(
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php', 'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php', 'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
'ArcanistPhpcsLinter' => 'lint/linter/ArcanistPhpcsLinter.php', 'ArcanistPhpcsLinter' => 'lint/linter/ArcanistPhpcsLinter.php',
'ArcanistPhrequentWorkflow' => 'workflow/ArcanistPhrequentWorkflow.php',
'ArcanistPhutilLibraryLinter' => 'lint/linter/ArcanistPhutilLibraryLinter.php', 'ArcanistPhutilLibraryLinter' => 'lint/linter/ArcanistPhutilLibraryLinter.php',
'ArcanistPhutilTestCase' => 'unit/engine/phutil/ArcanistPhutilTestCase.php', 'ArcanistPhutilTestCase' => 'unit/engine/phutil/ArcanistPhutilTestCase.php',
'ArcanistPhutilTestCaseTestCase' => 'unit/engine/phutil/testcase/ArcanistPhutilTestCaseTestCase.php', 'ArcanistPhutilTestCaseTestCase' => 'unit/engine/phutil/testcase/ArcanistPhutilTestCaseTestCase.php',
@ -160,6 +161,8 @@ phutil_register_library_map(array(
'ArcanistSingleLintEngine' => 'lint/engine/ArcanistSingleLintEngine.php', 'ArcanistSingleLintEngine' => 'lint/engine/ArcanistSingleLintEngine.php',
'ArcanistSpellingLinter' => 'lint/linter/ArcanistSpellingLinter.php', 'ArcanistSpellingLinter' => 'lint/linter/ArcanistSpellingLinter.php',
'ArcanistSpellingLinterTestCase' => 'lint/linter/__tests__/ArcanistSpellingLinterTestCase.php', 'ArcanistSpellingLinterTestCase' => 'lint/linter/__tests__/ArcanistSpellingLinterTestCase.php',
'ArcanistStartWorkflow' => 'workflow/ArcanistStartWorkflow.php',
'ArcanistStopWorkflow' => 'workflow/ArcanistStopWorkflow.php',
'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php', 'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php',
'ArcanistSubversionHookAPI' => 'repository/hookapi/ArcanistSubversionHookAPI.php', 'ArcanistSubversionHookAPI' => 'repository/hookapi/ArcanistSubversionHookAPI.php',
'ArcanistSvnHookPreCommitWorkflow' => 'workflow/ArcanistSvnHookPreCommitWorkflow.php', 'ArcanistSvnHookPreCommitWorkflow' => 'workflow/ArcanistSvnHookPreCommitWorkflow.php',
@ -167,6 +170,7 @@ phutil_register_library_map(array(
'ArcanistTestCase' => 'infrastructure/testing/ArcanistTestCase.php', 'ArcanistTestCase' => 'infrastructure/testing/ArcanistTestCase.php',
'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php', 'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php',
'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php', 'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php',
'ArcanistTimeWorkflow' => 'workflow/ArcanistTimeWorkflow.php',
'ArcanistTodoWorkflow' => 'workflow/ArcanistTodoWorkflow.php', 'ArcanistTodoWorkflow' => 'workflow/ArcanistTodoWorkflow.php',
'ArcanistUncommittedChangesException' => 'exception/usage/ArcanistUncommittedChangesException.php', 'ArcanistUncommittedChangesException' => 'exception/usage/ArcanistUncommittedChangesException.php',
'ArcanistUnitConsoleRenderer' => 'unit/renderer/ArcanistUnitConsoleRenderer.php', 'ArcanistUnitConsoleRenderer' => 'unit/renderer/ArcanistUnitConsoleRenderer.php',
@ -308,6 +312,7 @@ phutil_register_library_map(array(
'ArcanistPasteWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistPasteWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistPatchWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistPatchWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistPhpcsLinter' => 'ArcanistExternalLinter', 'ArcanistPhpcsLinter' => 'ArcanistExternalLinter',
'ArcanistPhrequentWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistPhutilLibraryLinter' => 'ArcanistLinter', 'ArcanistPhutilLibraryLinter' => 'ArcanistLinter',
'ArcanistPhutilTestCaseTestCase' => 'ArcanistPhutilTestCase', 'ArcanistPhutilTestCaseTestCase' => 'ArcanistPhutilTestCase',
'ArcanistPhutilTestSkippedException' => 'Exception', 'ArcanistPhutilTestSkippedException' => 'Exception',
@ -331,6 +336,8 @@ phutil_register_library_map(array(
'ArcanistSingleLintEngine' => 'ArcanistLintEngine', 'ArcanistSingleLintEngine' => 'ArcanistLintEngine',
'ArcanistSpellingLinter' => 'ArcanistLinter', 'ArcanistSpellingLinter' => 'ArcanistLinter',
'ArcanistSpellingLinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistSpellingLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistStartWorkflow' => 'ArcanistPhrequentWorkflow',
'ArcanistStopWorkflow' => 'ArcanistPhrequentWorkflow',
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI', 'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
'ArcanistSubversionHookAPI' => 'ArcanistHookAPI', 'ArcanistSubversionHookAPI' => 'ArcanistHookAPI',
'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow',
@ -338,6 +345,7 @@ phutil_register_library_map(array(
'ArcanistTestCase' => 'ArcanistPhutilTestCase', 'ArcanistTestCase' => 'ArcanistPhutilTestCase',
'ArcanistTextLinter' => 'ArcanistLinter', 'ArcanistTextLinter' => 'ArcanistLinter',
'ArcanistTextLinterTestCase' => 'ArcanistArcanistLinterTestCase', 'ArcanistTextLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistTimeWorkflow' => 'ArcanistPhrequentWorkflow',
'ArcanistTodoWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistTodoWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistUncommittedChangesException' => 'ArcanistUsageException', 'ArcanistUncommittedChangesException' => 'ArcanistUsageException',
'ArcanistUnitConsoleRenderer' => 'ArcanistUnitRenderer', 'ArcanistUnitConsoleRenderer' => 'ArcanistUnitRenderer',

View file

@ -0,0 +1,76 @@
<?php
/**
* Base workflow for Phrequent workflows
*/
abstract class ArcanistPhrequentWorkflow extends ArcanistBaseWorkflow {
protected function printCurrentTracking() {
$conduit = $this->getConduit();
$results = $conduit->callMethodSynchronous(
'phrequent.tracking',
array(
));
$results = $results['data'];
if (count($results) === 0) {
echo phutil_console_format(
"Not currently tracking time against any object\n");
return 0;
}
$phids_to_lookup = array();
foreach ($results as $result) {
$phids_to_lookup[] = $result['phid'];
}
$phid_query = $conduit->callMethodSynchronous(
'phid.query',
array(
'phids' => $phids_to_lookup,
));
$phid_map = array();
foreach ($phids_to_lookup as $lookup) {
if (array_key_exists($lookup, $phid_query)) {
$phid_map[$lookup] = $phid_query[$lookup]['fullName'];
} else {
$phid_map[$lookup] = 'Unknown Object';
}
}
$table = id(new PhutilConsoleTable())
->addColumn('type', array('title' => 'Status'))
->addColumn('time', array('title' => 'Tracked', 'align' => 'right'))
->addColumn('name', array('title' => 'Name'))
->setBorders(false);
$i = 0;
foreach ($results as $result) {
if ($result['ongoing']) {
if ($i === 0) {
$column_type = 'In Progress';
} else {
$column_type = 'Suspended';
}
} else {
$column_type = 'Stopped';
}
$table->addRow(array(
'type' => '('.$column_type.')',
'time' => phutil_format_relative_time($result['time']),
'name' => $phid_map[$result['phid']],
));
$i++;
}
$table->draw();
return 0;
}
}

View file

@ -0,0 +1,92 @@
<?php
/**
* Start time tracking on an object
*/
final class ArcanistStartWorkflow extends ArcanistPhrequentWorkflow {
public function getWorkflowName() {
return 'start';
}
public function getCommandSynopses() {
return phutil_console_format(<<<EOTEXT
**start** __object__
EOTEXT
);
}
public function getCommandHelp() {
return phutil_console_format(<<<EOTEXT
Start tracking work in Phrequent.
EOTEXT
);
}
public function requiresConduit() {
return true;
}
public function desiresWorkingCopy() {
return false;
}
public function requiresAuthentication() {
return true;
}
public function getArguments() {
return array(
'*' => 'name',
);
}
public function run() {
$conduit = $this->getConduit();
$started_phids = array();
$short_name = $this->getArgument('name');
foreach ($short_name as $object_name) {
$object_lookup = $conduit->callMethodSynchronous(
'phid.lookup',
array(
'names' => array($object_name),
));
if (!array_key_exists($object_name, $object_lookup)) {
echo "No such object '".$object_name."' found.\n";
return 1;
}
$object_phid = $object_lookup[$object_name]['phid'];
$started_phids[] = $conduit->callMethodSynchronous(
'phrequent.push',
array(
'objectPHID' => $object_phid
));
}
$phid_query = $conduit->callMethodSynchronous(
'phid.query',
array(
'phids' => $started_phids,
));
$name = '';
foreach ($phid_query as $ref) {
if ($name === '') {
$name = $ref['fullName'];
} else {
$name .= ', '.$ref['fullName'];
}
}
echo phutil_console_format(
"Started: %s\n\n",
$name);
$this->printCurrentTracking(true);
}
}

View file

@ -0,0 +1,132 @@
<?php
/**
* Stop time tracking on an object
*/
final class ArcanistStopWorkflow extends ArcanistPhrequentWorkflow {
public function getWorkflowName() {
return 'stop';
}
public function getCommandSynopses() {
return phutil_console_format(<<<EOTEXT
**stop** [--note __note__] [__objects__]
EOTEXT
);
}
public function getCommandHelp() {
return phutil_console_format(<<<EOTEXT
Start tracking work in Phrequent.
EOTEXT
);
}
public function requiresConduit() {
return true;
}
public function desiresWorkingCopy() {
return false;
}
public function requiresAuthentication() {
return true;
}
public function getArguments() {
return array(
'note' => array(
'param' => 'note',
'help' =>
'A note to attach to the tracked time.',
),
'*' => 'name',
);
}
public function run() {
$conduit = $this->getConduit();
$names = $this->getArgument('name');
$object_lookup = $conduit->callMethodSynchronous(
'phid.lookup',
array(
'names' => $names,
));
foreach ($names as $object_name) {
if (!array_key_exists($object_name, $object_lookup)) {
throw new ArcanistUsageException(
"No such object '".$object_name."' found.");
return 1;
}
}
if (count($names) === 0) {
// Implicit stop; add an entry so the loop will call
// phrequent.pop with a null objectPHID.
$object_lookup[] = array('phid' => null);
}
$stopped_phids = array();
foreach ($object_lookup as $ref) {
$object_phid = $ref['phid'];
$stopped_phid = $conduit->callMethodSynchronous(
'phrequent.pop',
array(
'objectPHID' => $object_phid,
'note' => $this->getArgument('note'),
));
if ($stopped_phid !== null) {
$stopped_phids[] = $stopped_phid;
}
}
if (count($stopped_phids) === 0) {
if (count($names) === 0) {
echo phutil_console_format(
"Not currently tracking time against any object\n");
} else {
$name = '';
foreach ($object_lookup as $ref) {
if ($name === '') {
$name = $ref['fullName'];
} else {
$name = ', '.$ref['fullName'];
}
}
echo phutil_console_format(
"Not currently tracking time against %s\n",
$name);
}
return 1;
}
$phid_query = $conduit->callMethodSynchronous(
'phid.query',
array(
'phids' => $stopped_phids,
));
$name = '';
foreach ($phid_query as $ref) {
if ($name === '') {
$name = $ref['fullName'];
} else {
$name .= ', '.$ref['fullName'];
}
}
echo phutil_console_format(
"Stopped: %s\n\n",
$name);
$this->printCurrentTracking(true);
}
}

View file

@ -0,0 +1,47 @@
<?php
/**
* Show time being tracked in Phrequent
*/
final class ArcanistTimeWorkflow extends ArcanistPhrequentWorkflow {
public function getWorkflowName() {
return 'time';
}
public function getCommandSynopses() {
return phutil_console_format(<<<EOTEXT
**time**
EOTEXT
);
}
public function getCommandHelp() {
return phutil_console_format(<<<EOTEXT
Show what you're currently tracking in Phrequent.
EOTEXT
);
}
public function requiresConduit() {
return true;
}
public function desiresWorkingCopy() {
return false;
}
public function requiresAuthentication() {
return true;
}
public function getArguments() {
return array(
);
}
public function run() {
$this->printCurrentTracking();
}
}