Hyperlink to external bug tracking system


#1

Perhaps Phacility don’t use this much internally, but as you know Phabricator offers a nice facility to use a regular expression to transform an external bug reference given in plain text into a hyper link

https://secure.phabricator.com/T4027

Its controlled by the following config options

image

As the T4027 is clear, this is only in the Diffusion commit message

For our installation the “Differential” is king, in fact some users are using only Differential and not Diffusion (because their source code is in legacy VCS system not supported by Phabricator)

For those people they see only the external reference as plain text in the reviews.

This frustrated me, so (I’m sure I’ve done this in completely the wrong way/location but it seems to work for me), I added the following into:

phabricator/src/applications/differential/customfield/DifferentialSummaryField.php

Pulling the linBugtraq directly from DiffusionCommitController.php

 private function linkBugtraq($corpus) {
        $url = PhabricatorEnv::getEnvConfig('bugtraq.url');
        if (!strlen($url)) {
          return $corpus;
        }

        $regexes = PhabricatorEnv::getEnvConfig('bugtraq.logregex');
        if (!$regexes) {
          return $corpus;
        }

        $parser = id(new PhutilBugtraqParser())
          ->setBugtraqPattern("[[ {$url} | %BUGID% ]]")
          ->setBugtraqCaptureExpression(array_shift($regexes));

        $select = array_shift($regexes);
        if ($select) {
          $parser->setBugtraqSelectExpression($select);
        }

        return $parser->processCorpus($corpus);
      }

Then modifying this readValueFromRevision in DifferentialSummaryField.php to simply modify the summary

using $message = $this->linkBugtraq($message);

  protected function readValueFromRevision(
    DifferentialRevision $revision) {
    if (!$revision->getID()) {
      return null;
    }
    $message = $revision->getSummary();
    $message = $this->linkBugtraq($message);
    return $message;
  }

This seems to have the desired effect of making the external reference a hyperlink in the reviews too.

It would be nice to see the bugtraq.logregex to be supported elsewhere (like other Details sections, remarkup) e.g. Maniphest (even maniphest Titles)

I guess it really comes to being able to build a connected system (including legacy components) which can support external links (more than just one system) and can be seen as almost first class citizens of Phabricator just like the internal T/D/PHI tags etc.

e.g.

image


#2

A more general way to do this in all remarkup fields is to make this a custom remarkup extension.

<?php

final class RemarkupBugtraqLinkRule extends PhabricatorRemarkupCustomInlineRule
 {

  public function getPriority() {
    return 200.0;
  }

  public function apply($corpus) {
     // Same content as the linkBugtraq function above
  }
}

but beware syntax clashes with other Remarkup rules (you may need to fiddle around with priorities to make it work as expected).

Creating a file with the above class definition in src/extensions should be sufficient to make it available.


#3

@jsonr now that is a very good idea!


#4

You were correct about the priority, tool low and the html characters of the get escaped, too high and the markup [[]] does not get transformed into html

I guessed at 20.0 by trail and error (no real science was involved!)

added this as RemarkupBugtraqLinkRule.php in src/extensions

It seem it only updates on edit of the remarkup not on display (but that is OK for now)

Thanks @jsonr for the suggestion

<?php

final class RemarkupBugtraqLinkRule extends PhabricatorRemarkupCustomInlineRule
 {

  public function getPriority() {
    return 20.0;
  }

  public function apply($corpus) {
        $url = PhabricatorEnv::getEnvConfig('bugtraq.url');
        if (!strlen($url)) {
          return $corpus;
        }

        $regexes = PhabricatorEnv::getEnvConfig('bugtraq.logregex');
        if (!$regexes) {
          return $corpus;
        }

        $parser = id(new PhutilBugtraqParser())
          ->setBugtraqPattern("[[{$url}|%BUGID%]]")
          ->setBugtraqCaptureExpression(array_shift($regexes));

        $select = array_shift($regexes);
        if ($select) {
          $parser->setBugtraqSelectExpression($select);
        }

        return $parser->processCorpus($corpus);
  }
}

#5

Some science is a matter of brilliant theories, vut a lot is just trial and error :smiley: