Skip to content
Permalink
Browse files
Initial version of issue updater
Reviewed-by: ehelin
  • Loading branch information
rwestberg committed Nov 27, 2019
1 parent 5c3f278 commit f3afc994aa1d3baf3033bf6ad45a99bec9d33a84
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.skara.bots.notify;

import org.openjdk.skara.forge.HostedRepository;
import org.openjdk.skara.vcs.*;

import java.io.*;
import java.time.format.DateTimeFormatter;

class CommitFormatters {
static String toTextBrief(HostedRepository repository, Commit commit) {
var writer = new StringWriter();
var printer = new PrintWriter(writer);

printer.println("Changeset: " + commit.hash().abbreviate());
printer.println("Author: " + commit.author().name() + " <" + commit.author().email() + ">");
if (!commit.author().equals(commit.committer())) {
printer.println("Committer: " + commit.committer().name() + " <" + commit.committer().email() + ">");
}
printer.println("Date: " + commit.date().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss +0000")));
printer.println("URL: " + repository.webUrl(commit.hash()));

return writer.toString();
}

private static String patchToText(Patch patch) {
if (patch.status().isAdded()) {
return "+ " + patch.target().path().orElseThrow();
} else if (patch.status().isDeleted()) {
return "- " + patch.source().path().orElseThrow();
} else if (patch.status().isModified()) {
return "! " + patch.target().path().orElseThrow();
} else {
return "= " + patch.target().path().orElseThrow();
}
}

static String toText(HostedRepository repository, Commit commit) {
var writer = new StringWriter();
var printer = new PrintWriter(writer);

printer.print(toTextBrief(repository, commit));
printer.println();
printer.println(String.join("\n", commit.message()));
printer.println();

for (var diff : commit.parentDiffs()) {
for (var patch : diff.patches()) {
printer.println(patchToText(patch));
}
}

return writer.toString();
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.skara.bots.notify;

import org.openjdk.skara.forge.HostedRepository;
import org.openjdk.skara.issuetracker.Issue;
import org.openjdk.skara.issuetracker.IssueProject;
import org.openjdk.skara.vcs.*;
import org.openjdk.skara.vcs.openjdk.*;

import java.util.List;
import java.util.logging.Logger;

public class IssueUpdater implements UpdateConsumer {
private final IssueProject issueProject;
private final Logger log = Logger.getLogger("org.openjdk.skara.bots.notify");

IssueUpdater(IssueProject issueProject) {
this.issueProject = issueProject;
}

@Override
public void handleCommits(HostedRepository repository, List<Commit> commits, Branch branch) {
for (var commit : commits) {
var commitNotification = CommitFormatters.toTextBrief(repository, commit);
var commitMessage = CommitMessageParsers.v1.parse(commit);
for (var commitIssue : commitMessage.issues()) {
var issue = issueProject.issue(commitIssue.id());
if (issue.isEmpty()) {
log.severe("Cannot update issue " + commitIssue.id() + " with commit " + commit.hash().abbreviate()
+ " - issue not found in issue project");
continue;
}
issue.get().addComment(commitNotification);
issue.get().setState(Issue.State.CLOSED);
}
}
}

@Override
public void handleOpenJDKTagCommits(HostedRepository repository, List<Commit> commits, OpenJDKTag tag, Tag.Annotated annotated) {

}

@Override
public void handleTagCommit(HostedRepository repository, Commit commit, Tag tag, Tag.Annotated annotation) {

}

@Override
public void handleNewBranch(HostedRepository repository, List<Commit> commits, Branch parent, Branch branch) {

}
}
@@ -111,6 +111,10 @@ public List<Bot> create(BotConfiguration configuration) {
includeBranchNames, mode, headers, allowedDomains));
}
}
if (repo.value().contains("issues")) {
var issueProject = configuration.issueProject(repo.value().get("issues").asString());
updaters.add(new IssueUpdater(issueProject));
}

if (updaters.isEmpty()) {
log.warning("No consumers configured for notify bot repository: " + repoName);
@@ -65,51 +65,6 @@ enum Mode {
this.allowedAuthorDomains = allowedAuthorDomains;
}

private String patchToText(Patch patch) {
if (patch.status().isAdded()) {
return "+ " + patch.target().path().orElseThrow();
} else if (patch.status().isDeleted()) {
return "- " + patch.source().path().orElseThrow();
} else if (patch.status().isModified()) {
return "! " + patch.target().path().orElseThrow();
} else {
return "= " + patch.target().path().orElseThrow();
}
}

private String commitToTextBrief(HostedRepository repository, Commit commit) {
var writer = new StringWriter();
var printer = new PrintWriter(writer);

printer.println("Changeset: " + commit.hash().abbreviate());
printer.println("Author: " + commit.author().name() + " <" + commit.author().email() + ">");
if (!commit.author().equals(commit.committer())) {
printer.println("Committer: " + commit.committer().name() + " <" + commit.committer().email() + ">");
}
printer.println("Date: " + commit.date().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss +0000")));
printer.println("URL: " + repository.webUrl(commit.hash()));

return writer.toString();
}

private String commitToText(HostedRepository repository, Commit commit) {
var writer = new StringWriter();
var printer = new PrintWriter(writer);

printer.print(commitToTextBrief(repository, commit));
printer.println();
printer.println(String.join("\n", commit.message()));
printer.println();

for (var diff : commit.parentDiffs()) {
for (var patch : diff.patches()) {
printer.println(patchToText(patch));
}
}

return writer.toString();
}

private String tagAnnotationToText(HostedRepository repository, Tag.Annotated annotation) {
var writer = new StringWriter();
var printer = new PrintWriter(writer);
@@ -201,7 +156,7 @@ private List<Commit> filterAndSendPrCommits(HostedRepository repository, List<Co
}
var rfr = rfrCandidates.get(0);

var body = commitToText(repository, commit);
var body = CommitFormatters.toText(repository, commit);
var email = Email.reply(rfr, "Re: [Integrated] " + rfr.subject(), body)
.sender(sender)
.author(commitToAuthor(commit))
@@ -223,7 +178,7 @@ private void sendCombinedCommits(HostedRepository repository, List<Commit> commi
var printer = new PrintWriter(writer);

for (var commit : commits) {
printer.println(commitToText(repository, commit));
printer.println(CommitFormatters.toText(repository, commit));
}

var subject = commitsToSubject(repository, commits, branch);
@@ -266,7 +221,7 @@ public void handleOpenJDKTagCommits(HostedRepository repository, List<Commit> co
if (annotation != null) {
printer.println(tagAnnotationToText(repository, annotation));
}
printer.println(commitToTextBrief(repository, taggedCommit));
printer.println(CommitFormatters.toTextBrief(repository, taggedCommit));

printer.println("The following commits are included in " + tag.tag());
printer.println("========================================================");
@@ -304,7 +259,7 @@ public void handleTagCommit(HostedRepository repository, Commit commit, Tag tag,
if (annotation != null) {
printer.println(tagAnnotationToText(repository, annotation));
}
printer.println(commitToTextBrief(repository, commit));
printer.println(CommitFormatters.toTextBrief(repository, commit));

var subject = tagToSubject(repository, commit.hash(), tag);
var email = Email.create(subject, writer.toString())
@@ -720,4 +720,42 @@ void testMailingListBranch(TestInfo testInfo) throws IOException {
assertEquals("The new branch newbranch2 is currently identical to the newbranch1 branch.", email.body());
}
}

@Test
void testIssue(TestInfo testInfo) throws IOException {
try (var credentials = new HostCredentials(testInfo);
var tempFolder = new TemporaryDirectory()) {
var repo = credentials.getHostedRepository();
var repoFolder = tempFolder.path().resolve("repo");
var localRepo = CheckableRepository.init(repoFolder, repo.repositoryType());
credentials.commitLock(localRepo);
localRepo.pushAll(repo.url());

var tagStorage = createTagStorage(repo);
var branchStorage = createBranchStorage(repo);
var storageFolder = tempFolder.path().resolve("storage");

var issueProject = credentials.getIssueProject();
var updater = new IssueUpdater(issueProject);
var notifyBot = new JNotifyBot(repo, storageFolder, Pattern.compile("master"), tagStorage, branchStorage, List.of(updater));

// Initialize history
TestBotRunner.runPeriodicItems(notifyBot);

// Create an issue and commit a fix
var issue = issueProject.createIssue("This is an issue", List.of("Indeed"));
var editHash = CheckableRepository.appendAndCommit(localRepo, "Another line", issue.id() + ": Fix that issue");
localRepo.push(editHash, repo.url(), "master");
TestBotRunner.runPeriodicItems(notifyBot);

// The changeset should be reflected in a comment
var comments = issue.comments();
assertEquals(1, comments.size());
var comment = comments.get(0);
assertTrue(comment.body().contains(editHash.abbreviate()));

// There should be no open issues
assertEquals(0, issueProject.issues().size());
}
}
}

0 comments on commit f3afc99

Please sign in to comment.