diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -134,6 +134,7 @@ 'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php', 'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php', 'ArcanistPhpcsLinter' => 'lint/linter/ArcanistPhpcsLinter.php', + 'ArcanistPhrequentWorkflow' => 'workflow/ArcanistPhrequentWorkflow.php', 'ArcanistPhutilLibraryLinter' => 'lint/linter/ArcanistPhutilLibraryLinter.php', 'ArcanistPhutilTestCase' => 'unit/engine/phutil/ArcanistPhutilTestCase.php', 'ArcanistPhutilTestCaseTestCase' => 'unit/engine/phutil/testcase/ArcanistPhutilTestCaseTestCase.php', @@ -160,6 +161,8 @@ 'ArcanistSingleLintEngine' => 'lint/engine/ArcanistSingleLintEngine.php', 'ArcanistSpellingLinter' => 'lint/linter/ArcanistSpellingLinter.php', 'ArcanistSpellingLinterTestCase' => 'lint/linter/__tests__/ArcanistSpellingLinterTestCase.php', + 'ArcanistStartWorkflow' => 'workflow/ArcanistStartWorkflow.php', + 'ArcanistStopWorkflow' => 'workflow/ArcanistStopWorkflow.php', 'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php', 'ArcanistSubversionHookAPI' => 'repository/hookapi/ArcanistSubversionHookAPI.php', 'ArcanistSvnHookPreCommitWorkflow' => 'workflow/ArcanistSvnHookPreCommitWorkflow.php', @@ -167,6 +170,7 @@ 'ArcanistTestCase' => 'infrastructure/testing/ArcanistTestCase.php', 'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php', 'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php', + 'ArcanistTimeWorkflow' => 'workflow/ArcanistTimeWorkflow.php', 'ArcanistTodoWorkflow' => 'workflow/ArcanistTodoWorkflow.php', 'ArcanistUncommittedChangesException' => 'exception/usage/ArcanistUncommittedChangesException.php', 'ArcanistUnitConsoleRenderer' => 'unit/renderer/ArcanistUnitConsoleRenderer.php', @@ -308,6 +312,7 @@ 'ArcanistPasteWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistPatchWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistPhpcsLinter' => 'ArcanistExternalLinter', + 'ArcanistPhrequentWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistPhutilLibraryLinter' => 'ArcanistLinter', 'ArcanistPhutilTestCaseTestCase' => 'ArcanistPhutilTestCase', 'ArcanistPhutilTestSkippedException' => 'Exception', @@ -331,6 +336,8 @@ 'ArcanistSingleLintEngine' => 'ArcanistLintEngine', 'ArcanistSpellingLinter' => 'ArcanistLinter', 'ArcanistSpellingLinterTestCase' => 'ArcanistArcanistLinterTestCase', + 'ArcanistStartWorkflow' => 'ArcanistPhrequentWorkflow', + 'ArcanistStopWorkflow' => 'ArcanistPhrequentWorkflow', 'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI', 'ArcanistSubversionHookAPI' => 'ArcanistHookAPI', 'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow', @@ -338,6 +345,7 @@ 'ArcanistTestCase' => 'ArcanistPhutilTestCase', 'ArcanistTextLinter' => 'ArcanistLinter', 'ArcanistTextLinterTestCase' => 'ArcanistArcanistLinterTestCase', + 'ArcanistTimeWorkflow' => 'ArcanistPhrequentWorkflow', 'ArcanistTodoWorkflow' => 'ArcanistBaseWorkflow', 'ArcanistUncommittedChangesException' => 'ArcanistUsageException', 'ArcanistUnitConsoleRenderer' => 'ArcanistUnitRenderer', diff --git a/src/workflow/ArcanistPhrequentWorkflow.php b/src/workflow/ArcanistPhrequentWorkflow.php new file mode 100644 --- /dev/null +++ b/src/workflow/ArcanistPhrequentWorkflow.php @@ -0,0 +1,76 @@ +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; + } + +} diff --git a/src/workflow/ArcanistStartWorkflow.php b/src/workflow/ArcanistStartWorkflow.php new file mode 100644 --- /dev/null +++ b/src/workflow/ArcanistStartWorkflow.php @@ -0,0 +1,92 @@ + '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); + } + +} diff --git a/src/workflow/ArcanistStopWorkflow.php b/src/workflow/ArcanistStopWorkflow.php new file mode 100644 --- /dev/null +++ b/src/workflow/ArcanistStopWorkflow.php @@ -0,0 +1,132 @@ + 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); + } + +} diff --git a/src/workflow/ArcanistTimeWorkflow.php b/src/workflow/ArcanistTimeWorkflow.php new file mode 100644 --- /dev/null +++ b/src/workflow/ArcanistTimeWorkflow.php @@ -0,0 +1,47 @@ +printCurrentTracking(); + } + +}