public function getJiraIssuesForAttachment()

in src/uber/UberTask.php [123:276]


  public function getJiraIssuesForAttachment($message) {
    while (true) {
      $this->console->writeOut(pht('Fetching issues from jira, patience please.')."\n");
      $issues = array();
      try {
        $issues = $this->getIssues();
      } catch (Exception $e) {
        $this->console->writeOut(
          pht("Something is wrong with jira, skipping...\n\n"));
        return array();
      } catch (Throwable $e) {
        $this->console->writeOut(
          pht("Something is wrong with jira, skipping...\n\n"));
        return array();
      }
      $for_search = array();

      list($tasks, $projects) = UberTask::getTasksAndProjects($issues);
      // add tasks to search list
      foreach ($tasks as $task) {
        $for_search[] = sprintf(self::TASK_MSG, $task['key'], $task['summary']);
      }
      // add refresh message
      $for_search[] = self::REFRESH_MSG;
      // need for way out in case user doesn't try using ESC/Ctrl+c/Ctrl+d
      $for_search[] = self::SKIP_MSG;
      // general jira task creation
      $for_search[] = self::CREATE_MSG;
      // sort projects by number of tasks
      uasort($projects,
        function ($v1, $v2) {
          return $v2['tasks'] - $v1['tasks'];
      });
      // attach create task in project XXX to the list
      foreach ($projects as $project => $v) {
        $for_search[] = sprintf(self::CREATE_IN_PROJ_MSG, $project);
      }

      // prompt user to choose from menu
      $fzf = id(new UberFZF());
      if (!$fzf->isFZFAvailable()) {
        $this->console->writeOut(
          "<bg:red>** %s **</bg>\n<bg:red>** %s **</bg>\n".
          "<bg:red>** %s **</bg> %s\n".
          "<bg:red>** %s **</bg>\n<bg:red>** %s **</bg>\n",
          pht('WARNING'),
          pht('WARNING'),
          pht('WARNING'),
          pht('Looks like you do not have `fzf`, please install using '.
              '`brew install fzf` or `apt-get install fzf` or `dnf install '.
              'fzf` and try again. Your productivity will improve if you '.
              "install this tool."),
          pht('WARNING'),
          pht('WARNING'));
      }
      $fzf->setMulti(50)
        ->setHeader('Select issue to attach to Differential Revision '.
                    '(use tab for multiple selection). You can skip adding '.
                    'task by pressing esc/ctrl+c/ctrl+d. If you just enter '.
                    'issue ID it will be used if it is not matching anything '.
                    'in the list.')
        ->setPrintQuery(true);
      $result = $fzf->fuzzyChoosePrompt($for_search);
      if (empty($result)) {
        // nothing was chosen (ctrl+d, ctrl+c)
        return;
      }

      // first item is query which was entered (if any)
      $query = $result[0];
      $result = array_slice($result, 1);
      $issues = array();
      foreach ($result as $line) {
        // restart whole outer loop
        if (trim($line) == self::REFRESH_MSG) {
          continue 2;
        }
        if (trim($line) == self::SKIP_MSG) {
          return;
        }
        if (trim($line) == self::CREATE_MSG) {
          $this->openURIsInBrowser(array(UberTask::JIRA_CREATE_URL));
          if (phutil_console_confirm('Do you want to refresh task list?',
                                     $default_no = false)) {
            continue 2;
          }
          return;
        }
        // fetch chosen tasks
        list($issue) = sscanf($line, self::TASK_MSG);
        if ($issue) {
          $issues[] = $issue;
        }
        // fetch projects where user want to create task
        list($project) = sscanf($line, self::CREATE_IN_PROJ_MSG);
        if ($project) {
          $title = self::AUTOGENERATED.' '.$message->getFieldValue('title');
          $description = $message->getFieldValue('summary');
          $content = sprintf(
            $this->getTaskTemplate(), $title, $description, $project);
          while (true) {
            // todo use preffered editor if necessary
            $editor = $this->newInteractiveEditor($content);
            $content = $editor->setName('new-task')->editInteractively();
            $parsed = UberJiraIssueMessageParser::parse($content);
            $title = $parsed['title'];
            $description = $parsed['description'];
            if (strpos($title, self::AUTOGENERATED) !== false) {
              $this->console->writeOut("JIRA issue has errors:\n");
              $this->console->writeOut("    - You didn't remove autogenerated ".
                "lines, please remove them!\n");
              $this->console->writeOut('You must resolve these errors to '.
                'create issue.');
              if (!phutil_console_confirm('Do you want to edit the issue?')) {
                break;
              }
              $content = sprintf(
                $this->getTaskTemplate(), $title, $description, $project);
              $content .= "# Resolve these errors:\n";
              $content .= "#  - You didn't remove autogenerated lines, ".
                'please remove them!';
              continue;
            }
            $project_id = $projects[$project]['id'];
            $jira_issue = $this
              ->getConduit()
              ->callMethodSynchronous('uber_jira.create_issue',
                array(
                  'project_id' => $project_id,
                  'issue_type' => self::ISSUE_TYPE,
                  'title' => $title,
                  'description' => $description,
                ));
            $issues[] = $jira_issue['key'];
            $issue_url = sprintf(self::ISSUE_URL, $jira_issue['key']);
            $this->console
              ->writeOut(pht("Jira issue %s created\n", $issue_url));
            $this->openURIsInBrowser(array($issue_url));
            break;
          }
        }
      }
      if (!empty($issues)) {
        return $issues;
      } else {
        $matches = array();
        if (preg_match_all('/([A-Z][A-Z0-9]*-[1-9]\d*)/',
          $query,
          $matches) !== 0) {
          return idx($matches, 0);
        }
      }
    }
  }