diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBot.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBot.java index 57f986c7f..5a2e786ff 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBot.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBot.java @@ -40,15 +40,17 @@ class JNotifyBot implements Bot, WorkItem { private final Logger log = Logger.getLogger("org.openjdk.skara.bots");; private final HostedRepository repository; private final Path storagePath; - private final Branch branch; + private final List branches; private final StorageBuilder tagStorageBuilder; private final StorageBuilder branchStorageBuilder; private final List updaters; - JNotifyBot(HostedRepository repository, Path storagePath, String branch, StorageBuilder tagStorageBuilder, StorageBuilder branchStorageBuilder, List updaters) { + JNotifyBot(HostedRepository repository, Path storagePath, List branches, StorageBuilder tagStorageBuilder, StorageBuilder branchStorageBuilder, List updaters) { this.repository = repository; this.storagePath = storagePath; - this.branch = new Branch(branch); + this.branches = branches.stream() + .map(Branch::new) + .collect(Collectors.toList()); this.tagStorageBuilder = tagStorageBuilder; this.branchStorageBuilder = branchStorageBuilder; this.updaters = updaters; @@ -66,9 +68,7 @@ public boolean concurrentWith(WorkItem other) { return false; } - private void handleBranch(Repository localRepo, UpdateHistory history, Branch branch) throws IOException { - var curHead = localRepo.resolve("FETCH_HEAD").orElseThrow(IOException::new); - + private void handleBranch(Repository localRepo, UpdateHistory history, Branch branch, Hash curHead) throws IOException { var lastRef = history.branchHash(branch); if (lastRef.isEmpty()) { log.warning("No previous history found for branch '" + branch + "' - resetting mark"); @@ -87,7 +87,7 @@ private void handleBranch(Repository localRepo, UpdateHistory history, Branch br Collections.reverse(newCommits); for (var updater : updaters) { - updater.handleCommits(repository, newCommits); + updater.handleCommits(repository, newCommits, branch); } } @@ -141,10 +141,14 @@ public void run(Path scratchPath) { var historyPath = scratchPath.resolve("notify").resolve("history"); try { - var localRepo = Repository.materialize(path, repository.getUrl(), branch.name(), false); + var localRepo = Repository.materialize(path, repository.getUrl(), "master", false); var history = UpdateHistory.create(tagStorageBuilder, historyPath.resolve("tags"), branchStorageBuilder, historyPath.resolve("branches")); - handleBranch(localRepo, history, branch); handleTags(localRepo, history); + + for (var branch : branches) { + var hash = localRepo.fetch(repository.getUrl(), branch.name()); + handleBranch(localRepo, history, branch, hash); + } } catch (IOException e) { throw new UncheckedIOException(e); } diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBotFactory.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBotFactory.java index d80e1e50f..dcaf851a3 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBotFactory.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JNotifyBotFactory.java @@ -24,12 +24,14 @@ import org.openjdk.skara.bot.*; import org.openjdk.skara.email.EmailAddress; +import org.openjdk.skara.json.JSONValue; import org.openjdk.skara.storage.StorageBuilder; -import org.openjdk.skara.vcs.Tag; +import org.openjdk.skara.vcs.*; import java.nio.file.Path; import java.util.*; import java.util.logging.Logger; +import java.util.stream.Collectors; public class JNotifyBotFactory implements BotFactory { private final Logger log = Logger.getLogger("org.openjdk.skara.bots");; @@ -52,7 +54,9 @@ public List create(BotConfiguration configuration) { for (var repo : specific.get("repositories").fields()) { var repoName = repo.name(); - var branch = repo.value().get("branch").asString(); + var branches = repo.value().get("branches").stream() + .map(JSONValue::asString) + .collect(Collectors.toList()); var build = repo.value().get("build").asString(); var version = repo.value().get("version").asString(); @@ -65,7 +69,7 @@ public List create(BotConfiguration configuration) { var senderName = mailcfg.get("name").asString(); var senderMail = mailcfg.get("email").asString(); var sender = EmailAddress.from(senderName, senderMail); - updaters.add(new MailingListUpdater(mailcfg.get("smtp").asString(), EmailAddress.parse(mailcfg.get("recipient").asString()), sender)); + updaters.add(new MailingListUpdater(mailcfg.get("smtp").asString(), EmailAddress.parse(mailcfg.get("recipient").asString()), sender, branches.size() > 1)); } if (updaters.isEmpty()) { @@ -77,7 +81,7 @@ public List create(BotConfiguration configuration) { .remoteRepository(databaseRepo, databaseRef, databaseName, databaseEmail, "Added tag for " + repoName); var branchStorageBuilder = new StorageBuilder(repoName + ".branches.txt") .remoteRepository(databaseRepo, databaseRef, databaseName, databaseEmail, "Added branch hash for " + repoName); - var bot = new JNotifyBot(configuration.repository(repoName), configuration.storageFolder(), branch, tagStorageBuilder, branchStorageBuilder, updaters); + var bot = new JNotifyBot(configuration.repository(repoName), configuration.storageFolder(), branches, tagStorageBuilder, branchStorageBuilder, updaters); ret.add(bot); } diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JsonUpdater.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JsonUpdater.java index 160120a5e..435d3d0da 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JsonUpdater.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/JsonUpdater.java @@ -24,7 +24,7 @@ import org.openjdk.skara.host.HostedRepository; import org.openjdk.skara.json.*; -import org.openjdk.skara.vcs.Commit; +import org.openjdk.skara.vcs.*; import org.openjdk.skara.vcs.openjdk.*; import java.nio.file.Path; @@ -76,7 +76,7 @@ private JSONObject issuesToChanges(HostedRepository repository, List issu } @Override - public void handleCommits(HostedRepository repository, List commits) { + public void handleCommits(HostedRepository repository, List commits, Branch branch) { try (var writer = new JsonUpdateWriter(path, repository.getName())) { for (var commit : commits) { var json = commitToChanges(repository, commit, defaultBuild); diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/MailingListUpdater.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/MailingListUpdater.java index 9501c56b2..0c242a45c 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/MailingListUpdater.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/MailingListUpdater.java @@ -35,11 +35,13 @@ public class MailingListUpdater implements UpdateConsumer { private final String host; private final EmailAddress recipient; private final EmailAddress sender; + private final boolean includeBranch; - MailingListUpdater(String host, EmailAddress recipient, EmailAddress sender) { + MailingListUpdater(String host, EmailAddress recipient, EmailAddress sender, boolean includeBranch) { this.host = host; this.recipient = recipient; this.sender = sender; + this.includeBranch = includeBranch; } private String patchToText(Patch patch) { @@ -78,12 +80,16 @@ private String commitToText(HostedRepository repository, Commit commit) { return writer.toString(); } - private String commitsToSubject(HostedRepository repository, List commits) { + private String commitsToSubject(HostedRepository repository, List commits, Branch branch) { var subject = new StringBuilder(); subject.append(repository.getRepositoryType().shortName()); subject.append(": "); subject.append(repository.getName()); subject.append(": "); + if (includeBranch) { + subject.append(branch.name()); + subject.append(": "); + } if (commits.size() > 1) { subject.append(commits.size()); subject.append(" new changesets"); @@ -94,11 +100,11 @@ private String commitsToSubject(HostedRepository repository, List commit } @Override - public void handleCommits(HostedRepository repository, List commits) { + public void handleCommits(HostedRepository repository, List commits, Branch branch) { var writer = new StringWriter(); var printer = new PrintWriter(writer); - var subject = commitsToSubject(repository, commits); + var subject = commitsToSubject(repository, commits, branch); for (var commit : commits) { printer.println(commitToText(repository, commit)); diff --git a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/UpdateConsumer.java b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/UpdateConsumer.java index 018b6a95f..0ba299cd4 100644 --- a/bots/notify/src/main/java/org/openjdk/skara/bots/notify/UpdateConsumer.java +++ b/bots/notify/src/main/java/org/openjdk/skara/bots/notify/UpdateConsumer.java @@ -23,12 +23,12 @@ package org.openjdk.skara.bots.notify; import org.openjdk.skara.host.HostedRepository; -import org.openjdk.skara.vcs.Commit; -import org.openjdk.skara.vcs.openjdk.*; +import org.openjdk.skara.vcs.*; +import org.openjdk.skara.vcs.openjdk.OpenJDKTag; import java.util.List; public interface UpdateConsumer { - void handleCommits(HostedRepository repository, List commits); + void handleCommits(HostedRepository repository, List commits, Branch branch); void handleTagCommits(HostedRepository repository, List commits, OpenJDKTag tag); } diff --git a/bots/notify/src/test/java/org/openjdk/skara/bots/notify/UpdaterTests.java b/bots/notify/src/test/java/org/openjdk/skara/bots/notify/UpdaterTests.java index 24e8997cd..5eb81159e 100644 --- a/bots/notify/src/test/java/org/openjdk/skara/bots/notify/UpdaterTests.java +++ b/bots/notify/src/test/java/org/openjdk/skara/bots/notify/UpdaterTests.java @@ -75,7 +75,7 @@ void testJsonUpdaterBranch(TestInfo testInfo) throws IOException { var storageFolder = tempFolder.path().resolve("storage"); var updater = new JsonUpdater(jsonFolder, "12", "team"); - var notifyBot = new JNotifyBot(repo, storageFolder, "master", tagStorage, branchStorage, List.of(updater)); + var notifyBot = new JNotifyBot(repo, storageFolder, List.of("master"), tagStorage, branchStorage, List.of(updater)); TestBotRunner.runPeriodicItems(notifyBot); assertEquals(List.of(), findJsonFiles(jsonFolder, "")); @@ -114,7 +114,7 @@ void testJsonUpdaterTag(TestInfo testInfo) throws IOException { var storageFolder =tempFolder.path().resolve("storage"); var updater = new JsonUpdater(jsonFolder, "12", "team"); - var notifyBot = new JNotifyBot(repo, storageFolder, "master", tagStorage, branchStorage, List.of(updater)); + var notifyBot = new JNotifyBot(repo, storageFolder, List.of("master"), tagStorage, branchStorage, List.of(updater)); TestBotRunner.runPeriodicItems(notifyBot); assertEquals(List.of(), findJsonFiles(jsonFolder, "")); @@ -164,8 +164,8 @@ void testMailingList(TestInfo testInfo) throws IOException { var sender = EmailAddress.from("duke", "duke@duke.duke"); var recipient = EmailAddress.from("list", "list@list.list"); - var updater = new MailingListUpdater(smtpServer.address(), recipient, sender); - var notifyBot = new JNotifyBot(repo, storageFolder, "master", tagStorage, branchStorage, List.of(updater)); + var updater = new MailingListUpdater(smtpServer.address(), recipient, sender, false); + var notifyBot = new JNotifyBot(repo, storageFolder, List.of("master"), tagStorage, branchStorage, List.of(updater)); // No mail should be sent on the first run as there is no history TestBotRunner.runPeriodicItems(notifyBot); @@ -177,6 +177,8 @@ void testMailingList(TestInfo testInfo) throws IOException { var email = smtpServer.receive(Duration.ofSeconds(10)); assertEquals(email.sender(), sender); assertEquals(email.recipients(), List.of(recipient)); + assertTrue(email.subject().contains(": 23456789: More fixes")); + assertFalse(email.subject().contains("master")); assertTrue(email.body().contains("Changeset: " + editHash.abbreviate())); assertTrue(email.body().contains("23456789: More fixes")); assertFalse(email.body().contains("Committer")); @@ -202,8 +204,8 @@ void testMailingListMultiple(TestInfo testInfo) throws IOException { var sender = EmailAddress.from("duke", "duke@duke.duke"); var recipient = EmailAddress.from("list", "list@list.list"); - var updater = new MailingListUpdater(smtpServer.address(), recipient, sender); - var notifyBot = new JNotifyBot(repo, storageFolder, "master", tagStorage, branchStorage, List.of(updater)); + var updater = new MailingListUpdater(smtpServer.address(), recipient, sender, false); + var notifyBot = new JNotifyBot(repo, storageFolder, List.of("master"), tagStorage, branchStorage, List.of(updater)); // No mail should be sent on the first run as there is no history TestBotRunner.runPeriodicItems(notifyBot); @@ -218,6 +220,8 @@ void testMailingListMultiple(TestInfo testInfo) throws IOException { var email = smtpServer.receive(Duration.ofSeconds(10)); assertEquals(email.sender(), sender); assertEquals(email.recipients(), List.of(recipient)); + assertTrue(email.subject().contains(": 2 new changesets")); + assertFalse(email.subject().contains("master")); assertTrue(email.body().contains("Changeset: " + editHash1.abbreviate())); assertTrue(email.body().contains("23456789: More fixes")); assertTrue(email.body().contains("Changeset: " + editHash2.abbreviate())); @@ -244,8 +248,8 @@ void testMailingListSponsored(TestInfo testInfo) throws IOException { var sender = EmailAddress.from("duke", "duke@duke.duke"); var recipient = EmailAddress.from("list", "list@list.list"); - var updater = new MailingListUpdater(smtpServer.address(), recipient, sender); - var notifyBot = new JNotifyBot(repo, storageFolder, "master", tagStorage, branchStorage, List.of(updater)); + var updater = new MailingListUpdater(smtpServer.address(), recipient, sender, false); + var notifyBot = new JNotifyBot(repo, storageFolder, List.of("master"), tagStorage, branchStorage, List.of(updater)); // No mail should be sent on the first run as there is no history TestBotRunner.runPeriodicItems(notifyBot); @@ -267,4 +271,64 @@ void testMailingListSponsored(TestInfo testInfo) throws IOException { } } + @Test + void testMailingListMultipleBranches(TestInfo testInfo) throws IOException { + try (var smtpServer = new SMTPServer(); + 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.getRepositoryType()); + var masterHash = localRepo.resolve("master").orElseThrow(); + credentials.commitLock(localRepo); + var branch = localRepo.branch(masterHash, "another"); + localRepo.pushAll(repo.getUrl()); + + var tagStorage = createTagStorage(repo); + var branchStorage = createBranchStorage(repo); + var storageFolder = tempFolder.path().resolve("storage"); + + var sender = EmailAddress.from("duke", "duke@duke.duke"); + var recipient = EmailAddress.from("list", "list@list.list"); + var updater = new MailingListUpdater(smtpServer.address(), recipient, sender, true); + var notifyBot = new JNotifyBot(repo, storageFolder, List.of("master", "another"), tagStorage, branchStorage, List.of(updater)); + + // No mail should be sent on the first run as there is no history + TestBotRunner.runPeriodicItems(notifyBot); + assertThrows(RuntimeException.class, () -> smtpServer.receive(Duration.ofMillis(1))); + + var editHash1 = CheckableRepository.appendAndCommit(localRepo, "Another line", "23456789: More fixes"); + localRepo.push(editHash1, repo.getUrl(), "master"); + var editHash2 = CheckableRepository.appendAndCommit(localRepo, "Yet another line", "3456789A: Even more fixes"); + localRepo.push(editHash2, repo.getUrl(), "master"); + + TestBotRunner.runPeriodicItems(notifyBot); + var email = smtpServer.receive(Duration.ofSeconds(10)); + assertEquals(email.sender(), sender); + assertEquals(email.recipients(), List.of(recipient)); + assertFalse(email.subject().contains("another")); + assertTrue(email.subject().contains(": master: 2 new changesets")); + assertTrue(email.body().contains("Changeset: " + editHash1.abbreviate())); + assertTrue(email.body().contains("23456789: More fixes")); + assertTrue(email.body().contains("Changeset: " + editHash2.abbreviate())); + assertTrue(email.body().contains("3456789A: Even more fixes")); + assertFalse(email.body().contains(masterHash.abbreviate())); + assertFalse(email.body().contains("456789AB: Yet more fixes")); + + localRepo.checkout(branch, true); + var editHash3 = CheckableRepository.appendAndCommit(localRepo, "Another branch", "456789AB: Yet more fixes"); + localRepo.push(editHash3, repo.getUrl(), "another"); + + TestBotRunner.runPeriodicItems(notifyBot); + email = smtpServer.receive(Duration.ofSeconds(10)); + assertEquals(email.sender(), sender); + assertEquals(email.recipients(), List.of(recipient)); + assertTrue(email.subject().contains(": another: 456789AB: Yet more fixes")); + assertFalse(email.subject().contains("master")); + assertTrue(email.body().contains("Changeset: " + editHash3.abbreviate())); + assertTrue(email.body().contains("456789AB: Yet more fixes")); + assertFalse(email.body().contains("Changeset: " + editHash2.abbreviate())); + assertFalse(email.body().contains("3456789A: Even more fixes")); + } + } }