@@ -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<IssueTracker, Project> 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<TicketReference> ticketRefs = git.getTicketReferencesBetween(moduleIteration.getProject(), previousIteration,
|
||||
List<TicketReference> 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<TicketReference> ticketRefs) {
|
||||
private Tickets toTickets(ModuleIteration module, List<TicketReference> 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<Ticket> tickets = new ArrayList<>();
|
||||
|
||||
for (IssueTracker tracker : trackers) {
|
||||
tickets.addAll(tracker.findTickets(module, ticketReferences).getTickets());
|
||||
}
|
||||
|
||||
return new Tickets(tickets);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(".");
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -98,11 +98,17 @@ public class Tickets implements Streamable<Ticket> {
|
||||
*/
|
||||
@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();
|
||||
|
||||
@@ -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<String, Object> parameters = newUrlTemplateVariables();
|
||||
parameters.put("jql", JqlQuery.from(ids));
|
||||
parameters.put("fields", "summary,status,resolution,fixVersions");
|
||||
|
||||
@@ -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<Project> 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) {
|
||||
|
||||
Reference in New Issue
Block a user