diff --git a/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java b/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java index 52da633..82cf7cd 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/GitCommands.java @@ -18,6 +18,7 @@ package org.springframework.data.release.git; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -28,14 +29,18 @@ import java.util.stream.Stream; import org.springframework.data.release.CliComponent; import org.springframework.data.release.TimedCommand; import org.springframework.data.release.issues.Changelog; +import org.springframework.data.release.issues.IssueTracker; import org.springframework.data.release.issues.Ticket; import org.springframework.data.release.issues.TicketReference; import org.springframework.data.release.issues.Tickets; +import org.springframework.data.release.model.ArtifactVersion; +import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.ReleaseTrains; import org.springframework.data.release.model.Train; import org.springframework.data.release.model.TrainIteration; import org.springframework.data.release.utils.ExecutionUtils; +import org.springframework.plugin.core.PluginRegistry; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.shell.support.table.Table; @@ -50,6 +55,7 @@ import org.springframework.util.StringUtils; @RequiredArgsConstructor class GitCommands extends TimedCommand { + private final PluginRegistry trackers; private final @NonNull GitOperations git; private final @NonNull Executor executor; @@ -87,23 +93,33 @@ class GitCommands extends TimedCommand { TrainIteration previousIteration = git.getPreviousIteration(iteration); - return ExecutionUtils.runAndReturn(executor, iteration, moduleIteration -> { + return ExecutionUtils.runAndReturn(executor, iteration, module -> { - List ticketRefs = git.getTicketReferencesBetween(moduleIteration.getProject(), previousIteration, + List ticketRefs = git.getTicketReferencesBetween(module.getProject(), previousIteration, iteration); - return Changelog.of(moduleIteration, toTickets(ticketRefs)); + return Changelog.of(module, toTickets(module, ticketRefs)); }).stream() // - .map(Changelog::toString) // + .map(changelog -> { + + ModuleIteration module = changelog.getModule(); + return String.format("%s %s%n%s", module.getModule().getProject().getFullName(), ArtifactVersion.of(module), + changelog.toString(false, " ")); + }) // .collect(Collectors.joining("\n")); } - private Tickets toTickets(List ticketRefs) { + private Tickets toTickets(ModuleIteration module, List ticketReferences) { - return new Tickets( - ticketRefs.stream().map(it -> new Ticket(it.getId(), it.getMessage(), "", null, null)) - .collect(Collectors.toList())); + // TODO: Use only associated tracker + List tickets = new ArrayList<>(); + + for (IssueTracker tracker : trackers) { + tickets.addAll(tracker.findTickets(module, ticketReferences).getTickets()); + } + + return new Tickets(tickets); } /** diff --git a/release-tools/src/main/java/org/springframework/data/release/git/ParsedCommitMessage.java b/release-tools/src/main/java/org/springframework/data/release/git/ParsedCommitMessage.java index da30fca..335cc81 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/ParsedCommitMessage.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/ParsedCommitMessage.java @@ -54,10 +54,10 @@ class ParsedCommitMessage { .compile(String.format("(%s|%s)", JIRA_TICKET.pattern(), GITHUB_TICKET.pattern())); private static final Pattern ORIGINAL_PULL_REQUEST = Pattern - .compile("Original (?>pull request|PR|pullrequest):(?>\\s+)?" + A_TICKET.pattern(), Pattern.CASE_INSENSITIVE); + .compile("Original (?>pull request|PR|pullrequest)[:]*(?>\\s+)?" + A_TICKET.pattern(), Pattern.CASE_INSENSITIVE); private static final Pattern RELATED_TICKET = Pattern.compile( - "Related (?>tickets|ticket):(?>\\s+)?((" + A_TICKET.pattern() + "(?>[\\s,]*))+)", Pattern.CASE_INSENSITIVE); + "Related (?>tickets|ticket)[:]*(?>\\s+)?((" + A_TICKET.pattern() + "(?>[\\s,]*))+)", Pattern.CASE_INSENSITIVE); private final String summary; private final @Nullable String body; diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java b/release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java index 7c618ca..ecb93aa 100644 --- a/release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java @@ -16,6 +16,7 @@ package org.springframework.data.release.issues; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.RequiredArgsConstructor; import java.util.Date; @@ -34,7 +35,7 @@ import org.springframework.format.datetime.DateFormatter; @EqualsAndHashCode public class Changelog { - private final ModuleIteration module; + @Getter private final ModuleIteration module; private final Tickets tickets; /* @@ -43,25 +44,35 @@ public class Changelog { */ @Override public String toString() { + return toString(true, ""); + } + + public String toString(boolean header, String indentation) { ArtifactVersion version = ArtifactVersion.of(module); String headline = String.format("Changes in version %s (%s)", version, new DateFormatter("YYYY-MM-dd").print(new Date(), Locale.US)); - StringBuilder builder = new StringBuilder(headline).append(IOUtils.LINE_SEPARATOR); + StringBuilder builder = new StringBuilder(); - for (int i = 0; i < headline.length(); i++) { - builder.append("-"); + if (header) { + + builder.append(indentation).append(headline).append(IOUtils.LINE_SEPARATOR).append(indentation); + + for (int i = 0; i < headline.length(); i++) { + builder.append("-"); + } + + builder.append(IOUtils.LINE_SEPARATOR); } - builder.append(IOUtils.LINE_SEPARATOR); - for (Ticket ticket : tickets) { String summary = ticket.getSummary(); - builder.append("* ").append(ticket.getId()).append(" - ").append(summary != null ? summary.trim() : ""); + builder.append(indentation).append("* ").append(ticket.getId()).append(" - ") + .append(summary != null ? summary.trim() : ""); if (!summary.endsWith(".")) { builder.append("."); diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java index b0ab1b8..a81cd8a 100644 --- a/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java @@ -136,8 +136,8 @@ class IssueTrackerCommands extends TimedCommand { .toString(); } - @CliCommand("tracker changelog") - public String changelog(@CliOption(key = "", mandatory = true) TrainIteration iteration, // + @CliCommand("tracker open-tickets") + public String openTickets(@CliOption(key = "", mandatory = true) TrainIteration iteration, // @CliOption(key = "module") String moduleName) { if (StringUtils.hasText(moduleName)) { @@ -145,11 +145,15 @@ class IssueTrackerCommands extends TimedCommand { Project project = Projects.requiredByName(moduleName); ModuleIteration module = iteration.getModule(project); - return getTrackerFor(module).getChangelogFor(module).toString(); + String tickets = getTrackerFor(module).getTicketsFor(module).stream().filter(it -> !it.isResolved()) + .collect(Tickets.toTicketsCollector()).toString(false); + + return String.format("%s - %s%n%s%n", project.getFullName(), module.getFullVersionString(), tickets); } - return ExecutionUtils.runAndReturn(executor, iteration, this::getChangelog).// - stream().map(it -> it.toString()).collect(Collectors.joining("\n")); + return ExecutionUtils.runAndReturn(executor, iteration, + moduleIteration -> openTickets(iteration, moduleIteration.getModule().getProject().getName())).// + stream().collect(Collectors.joining("\n")); } @CliCommand("tracker close") diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java b/release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java index e138e38..6186238 100644 --- a/release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java @@ -98,11 +98,17 @@ public class Tickets implements Streamable { */ @Override public String toString() { + return toString(true); + } + + public String toString(boolean header) { StringBuilder builder = new StringBuilder(); - builder.append(String.format("Train only tickets: %s of %s", tickets.size(), overallTotal)); - builder.append(IOUtils.LINE_SEPARATOR); + if (header) { + builder.append(String.format("Train only tickets: %s of %s", tickets.size(), overallTotal)); + builder.append(IOUtils.LINE_SEPARATOR); + } builder.append(tickets.stream().map(it -> "\t" + it).collect(Collectors.joining(IOUtils.LINE_SEPARATOR))); return builder.toString(); diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java index 5ed3ff9..ade61ce 100644 --- a/release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java @@ -593,6 +593,10 @@ class Jira implements JiraConnector { .filter(it -> it.getId().startsWith(moduleIteration.getProjectKey().getKey())).map(TicketReference::getId) .collect(Collectors.toList()); + if (ids.isEmpty()) { + return new Tickets(Collections.emptyList()); + } + Map parameters = newUrlTemplateVariables(); parameters.put("jql", JqlQuery.from(ids)); parameters.put("fields", "summary,status,resolution,fixVersions"); diff --git a/release-tools/src/main/java/org/springframework/data/release/model/Projects.java b/release-tools/src/main/java/org/springframework/data/release/model/Projects.java index bd1710e..6559fce 100644 --- a/release-tools/src/main/java/org/springframework/data/release/model/Projects.java +++ b/release-tools/src/main/java/org/springframework/data/release/model/Projects.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.jgrapht.graph.DefaultDirectedGraph; import org.jgrapht.graph.DefaultEdge; @@ -131,9 +132,9 @@ public class Projects { public static Optional byName(String name) { - return PROJECTS.stream().// - filter(project -> project.getName().equalsIgnoreCase(name) || project.getKey().toString().equals(name)).// - findFirst(); + return Stream.concat(Stream.of(BOM), PROJECTS.stream()) // + .filter(project -> project.getName().equalsIgnoreCase(name) || project.getKey().toString().equals(name))// + .findFirst(); } public static Project requiredByName(String name) {