package com.coravy.hudson.plugins.github; import hudson.Extension; import hudson.MarkupText; import hudson.MarkupText.SubText; import hudson.model.AbstractBuild; import hudson.plugins.git.GitChangeSet; import hudson.scm.ChangeLogAnnotator; import hudson.scm.ChangeLogSet.Entry; import java.util.regex.Pattern; /** * This class annotates changelog links. * <p> * It's based on the TracLinkAnnotator. * <p> * * @todo Change the annotator to use GithubUrl instead of the String url. * Knowledge about the github url structure should be encapsulated in * GithubUrl. * @author Stefan Saasen <stefan@coravy.com> */ @Extension public class GithubLinkAnnotator extends ChangeLogAnnotator { @Override public void annotate(AbstractBuild<?, ?> build, Entry change, MarkupText text) { final GithubProjectProperty p = build.getProject().getProperty( GithubProjectProperty.class); if (null == p || null == p.getProjectUrl()) { return; } annotate(p.getProjectUrl(), text, change); } void annotate(final GithubUrl url, final MarkupText text, final Entry change) { final String base = url.baseUrl(); for (LinkMarkup markup : MARKUPS) { markup.process(text, base); } if(change instanceof GitChangeSet) { GitChangeSet cs = (GitChangeSet)change; text.wrapBy("", " (<a href='"+url.commitId(cs.getId())+"'>commit: "+cs.getId()+"</a>)"); } } private static final class LinkMarkup { private final Pattern pattern; private final String href; LinkMarkup(String pattern, String href) { // \\\\d becomes \\d when in the expanded text. pattern = NUM_PATTERN.matcher(pattern).replaceAll("(\\\\d+)"); pattern = ANYWORD_PATTERN.matcher(pattern).replaceAll( "((?:\\\\w|[._-])+)"); this.pattern = Pattern.compile(pattern); this.href = href; } void process(MarkupText text, String url) { for (SubText st : text.findTokens(pattern)) { st.surroundWith("<a href='" + url + href + "'>", "</a>"); } } private static final Pattern NUM_PATTERN = Pattern.compile("NUM"); private static final Pattern ANYWORD_PATTERN = Pattern .compile("ANYWORD"); } private static final LinkMarkup[] MARKUPS = new LinkMarkup[] { new LinkMarkup( "(?:C|c)lose(?:s?)\\s(?<!\\:)(?:#)NUM", // "Closes #123" "issues/$1/find") }; }