in prs/handler/impl/src/org/netbeans/modules/jackpot/prs/handler/impl/HandlePullRequest.java [96:280]
public static void processPullRequest(String inputData, String oauthToken, String oauthAppToken) throws Exception {
File tempDir = Places.getCacheSubdirectory("checkout");
Map<String, Object> inputParsed = new ObjectMapper().readValue(inputData, Map.class);
Object action = inputParsed.get("action");
if (!"opened".equals(action))
return ;
Map<String, Object> pullRequest = (Map<String, Object>) inputParsed.get("pull_request");
if (pullRequest == null) {
return ;
}
Map<String, Object> base = (Map<String, Object>) pullRequest.get("base");
Map<String, Object> baseRepo = (Map<String, Object>) base.get("repo");
Map<String, Object> head = (Map<String, Object>) pullRequest.get("head");
Map<String, Object> headRepo = (Map<String, Object>) head.get("repo");
SiteWrapper statusGithub = factory.create(oauthToken);
String fullRepoName = (String) baseRepo.get("full_name");
String sha = (String) head.get("sha");
statusGithub.createCommitStatusPending(fullRepoName, sha, "Running Jackpot verification");
String cloneURL = (String) headRepo.get("clone_url");
new ProcessBuilder("git", "clone", cloneURL, "workdir").directory(tempDir).inheritIO().start().waitFor();
FileObject workdir = FileUtil.toFileObject(new File(tempDir, "workdir"));
new ProcessBuilder("git", "checkout", sha).directory(FileUtil.toFile(workdir)).inheritIO().start().waitFor();
FileObject jlObject = workdir.getFileObject("src/java.base/share/classes/java/lang/Object.java");
if (jlObject != null) {
Project prj = FileOwnerQuery.getOwner(jlObject); //ensure external roots (tests) are registered
ProjectUtils.getSources(prj).getSourceGroups(Sources.TYPE_GENERIC); //register external roots
}
FileObject jlmSourceVersion = workdir.getFileObject("src/java.compiler/share/classes/javax/lang/model/SourceVersion.java");
if (jlmSourceVersion != null) {
Project prj = FileOwnerQuery.getOwner(jlmSourceVersion); //ensure external roots (tests) are registered
ProjectUtils.getSources(prj).getSourceGroups(Sources.TYPE_GENERIC); //register external roots
}
Set<Project> projects = new HashSet<>();
Map<FileObject, FileData> file2Remap = new HashMap<>();
String diffURL = (String) pullRequest.get("diff_url");
URLConnection conn = new URL(diffURL).openConnection();
String text;
try (InputStream in = conn.getInputStream()) {
String encoding = conn.getContentEncoding();
if (encoding == null) encoding = "UTF-8";
//workaround for the diff parser, which does not handle git diffs properly:
text = new String(in.readAllBytes(), encoding)
.replace("\ndiff --git", "\n\ndiff --git");
}
List<Diff> diffs = new UnifiedDiffParser().parse(text.getBytes());
for (Diff diff : diffs) {
String filename = diff.getToFileName().substring(2);
if (filename.endsWith(".java")) {
FileObject file = workdir.getFileObject(filename);
if (file == null) {
//TODO: how to handle? log?
continue;
}
Project project = FileOwnerQuery.getOwner(file);
if (project != null) {
int[] remap = new int[file.asLines().size() + 1]; //TODO: encoding?
Arrays.fill(remap, -1);
int idx = 1;
for (Hunk hunk : diff.getHunks()) {
int pointer = hunk.getToFileRange().getLineStart();
for (Line line : hunk.getLines()) {
switch (line.getLineType()) {
case NEUTRAL: pointer++; idx++; break;
case TO: remap[pointer++] = idx++; break;
}
}
}
projects.add(project);
file2Remap.put(file, new FileData(filename, remap));
} else {
System.err.println("no project found for: " + filename);
}
}
}
int prId = (int) pullRequest.get("number");
SiteWrapper[] commentGitHub = new SiteWrapper[1];
boolean[] hasWarnings = {false};
for (Project project : projects) {
switch (project.getClass().getName()) {//XXX: ensure that the environment variables are dropped here!
case "org.netbeans.modules.maven.NbMavenProjectImpl":
new ProcessBuilder("mvn", "dependency:go-offline").directory(FileUtil.toFile(project.getProjectDirectory())).inheritIO().start().waitFor();
break;
case "org.netbeans.modules.apisupport.project.NbModuleProject":
FileObject nbbuild = project.getProjectDirectory().getFileObject("../../nbbuild");
if (nbbuild == null) {
nbbuild = project.getProjectDirectory().getFileObject("../nbbuild");
}
if (nbbuild != null) { //TODO: only once
new ProcessBuilder("ant", "-autoproxy", "download-all-extbins").directory(FileUtil.toFile(nbbuild)).inheritIO().start().waitFor();
}
//TODO: download extbins!
break;
case "org.netbeans.modules.java.openjdk.project.JDKProject":
//no bootstrap at this time
break;
default:
System.err.println("project name: " + project.getClass().getName());
break;
}
}
OpenProjects.getDefault().open(projects.toArray(new Project[0]), false);
Map<ClasspathInfo, Collection<FileObject>> sorted = BatchUtilities.sortFiles(file2Remap.keySet());
for (Entry<ClasspathInfo, Collection<FileObject>> e : sorted.entrySet()) {
System.err.println("Running hints for:");
System.err.println("files: " + e.getValue());
System.err.println("classpath: " + e.getKey());
try {
JavaSource.create(e.getKey(), e.getValue()).runWhenScanFinished(cc -> {
FileData fileData = file2Remap.get(cc.getFileObject());
if (fileData == null)
return ;
cc.toPhase(JavaSource.Phase.RESOLVED); //XXX
List<ErrorDescription> warnings = new HintsInvoker(HintsSettings.getGlobalSettings(), new AtomicBoolean()).computeHints(cc);
System.err.println("warnings=" + warnings);
for (ErrorDescription ed : warnings) {
int startLine = ed.getRange().getBegin().getLine() + 1;
int targetPosition = fileData.remap[startLine];
if (targetPosition == (-1))
continue;
String comment = "Jackpot:\nwarning: " + ed.getDescription();
//TODO: fixes
// if (additions != null) {
// comment += "```suggestion\n" + additions.toString() + "```";
// }
hasWarnings[0] = true;
if (commentGitHub[0] == null) {
commentGitHub[0] = factory.create(oauthAppToken);
}
commentGitHub[0].createReviewComment(fullRepoName, prId, comment, sha, fileData.filename, targetPosition);
}
}, false).get();
} catch (Throwable ex) {
System.err.println("error while processing: " + e.getValue());
Exceptions.printStackTrace(ex);
}
}
// String file = (String) m.get("file");
// int startLine = (Integer) m.get("startLine");
// List<String> fixes = (List<String>) m.get("fixes");
// StringBuilder additions = null;
// if (fixes != null && fixes.size() > 1) { //TODO: or == 1?
// List<Diff> fixDiffs = new UnifiedDiffParser().parse(fixes.get(0).getBytes("UTF-8"));
// if (fixDiffs.size() == 1 && fixDiffs.get(0).getHunks().size() == 1) {
// int start = fixDiffs.get(0).getHunks().get(0).getToFileRange().getLineStart();
// additions = new StringBuilder();
// boolean seenRemoval = false;
// for (Line line : fixDiffs.get(0).getHunks().get(0).getLines()) {
// if (line.getLineType() == Line.LineType.FROM) {
// if (seenRemoval) {
// start = -1;
// break;
// } else {
// seenRemoval = true;
// }
// } else if (line.getLineType() == Line.LineType.TO) {
// additions.append(line.getContent());
// additions.append("\n");
// }
// }
// if (start != (-1) && seenRemoval) {
// startLine = start;
// } else {
// additions = null;
// }
// }
// }
// }
// }
//
String mainComment;
if (!hasWarnings[0]) {
mainComment = "Jackpot: no warnings.";
} else {
mainComment = "Jackpot: warnings found.";
}
//TODO: set status on crash/error!
statusGithub.createCommitStatusSuccess(fullRepoName, sha, mainComment);
}