public function run($arguments, CLImaxController $cliController) { // Set up options for search $config = GitPlanbox_Config::get(); $statuses = array('completed', 'delivered', 'accepted'); $opts = array('productid' => $config->productid(), 'timeframe' => $timeframe, 'status' => $statuses); // Pull in timeframe(s) if they've been specified if (isset($arguments[0])) { $opts['timeframe'] = explode(',', $arguments[0]); } else { $opts['timeframe'] = array('last', 'current', 'next'); } // Create a session so we can run commands $session = GitPlanbox_Session::create(); // Get a list of stories $stories = GitPlanbox_Search::search($session, $opts); if (count($stories) == 0) { print "There are no stories in status: " . implode(', ', $statuses) . ".\n"; return 0; } // Format stories nicely print "Stories that are ready for release:\n"; foreach ($stories as $story) { printf("%8s %10s - %-50s\n", "#{$story->id}", $story->status, $story->name); } print "\nHint: use `git-planbox status <storyId>` to find out what branch the story is on.\n\n"; return 0; }
public function run($arguments, CLImaxController $cliController) { // First try the storyId specified on the command line $storyId = NULL; if (isset($arguments[0])) { $storyId = ltrim($arguments[0], "# "); } // If no storyId was specified on the command line, try to // parse it out of the current branch name if (!$storyId) { $storyId = GitPlanbox_Util::currentStoryId(); } // If we still don't have a story id, tell the user to please // specify one if (!$storyId) { throw new Exception("Couldn't auto-detect a story_id, please specify one like so: git planbox start 12345"); } // Get the story from Planbox $session = GitPlanbox_Session::create(); try { $story = $session->post('get_story', array('story_id' => $storyId)); } catch (GitPlanbox_ApplicationErrorException $e) { throw new Exception("Unable to fetch story {$storyId} from Planbox."); } // Switch branches $this->_switchBranches($story); // Update timers $this->_stopRunningTimers($session); $this->_startTimer($session, $story); // Success! return 0; }
public function run($arguments, CLImaxController $cliController) { // Look for a story id on the command line $storyId = NULL; if (isset($arguments[0])) { $storyId = ltrim($arguments[0], "# "); } // Look for the story id in the current git branch name if (!$storyId) { $storyId = GitPlanbox_Util::currentStoryId(); } // Require a storyId to move forward if (!$storyId) { throw new Exception("I was unable to auto-detect which story id you would like to pause, please specify it like this: 'git planbox pause 12345'"); } // Fetch the story from Planbox $session = GitPlanbox_Session::create(); try { $story = $session->post('get_story', array('story_id' => $storyId)); } catch (GitPlanbox_ApplicationErrorException $e) { throw new Exception("Unable to fetch story {$storyId} from Planbox."); } // Arrange tasks in useful ways $tasksByStatus = array(); $tasksByTaskId = array(); foreach ($story->tasks as $task) { $tasksByStatus[$task->status][] = $task; $tasksByTaskId[$task->id] = $task; } // If there are no inprogress tasks, tell the user if (!isset($tasksByStatus['inprogress']) || count($tasksByStatus['inprogress']) < 1) { print "There are no tasks currently in-progress for story {$storyId}.\n"; return 0; } // If there's only one status:inprogress task, set it to status:pending if (count($tasksByStatus['inprogress']) == 1) { $task = array_shift($tasksByStatus['inprogress']); $this->_pauseTimerForTask($session, $storyId, $task->id); return 0; } // Otherwise ask the user which task they'd like to pause (allow pausing all too!) foreach ($tasksByStatus['inprogress'] as $task) { printf("%8s %10s - %-50s\n", "#{$task->id}", $task->status, $task->name); } $taskId = GitPlanbox_Util::readline("Which task id would you like to pause? You can also say all... "); if (strtolower($taskId) === 'all') { foreach ($tasksByStatus['inprogress'] as $task) { $this->_pauseTimerForTask($session, $storyId, $task->id); } } elseif (isset($tasksByTaskId[intVal($taskId)])) { $task = $tasksByTaskId[intVal($taskId)]; $this->_pauseTimerForTask($session, $storyId, $task->id); } else { if (!$storyId) { throw new Exception("I didn't understand that story id."); } } return 0; }
public function run($arguments, CLImaxController $cliController) { // Pull in iterations if they've been specified, otherwise // use current as default $timeframe = 'current'; if (isset($arguments[0])) { $timeframe = explode(',', $arguments[0]); } // Create a session so we can run commands $session = GitPlanbox_Session::create(); // Get a list of stories $config = GitPlanbox_Config::get(); $postData = array('product_id' => $config->productid(), 'timeframe' => $timeframe); if ($config->resourceid()) { $postData['resource_id'] = array($config->resourceid()); } // Restrict list to the current user if they have specified a planbox.resourceid in gitconfig $stories = $session->post('get_stories', $postData); // Format stories nicely $skippedStoriesByStatus = array(); foreach ($stories as $story) { // Skip stories that are done $statusesToSkip = array('completed', 'delivered', 'accepted', 'rejected', 'released', 'blocked'); if (in_array($story->status, $statusesToSkip)) { if (!isset($skippedStoriesByStatus[$story->status])) { $skippedStoriesByStatus[$story->status] = 0; } $skippedStoriesByStatus[$story->status]++; continue; } printf("%8s %9s %10s - %-50s\n", "#{$story->id}", $story->type, $story->status, $story->name); } if (!empty($skippedStoriesByStatus)) { $skippedStoryStatuses = array(); foreach ($skippedStoriesByStatus as $status => $numSkipped) { array_push($skippedStoryStatuses, "{$numSkipped} {$status}"); } print "...plus " . implode(', ', $skippedStoryStatuses) . " tasks that are not displayed.\n"; } return 0; }
public function run($arguments, CLImaxController $cliController) { // First try the storyId specified on the command line $storyId = NULL; if (isset($arguments[0])) { $storyId = ltrim($arguments[0], "# "); } // If no storyId was specified on the command line, try to // parse it out of the current branch name if (!$storyId) { $storyId = GitPlanbox_Util::currentStoryId(); } // If we still don't have a story id, tell the user to please // specify one if (!$storyId) { throw new Exception("Couldn't auto-detect a story_id, please specify one like so: git planbox status 12345"); } // Get the story from Planbox $session = GitPlanbox_Session::create(); try { $story = $session->post('get_story', array('story_id' => $storyId)); } catch (GitPlanbox_ApplicationErrorException $e) { throw new Exception("Unable to fetch story {$storyId} from Planbox."); } // Find all SHAs referenced in the comments $shas = array(); foreach ($story->comments as $comment) { $commentShas = array(); preg_match_all('/[a-fA-F0-9]{40}/', $comment->text, $commentShas); if (isset($commentShas[0])) { $shas = array_merge($shas, $commentShas[0]); } } $shas = array_unique($shas); // Run `git branch --contains {$sha}` on each sha to see where it's been merged to $infos = array(); foreach ($shas as $sha) { $info = array('sha' => $sha); // Get the commit message for this sha $command = "git log -1 --pretty=oneline --abbrev-commit {$sha} 2>&1"; $output = ''; exec($command, $output, $returnCode); $commitMessage = array_shift($output); $info['message'] = $commitMessage; // Find out which git branches contain this sha $command = "git branch -a --contains {$sha} 2>&1"; $output = ''; exec($command, $output, $returnCode); if ($returnCode === 0) { $branches = array(); $branchesText = trim(preg_replace('/\\s+/', ' ', str_replace('*', '', implode("\n", $output)))); if ($branchesText) { $branches = explode("\n", $branchesText); } $info['branches'] = $branches; } else { $info['branches'] = array(); } array_push($infos, $info); } // Pretty print the story status and the branches it's merged to print "Story #{$storyId} is currently: {$story->status}\n"; if (count($infos) > 0) { print "Commits:\n"; } foreach ($infos as $info) { if (isset($info['branches']) && $info['branches']) { print " \"{$info['message']}\" is on branches: " . implode(', ', $info['branches']) . "\n"; } else { print " \"{$info['message']}\" is not on any branches.\n"; } } // Success! return 0; }
public function run($arguments, CLImaxController $cliController) { // If we have an argument, show the story with _that_ id $storyId = NULL; if (isset($arguments[0])) { $storyId = ltrim($arguments[0], "# "); } // Otherwise try to figure out what story we're working on // based on the current branch name if (!$storyId) { $currentBranchName = GitPlanbox_Util::currentGitBranchName(); // Try to parse out a story id preg_match("/[0-9]{5,8}/", $currentBranchName, $matches); if ($matches) { $storyId = array_pop($matches); } } // If we STILL don't know what story to show, throw a usage exception if (!$storyId) { throw new Exception("Please specify a story_id to show."); } // Fetch the story $session = GitPlanbox_Session::create(); try { $story = $session->post('get_story', array('story_id' => $storyId)); } catch (GitPlanbox_ApplicationErrorException $e) { throw new Exception("Unable to fetch story {$storyId} from Planbox."); } // Lines for all stories $storyText = ''; $lineFormat = "%-10s %s\n"; $storyLines = array('Story' => "#{$story->id}", 'Name' => $story->name, 'Type' => $story->type, 'Status' => $story->status, 'Created' => GitPlanbox_Util::timeAgo($story->created_on)); foreach ($storyLines as $key => $value) { $storyText .= sprintf($lineFormat, "{$key}:", $value); } // Optional fields $optionalLines = array(); if ($story->completed_on) { $optionalLines['Completed'] = GitPlanbox_Util::timeAgo($story->completed_on); } foreach ($optionalLines as $key => $value) { $storyText .= sprintf($lineFormat, "{$key}:", $value); } if ($story->description) { $storyText .= "\nDescription:\n {$story->description}\n"; } if ($story->tasks) { $storyText .= "\nTasks:\n"; foreach ($story->tasks as $task) { $storyText .= sprintf(" #%-10s %-10s %1.1f/%1.1f hours %-30s\n", $task->id, $task->status, $task->duration, $task->estimate, $task->name); } } if ($story->comments) { $storyText .= "\nComments:\n"; foreach ($story->comments as $comment) { $storyText .= " " . GitPlanbox_Util::timeAgo($comment->date) . "\n {$comment->text}\n\n"; } } print $storyText; return 0; }