Java tutorial
/* * Sonar PullRequest Report (Maven plugin) * Copyright (C) 2010 klicap - ingenieria del puzle * dev@sonar.codehaus.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ package com.marvinformatics.sonarpullrequestintegration.mojo; import java.io.IOException; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.eclipse.egit.github.core.CommitComment; import org.eclipse.egit.github.core.CommitFile; import org.eclipse.egit.github.core.Repository; import org.eclipse.egit.github.core.RepositoryCommit; import org.eclipse.egit.github.core.client.GitHubClient; import org.eclipse.egit.github.core.service.PullRequestService; import org.eclipse.egit.github.core.service.RepositoryService; import org.sonar.wsclient.internal.HttpRequestFactory; import org.sonar.wsclient.issue.Issue; import org.sonar.wsclient.issue.IssueClient; import org.sonar.wsclient.issue.IssueQuery; import org.sonar.wsclient.issue.Issues; import org.sonar.wsclient.issue.internal.DefaultIssueClient; import org.sonar.wsclient.services.Violation; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; /** * Generate a PullRequest report. WARNING, Sonar server must be started. * * @goal publish * @aggregator */ public class SonarPullRequestMojo extends AbstractMojo { /** * Maven project info. * * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * Sonar Base URL. * * @parameter expression="${sonar.host.url}" * default-value="http://localhost:9000/" * @optional */ private String sonarHostUrl; /** * Branch to be used. * * @parameter expression="${sonar.branch}" * @optional */ private String sonarBranch; /** * Username to access WS API. * * @parameter expression="${sonar.ws.username}" * @optional */ private String username; /** * Password to access WS API. * * @parameter expression="${sonar.ws.password}" * @optional */ private String password; /** * Set OAuth2 token * * @parameter expression="${github.oauth2}" */ private String oauth2 = "7f7f79ecbaa0f2a6521bab44af799155c80d54d5"; /** * Github pull request ID * * @parameter expression="${github.pullRequestId}" */ private int pullRequestId = 1; /** * Github repository owner * * @parameter expression="${github.repositoryOwner}" */ private String repositoryOwner = "velo"; /** * Github repository name * * @parameter expression="${github.repositoryName}" */ private String repositoryName = "querydsl"; public void execute() throws MojoExecutionException { List<Issue> issues; try { issues = getIssues(); } catch (Exception e) { throw new MojoExecutionException("Unable to get sonar project", e); } Multimap<String, Issue> fileViolations = LinkedHashMultimap.create(); for (Issue issue : issues) { String fileName = issue.componentKey(); fileName = fileName.substring(fileName.lastIndexOf(':') + 1); fileName = fileName.replace('.', '/'); fileName = fileName + ".java"; fileViolations.put(fileName, issue); } try { recordGit(fileViolations); } catch (IOException e) { throw new MojoExecutionException("Unable to comment on github", e); } } private void recordGit(Multimap<String, Issue> fileViolations) throws IOException { GitHubClient client = new GitHubClient().setOAuth2Token(oauth2); RepositoryService rs = new RepositoryService(client); Repository repository = rs.getRepository(repositoryOwner, repositoryName); PullRequestService pullRequestService = new PullRequestService(client); Iterator<RepositoryCommit> commits = pullRequestService.getCommits(repository, pullRequestId).iterator(); if (!commits.hasNext()) return; RepositoryCommit lastCommit = commits.next(); List<CommitFile> files = pullRequestService.getFiles(repository, pullRequestId); Multimap<String, Issue> relatedFileViolations = LinkedHashMultimap.create(); Map<String, LinePositioner> linePositioners = Maps.newLinkedHashMap(); for (CommitFile commitFile : files) { Set<String> keys = fileViolations.keySet(); for (String key : keys) { if (commitFile.getFilename().contains(key)) { relatedFileViolations.putAll(commitFile.getFilename(), fileViolations.get(key)); linePositioners.put(commitFile.getFilename(), new LinePositioner(commitFile.getPatch())); } } } List<CommitComment> currentComments = pullRequestService.getComments(repository, pullRequestId); for (CommitComment comment : currentComments) { Iterator<Issue> issues = relatedFileViolations.get(comment.getPath()).iterator(); while (issues.hasNext()) { Issue issue = (Issue) issues.next(); int position = linePositioners.get(comment.getPath()).toPostion(issue.line()); if (position == comment.getPosition() && issue.message().equals(comment.getBody())) issues.remove(); } } Collection<Entry<String, Issue>> entries = relatedFileViolations.entries(); for (Entry<String, Issue> entry : entries) { CommitComment comment = new CommitComment(); comment.setBody(entry.getValue().message()); comment.setCommitId(lastCommit.getSha()); comment.setPath(entry.getKey()); int line = entry.getValue().line(); comment.setLine(line); comment.setPosition(linePositioners.get(entry.getKey()).toPostion(line)); pullRequestService.createComment(repository, pullRequestId, comment); } } private List<Issue> getIssues() throws IOException { if (sonarHostUrl != null) { if (sonarHostUrl.endsWith("/")) { sonarHostUrl = sonarHostUrl.substring(0, sonarHostUrl.length() - 1); } } String sonarProjectId = project.getGroupId() + ":" + project.getArtifactId(); if (sonarBranch != null) { sonarProjectId += ":" + sonarBranch; getLog().info("Branch " + sonarBranch + " selected"); } HttpRequestFactory requestFactory = new HttpRequestFactory(sonarHostUrl).setLogin(username) .setPassword(password); IssueClient client = new DefaultIssueClient(requestFactory); Issues result = client.find(IssueQuery.create().componentRoots(sonarProjectId)); List<Issue> issues = result.list(); return issues; } }