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:
parent
76cba9d46b
commit
f658f17080
5 changed files with 355 additions and 0 deletions
|
@ -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',
|
||||||
|
|
76
src/workflow/ArcanistPhrequentWorkflow.php
Normal file
76
src/workflow/ArcanistPhrequentWorkflow.php
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
92
src/workflow/ArcanistStartWorkflow.php
Normal file
92
src/workflow/ArcanistStartWorkflow.php
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
132
src/workflow/ArcanistStopWorkflow.php
Normal file
132
src/workflow/ArcanistStopWorkflow.php
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
src/workflow/ArcanistTimeWorkflow.php
Normal file
47
src/workflow/ArcanistTimeWorkflow.php
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue