diff --git a/release-tools/pom.xml b/release-tools/pom.xml index 65ea289..a907794 100644 --- a/release-tools/pom.xml +++ b/release-tools/pom.xml @@ -39,6 +39,11 @@ jackson-databind + + com.fasterxml.jackson.module + jackson-module-parameter-names + + joda-time joda-time @@ -137,6 +142,16 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + -parameters + + + diff --git a/release-tools/src/main/java/org/springframework/data/release/build/BuildCommands.java b/release-tools/src/main/java/org/springframework/data/release/build/BuildCommands.java new file mode 100644 index 0000000..4a25bcf --- /dev/null +++ b/release-tools/src/main/java/org/springframework/data/release/build/BuildCommands.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.release.build; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.release.CliComponent; +import org.springframework.data.release.io.Workspace; +import org.springframework.data.release.utils.Logger; +import org.springframework.shell.core.annotation.CliCommand; + +/** + * @author Oliver Gierke + */ +@CliComponent +@RequiredArgsConstructor(onConstructor = @__(@Autowired) ) +public class BuildCommands { + + private final @NonNull BuildOperations build; + private final @NonNull Workspace workspace; + private final @NonNull Logger logger; + + /** + * Removes all Spring Data artifacts from the local repository. + * + * @throws IOException + */ + @CliCommand("workspace purge artifacts") + public void purge() throws IOException { + + logger.log("Workspace", "Cleaning up workspace directory at %s.", + workspace.getWorkingDirectory().getAbsolutePath()); + + workspace.purge(build.getLocalRepository(), + path -> build.getLocalRepository().relativize(path).startsWith("org/springframework/data")); + } +} diff --git a/release-tools/src/main/java/org/springframework/data/release/build/BuildOperations.java b/release-tools/src/main/java/org/springframework/data/release/build/BuildOperations.java index 075bc1c..76ac831 100644 --- a/release-tools/src/main/java/org/springframework/data/release/build/BuildOperations.java +++ b/release-tools/src/main/java/org/springframework/data/release/build/BuildOperations.java @@ -28,7 +28,6 @@ import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.TrainIteration; -import org.springframework.data.release.model.UpdateInformation; import org.springframework.plugin.core.PluginRegistry; import org.springframework.plugin.core.PluginRegistry.Supplier; import org.springframework.stereotype.Component; @@ -56,13 +55,13 @@ public class BuildOperations { Assert.notNull(iteration, "Train iteration must not be null!"); Assert.notNull(phase, "Phase must not be null!"); - UpdateInformation updateInformation = new UpdateInformation(iteration, phase); + UpdateInformation updateInformation = UpdateInformation.of(iteration, phase); doWithBuildSystem(iteration, (system, it) -> system.updateProjectDescriptors(it, updateInformation)); } /** - * Triggers the distribution builds for all modules particitpating in the given {@link TrainIteration}. + * Triggers the distribution builds for all modules participating in the given {@link TrainIteration}. * * @param iteration must not be {@literal null}. */ diff --git a/release-tools/src/main/java/org/springframework/data/release/build/BuildSystem.java b/release-tools/src/main/java/org/springframework/data/release/build/BuildSystem.java index 133d56e..649143b 100644 --- a/release-tools/src/main/java/org/springframework/data/release/build/BuildSystem.java +++ b/release-tools/src/main/java/org/springframework/data/release/build/BuildSystem.java @@ -19,7 +19,6 @@ import org.springframework.data.release.deployment.DeploymentInformation; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Project; -import org.springframework.data.release.model.UpdateInformation; import org.springframework.plugin.core.Plugin; /** @@ -30,16 +29,35 @@ import org.springframework.plugin.core.Plugin; interface BuildSystem extends Plugin { /** - * @param iteration - * @param train - * @param phase - * @throws Exception + * Updates the project descriptors for the given {@link ModuleIteration} using the given {@link UpdateInformation}. + * + * @param iteration must not be {@literal null}. + * @param updateInformation must not be {@literal null}. */ ModuleIteration updateProjectDescriptors(ModuleIteration iteration, UpdateInformation updateInformation); + /** + * Prepares the project descriptor of the {@link ModuleIteration} for the given release {@link Phase}. + * + * @param module must not be {@literal null}. + * @param phase must not be {@literal null}. + * @return + */ ModuleIteration prepareVersion(ModuleIteration module, Phase phase); - ModuleIteration triggerDistributionBuild(ModuleIteration module); - + /** + * Deploy artifacts for the given {@link ModuleIteration} and return the {@link DeploymentInformation}. + * + * @param module must not be {@literal null}. + * @return + */ DeploymentInformation deploy(ModuleIteration module); + + /** + * Runs the distribution build. + * + * @param module must not be {@literal null}. + * @return + */ + ModuleIteration triggerDistributionBuild(ModuleIteration module); } diff --git a/release-tools/src/main/java/org/springframework/data/release/build/GradleBuildSystem.java b/release-tools/src/main/java/org/springframework/data/release/build/GradleBuildSystem.java index 42ebb6c..19acb64 100644 --- a/release-tools/src/main/java/org/springframework/data/release/build/GradleBuildSystem.java +++ b/release-tools/src/main/java/org/springframework/data/release/build/GradleBuildSystem.java @@ -29,7 +29,6 @@ import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.TrainIteration; -import org.springframework.data.release.model.UpdateInformation; import org.springframework.data.release.utils.Logger; import org.springframework.stereotype.Component; @@ -61,7 +60,7 @@ class GradleBuildSystem implements BuildSystem { */ public void updateProject(TrainIteration iteration, final Phase phase) throws Exception { - UpdateInformation updateInformation = new UpdateInformation(iteration, phase); + UpdateInformation updateInformation = UpdateInformation.of(iteration, phase); for (ModuleIteration module : iteration.getModulesExcept(BUILD)) { updateProjectDescriptors(module, updateInformation); diff --git a/release-tools/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java b/release-tools/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java index c798061..eb1524f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java +++ b/release-tools/src/main/java/org/springframework/data/release/build/MavenBuildSystem.java @@ -36,7 +36,6 @@ import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.Train; import org.springframework.data.release.model.TrainIteration; -import org.springframework.data.release.model.UpdateInformation; import org.springframework.data.release.utils.ExecutionUtils; import org.springframework.data.release.utils.Logger; import org.springframework.stereotype.Component; @@ -218,7 +217,7 @@ class MavenBuildSystem implements BuildSystem { public ModuleIteration prepareVersion(ModuleIteration module, Phase phase) { Project project = module.getProject(); - UpdateInformation information = new UpdateInformation(module.getTrainIteration(), phase); + UpdateInformation information = UpdateInformation.of(module.getTrainIteration(), phase); mvn.execute(project, "versions:set", "versions:commit", "-DnewVersion=".concat(information.getProjectVersionToSet(project).toString())); diff --git a/release-tools/src/main/java/org/springframework/data/release/build/PomUpdater.java b/release-tools/src/main/java/org/springframework/data/release/build/PomUpdater.java index 56e2e04..b50c17d 100644 --- a/release-tools/src/main/java/org/springframework/data/release/build/PomUpdater.java +++ b/release-tools/src/main/java/org/springframework/data/release/build/PomUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.Project; -import org.springframework.data.release.model.UpdateInformation; import org.springframework.data.release.utils.Logger; import org.springframework.util.Assert; diff --git a/release-tools/src/main/java/org/springframework/data/release/model/UpdateInformation.java b/release-tools/src/main/java/org/springframework/data/release/build/UpdateInformation.java similarity index 71% rename from release-tools/src/main/java/org/springframework/data/release/model/UpdateInformation.java rename to release-tools/src/main/java/org/springframework/data/release/build/UpdateInformation.java index 0e40d90..135fa94 100644 --- a/release-tools/src/main/java/org/springframework/data/release/model/UpdateInformation.java +++ b/release-tools/src/main/java/org/springframework/data/release/build/UpdateInformation.java @@ -1,4 +1,19 @@ -package org.springframework.data.release.model; +/* + * Copyright 2015-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.release.build; import static org.springframework.data.release.model.Projects.*; @@ -6,7 +21,10 @@ import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import org.springframework.data.release.build.Repository; +import org.springframework.data.release.model.ArtifactVersion; +import org.springframework.data.release.model.Phase; +import org.springframework.data.release.model.Project; +import org.springframework.data.release.model.TrainIteration; import org.springframework.util.Assert; /** @@ -14,7 +32,7 @@ import org.springframework.util.Assert; * * @author Oliver Gierke */ -@RequiredArgsConstructor +@RequiredArgsConstructor(staticName = "of") public class UpdateInformation { private final @NonNull @Getter TrainIteration iteration; diff --git a/release-tools/src/main/java/org/springframework/data/release/git/Commit.java b/release-tools/src/main/java/org/springframework/data/release/git/Commit.java index b063881..7706954 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/Commit.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/Commit.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import lombok.RequiredArgsConstructor; import java.util.Optional; -import org.springframework.data.release.jira.Ticket; +import org.springframework.data.release.issues.Ticket; /** * @author Oliver Gierke 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 56ce187..c5efbde 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 @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,7 @@ import java.util.stream.Stream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.CliComponent; -import org.springframework.data.release.jira.Ticket; -import org.springframework.data.release.jira.TicketBranches; +import org.springframework.data.release.issues.Ticket; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.ReleaseTrains; import org.springframework.data.release.model.Train; @@ -118,8 +117,9 @@ public class GitCommands implements CommandMarker { public void backportChangelogs(@CliOption(key = "", mandatory = true) TrainIteration iteration, // @CliOption(key = "target", mandatory = true) String trains) { - List targets = Stream.of(trains.split(",")).map(it -> ReleaseTrains.getTrainByName(it)) - .collect(Collectors.toList()); + List targets = Stream.of(trains.split(",")).// + map(it -> ReleaseTrains.getTrainByName(it)).// + collect(Collectors.toList()); git.backportChangelogs(iteration, targets); } @@ -149,7 +149,7 @@ public class GitCommands implements CommandMarker { filter(branch -> ticketBranches.hasTicketFor(branch, resolved)).// forEachOrdered(branch -> { - Optional ticket = ticketBranches.getTicket(branch); + Optional ticket = ticketBranches.findTicket(branch); table.addRow(branch.toString(), // ticket.map(t -> t.getTicketStatus().getLabel()).orElse(""), // diff --git a/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java b/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java index 410e927..46f8d0c 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/GitOperations.java @@ -15,7 +15,9 @@ */ package org.springframework.data.release.git; +import lombok.AccessLevel; import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; import java.io.File; import java.io.IOException; @@ -41,9 +43,8 @@ import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.TagOpt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.io.Workspace; -import org.springframework.data.release.jira.IssueTracker; -import org.springframework.data.release.jira.Ticket; -import org.springframework.data.release.jira.TicketBranches; +import org.springframework.data.release.issues.IssueTracker; +import org.springframework.data.release.issues.Ticket; import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; @@ -62,13 +63,14 @@ import org.springframework.util.Assert; */ @Component @RequiredArgsConstructor(onConstructor = @__(@Autowired) ) +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class GitOperations { - private final GitServer server = new GitServer(); - private final Workspace workspace; - private final Logger logger; - private final PluginRegistry issueTracker; - private final GitProperties gitProperties; + GitServer server = new GitServer(); + Workspace workspace; + Logger logger; + PluginRegistry issueTracker; + GitProperties gitProperties; /** * Returns the {@link GitProject} for the given {@link Project}. @@ -297,8 +299,8 @@ public class GitOperations { Collection tickets = tracker.findTickets(project, ticketIds.keySet()); - return TicketBranches.from(tickets.stream() - .collect(Collectors.toMap(ticket -> ticketIds.get(ticket.getId()), ticket -> ticket))); + return TicketBranches + .from(tickets.stream().collect(Collectors.toMap(ticket -> ticketIds.get(ticket.getId()), ticket -> ticket))); }); } @@ -659,12 +661,10 @@ public class GitOperations { } private static interface GitCallback { - T doWithGit(Git git) throws Exception; } private static interface VoidGitCallback { - void doWithGit(Git git) throws Exception; } } diff --git a/release-tools/src/main/java/org/springframework/data/release/git/GitProperties.java b/release-tools/src/main/java/org/springframework/data/release/git/GitProperties.java index 3a96fa2..576472a 100644 --- a/release-tools/src/main/java/org/springframework/data/release/git/GitProperties.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/GitProperties.java @@ -23,7 +23,6 @@ import javax.annotation.PostConstruct; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.data.release.utils.HttpBasicCredentials; import org.springframework.stereotype.Component; @@ -43,8 +42,6 @@ public class GitProperties { private @Getter(AccessLevel.PRIVATE) String password; private String username, author, email; - @Value("${github.api.url}") private String githubApiBaseUrl; - @PostConstruct public void init() { @@ -52,7 +49,6 @@ public class GitProperties { Assert.hasText(password, "No GitHub password (git.password) configured!"); Assert.hasText(author, "No Git author (git.author) configured!"); Assert.hasText(email, "No Git email (git.email) configured!"); - Assert.hasText(githubApiBaseUrl, "No GitHub API base url configured!"); } /** diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/TicketBranches.java b/release-tools/src/main/java/org/springframework/data/release/git/TicketBranches.java similarity index 93% rename from release-tools/src/main/java/org/springframework/data/release/jira/TicketBranches.java rename to release-tools/src/main/java/org/springframework/data/release/git/TicketBranches.java index 36c8fe0..d84af9f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/TicketBranches.java +++ b/release-tools/src/main/java/org/springframework/data/release/git/TicketBranches.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.git; import java.util.Iterator; import java.util.Map; @@ -22,7 +22,7 @@ import java.util.Optional; import java.util.stream.Collectors; import org.springframework.data.release.Streamable; -import org.springframework.data.release.git.Branch; +import org.springframework.data.release.issues.Ticket; import org.springframework.util.Assert; import lombok.EqualsAndHashCode; @@ -53,7 +53,7 @@ public class TicketBranches implements Streamable { Assert.notNull(branch, "Branch must not be null!"); - return getTicket(branch).// + return findTicket(branch).// map(ticket -> requireResolved ? ticket.getTicketStatus().isResolved() : true).// orElse(false); } @@ -76,7 +76,7 @@ public class TicketBranches implements Streamable { * @param branch must not be {@literal null}. * @return */ - public Optional getTicket(Branch branch) { + public Optional findTicket(Branch branch) { Assert.notNull(branch, "Branch must not be null!"); return Optional.ofNullable(ticketBranches.get(branch)); diff --git a/release-tools/src/main/java/org/springframework/data/release/io/WorkspaceCommands.java b/release-tools/src/main/java/org/springframework/data/release/io/WorkspaceCommands.java index e4c49f8..12425fa 100644 --- a/release-tools/src/main/java/org/springframework/data/release/io/WorkspaceCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/io/WorkspaceCommands.java @@ -21,7 +21,6 @@ import java.io.IOException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.CliComponent; -import org.springframework.data.release.build.BuildOperations; import org.springframework.data.release.utils.Logger; import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; @@ -34,7 +33,6 @@ import org.springframework.shell.core.annotation.CliCommand; public class WorkspaceCommands implements CommandMarker { private final Workspace workspace; - private final BuildOperations build; private final Logger logger; @CliCommand("workspace cleanup") @@ -45,19 +43,4 @@ public class WorkspaceCommands implements CommandMarker { workspace.cleanup(); } - - /** - * Removes all Spring Data artifacts from the local repository. - * - * @throws IOException - */ - @CliCommand("workspace purge artifacts") - public void purge() throws IOException { - - logger.log("Workspace", "Cleaning up workspace directory at %s.", - workspace.getWorkingDirectory().getAbsolutePath()); - - workspace.purge(build.getLocalRepository(), - path -> build.getLocalRepository().relativize(path).startsWith("org/springframework/data")); - } } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/Changelog.java b/release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java similarity index 91% rename from release-tools/src/main/java/org/springframework/data/release/jira/Changelog.java rename to release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java index 5c28990..61336ca 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/Changelog.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/Changelog.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,15 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues; + +import lombok.EqualsAndHashCode; +import lombok.RequiredArgsConstructor; import java.util.Date; import java.util.Locale; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; - import org.springframework.data.release.model.ArtifactVersion; import org.springframework.data.release.model.ModuleIteration; import org.springframework.format.datetime.DateFormatter; @@ -30,7 +29,7 @@ import org.springframework.shell.support.util.OsUtils; /** * @author Oliver Gierke */ -@RequiredArgsConstructor(access = AccessLevel.PACKAGE) +@RequiredArgsConstructor(staticName = "of") @EqualsAndHashCode public class Changelog { diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/IssueTracker.java b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTracker.java similarity index 65% rename from release-tools/src/main/java/org/springframework/data/release/jira/IssueTracker.java rename to release-tools/src/main/java/org/springframework/data/release/issues/IssueTracker.java index 58b311a..344127f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/IssueTracker.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTracker.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues; import java.util.Collection; @@ -25,13 +25,15 @@ import org.springframework.data.release.model.TrainIteration; import org.springframework.plugin.core.Plugin; /** + * Interface for issue tracker operations. + * * @author Oliver Gierke * @author Mark Paluch */ public interface IssueTracker extends Plugin { /** - * Reset internal state (cache, ...). + * Reset internal state (cache, etc). */ void reset(); @@ -55,7 +57,7 @@ public interface IssueTracker extends Plugin { /** * Returns the {@link Ticket} that tracks modifications in the context of a release. * - * @param module the module to lookup the {@link Ticket} for. + * @param module the module to lookup the {@link Ticket} for, must not be {@literal null}. * @return */ Ticket getReleaseTicketFor(ModuleIteration module); @@ -64,8 +66,8 @@ public interface IssueTracker extends Plugin { * Query the issue tracker for multiple {@link Ticket#id ticket Ids}. Tickets that are not found are not returned * within the result. * - * @param project - * @param ticketIds collection of {@link Ticket#id ticket Ids} + * @param project must not be {@literal null}. + * @param ticketIds collection of {@link Ticket#id ticket Ids}, must not be {@literal null}. * @return */ Collection findTickets(Project project, Collection ticketIds); @@ -73,18 +75,40 @@ public interface IssueTracker extends Plugin { /** * Creates a release version if release version is missing. * - * @param moduleIteration must not be {@literal null}. - * @param credentials must not be {@literal null}. + * @param module must not be {@literal null}. */ - void createReleaseVersion(ModuleIteration moduleIteration); + void createReleaseVersion(ModuleIteration module); /** * Create release ticket if release ticket is missing. + *

+ * TODO: Return created ticket * - * @param iteration must not be {@literal null}. + * @param module must not be {@literal null}. + */ + void createReleaseTicket(ModuleIteration module); + + /** + * Assigns the ticket to the current user. + * + * @param ticket must not be {@literal null}. * @param credentials must not be {@literal null}. */ - void createReleaseTicket(ModuleIteration moduleIteration); + void assignTicketToMe(Ticket ticket); - Changelog getChangelogFor(ModuleIteration iteration); + /** + * Assigns the release ticket for the given {@link ModuleIteration} to the current user. + * + * @param module must not be {@literal null}. + * @return + */ + Ticket assignReleaseTicketToMe(ModuleIteration module); + + /** + * Returns the {@link Changelog} for the given {@link ModuleIteration}. + * + * @param module must not be {@literal null}. + * @return + */ + Changelog getChangelogFor(ModuleIteration module); } diff --git a/release-tools/src/main/java/org/springframework/data/release/cli/IssueTrackerCommands.java b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java similarity index 63% rename from release-tools/src/main/java/org/springframework/data/release/cli/IssueTrackerCommands.java rename to release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java index 6e19e5b..d702f7f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/cli/IssueTrackerCommands.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerCommands.java @@ -13,17 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.cli; +package org.springframework.data.release.issues; +import static org.springframework.data.release.utils.ExecutionUtils.*; + +import lombok.AccessLevel; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.experimental.FieldDefaults; + +import java.util.function.BiFunction; import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.stream.StreamSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.CliComponent; -import org.springframework.data.release.jira.Changelog; -import org.springframework.data.release.jira.IssueTracker; -import org.springframework.data.release.jira.JiraConnector; -import org.springframework.data.release.jira.Tickets; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.TrainIteration; @@ -39,56 +44,38 @@ import org.springframework.util.StringUtils; * @author Mark Paluch */ @CliComponent +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +@RequiredArgsConstructor(onConstructor = @__(@Autowired) ) public class IssueTrackerCommands implements CommandMarker { - private final PluginRegistry tracker; - private final JiraConnector jira; - - /** - * @param tracker must not be {@literal null}. - * @param jira must not be {@literal null}. - * @param environment must not be {@literal null}. - */ - @Autowired - public IssueTrackerCommands(PluginRegistry tracker, JiraConnector jira) { - - this.tracker = tracker; - this.jira = jira; - } + @NonNull PluginRegistry tracker; @CliCommand("tracker evict") public void evict() { StreamSupport.stream(tracker.spliterator(), false).forEach(IssueTracker::reset); } - @CliCommand(value = "jira tickets") + @CliCommand(value = "tracker tickets") public String jira(@CliOption(key = "", mandatory = true) TrainIteration iteration, // @CliOption(key = "for-current-user", specifiedDefaultValue = "true", unspecifiedDefaultValue = "false") boolean forCurrentUser) { - Tickets tickets = StreamSupport.stream(tracker.spliterator(), false). // - flatMap(issueTracker -> issueTracker. // - getTicketsFor(iteration, forCurrentUser).stream()) - . // - collect(Tickets.toTicketsCollector()); - return tickets.toString(); + return tracker.getPlugins().stream().// + flatMap(it -> it.getTicketsFor(iteration, forCurrentUser).stream()).// + collect(Tickets.toTicketsCollector()).toString(); } @CliCommand(value = "tracker releasetickets") public String releaseTickets(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - - Tickets tickets = StreamSupport.stream(tracker.spliterator(), false). // - flatMap(issueTracker -> issueTracker.getTicketsFor(iteration).stream()). // - collect(Tickets.toTicketsCollector()); - return tickets.getReleaseTickets(iteration).toString(); + return runAndReturn(iteration, module -> getTrackerFor(module).getReleaseTicketFor(module), + Tickets.toTicketsCollector()).toString(); } - @CliCommand(value = "jira self-assign releasetickets") + @CliCommand(value = "tracker self-assign releasetickets") public String jiraSelfAssignReleaseTickets(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - Tickets releaseTickets = jira.getTicketsFor(iteration).getReleaseTickets(iteration); - releaseTickets.forEach(ticket -> jira.assignTicketToMe(ticket)); - return releaseTickets(iteration); + return runAndReturn(iteration, module -> getTrackerFor(module).assignReleaseTicketToMe(module), + Tickets.toTicketsCollector()).toString(); } @CliCommand(value = "tracker create releaseversions") @@ -99,21 +86,14 @@ public class IssueTrackerCommands implements CommandMarker { @CliCommand(value = "tracker create releasetickets") public String createReleaseTickets(@CliOption(key = "", mandatory = true) TrainIteration iteration) { - iteration.forEach(this::createReleaseVersion); + iteration.stream().// + forEach(module -> getTrackerFor(module).createReleaseTicket(module)); evict(); return releaseTickets(iteration); } - private void createReleaseVersion(ModuleIteration moduleIteration) { - getPluginFor(moduleIteration).createReleaseVersion(moduleIteration); - } - - private IssueTracker getPluginFor(ModuleIteration moduleIteration) { - return tracker.getPluginFor(moduleIteration.getProject()); - } - @CliCommand("tracker changelog") public String changelog(@CliOption(key = "", mandatory = true) TrainIteration iteration, // @CliOption(key = "module") String moduleName) { @@ -121,7 +101,7 @@ public class IssueTrackerCommands implements CommandMarker { if (StringUtils.hasText(moduleName)) { ModuleIteration module = iteration.getModule(moduleName); - return tracker.getPluginFor(module.getProject()).getChangelogFor(module).toString(); + return getTrackerFor(module).getChangelogFor(module).toString(); } return ExecutionUtils.runAndReturn(iteration, this::getChangelog).// @@ -129,6 +109,18 @@ public class IssueTrackerCommands implements CommandMarker { } private Changelog getChangelog(ModuleIteration module) { - return tracker.getPluginFor(module.getProject()).getChangelogFor(module); + return getTrackerFor(module).getChangelogFor(module); + } + + private void createReleaseVersion(ModuleIteration moduleIteration) { + getTrackerFor(moduleIteration).createReleaseVersion(moduleIteration); + } + + private Stream doWithBuildSystem(TrainIteration train, BiFunction function) { + return train.stream().map(module -> function.apply(getTrackerFor(module), module)); + } + + private IssueTracker getTrackerFor(ModuleIteration moduleIteration) { + return tracker.getPluginFor(moduleIteration.getProject()); } } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/IssueTrackerConfiguration.java b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerConfiguration.java similarity index 58% rename from release-tools/src/main/java/org/springframework/data/release/jira/IssueTrackerConfiguration.java rename to release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerConfiguration.java index 78f69b7..9008de4 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/IssueTrackerConfiguration.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/IssueTrackerConfiguration.java @@ -13,60 +13,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues; import java.util.ArrayList; import java.util.List; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.release.git.GitProperties; import org.springframework.data.release.model.Project; -import org.springframework.data.release.utils.Logger; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.plugin.core.OrderAwarePluginRegistry; import org.springframework.plugin.core.PluginRegistry; import org.springframework.web.client.RestTemplate; +import com.fasterxml.jackson.annotation.JsonCreator.Mode; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.AnnotatedMember; +import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; +import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; /** * @author Oliver Gierke * @author Mark Paluch */ @Configuration -@EnableCaching +@EnableCaching(proxyTargetClass = true) class IssueTrackerConfiguration { @Bean - public CacheManager cacheManager() { + CacheManager cacheManager() { return new ConcurrentMapCacheManager(); } @Bean - public PluginRegistry issueTrackers(List plugins) { - return OrderAwarePluginRegistry.create(plugins); - } - - @Bean - public ObjectMapper jacksonObjectMapper() { + ObjectMapper jacksonObjectMapper() { ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setSerializationInclusion(Include.NON_NULL); + mapper.registerModule(new ParameterNamesModule(Mode.PROPERTIES)); + mapper.registerModule(new SyntheticLambdaFactoryMethodIgnoringModule()); return mapper; } @Bean - public RestTemplate restTemplate() { + @Qualifier("tracker") + RestTemplate restTemplate() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(jacksonObjectMapper()); @@ -81,12 +84,36 @@ class IssueTrackerConfiguration { } @Bean - public Jira jira(Logger logger, JiraProperties jiraProperties) { - return new Jira(restTemplate(), logger, jiraProperties); + PluginRegistry issueTrackers(List plugins) { + return OrderAwarePluginRegistry.create(plugins); } - @Bean - public GitHubIssueTracker github(Logger logger, GitProperties properties) { - return new GitHubIssueTracker(restTemplate(), logger, properties); + /** + * @author Oliver Gierke + */ + static class SyntheticLambdaFactoryMethodIgnoringModule extends SimpleModule { + + private static final long serialVersionUID = -3075786389813846512L; + + @Override + public void setupModule(SetupContext context) { + + context.insertAnnotationIntrospector(new NopAnnotationIntrospector() { + + private static final long serialVersionUID = 479313244908256455L; + + @Override + public boolean hasIgnoreMarker(AnnotatedMember m) { + + if (!(m instanceof AnnotatedMethod)) { + return super.hasIgnoreMarker(m); + } + + AnnotatedMethod method = (AnnotatedMethod) m; + + return method.getName().startsWith("lambda$") ? true : super.hasIgnoreMarker(m); + } + }); + } } } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/Ticket.java b/release-tools/src/main/java/org/springframework/data/release/issues/Ticket.java similarity index 54% rename from release-tools/src/main/java/org/springframework/data/release/jira/Ticket.java rename to release-tools/src/main/java/org/springframework/data/release/issues/Ticket.java index ed15a72..ccbbead 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/Ticket.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/Ticket.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues; + +import lombok.Value; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Tracker; import org.springframework.data.release.model.TrainIteration; - -import lombok.Value; +import org.springframework.util.Assert; /** * Value object to represent a {@link Ticket}. @@ -29,9 +30,8 @@ import lombok.Value; @Value public class Ticket { - private final String id; - private final String summary; - private final TicketStatus ticketStatus; + String id, summary; + TicketStatus ticketStatus; /* * (non-Javadoc) @@ -39,18 +39,32 @@ public class Ticket { */ @Override public String toString() { - return String.format("%13s - %s", id, summary); + return String.format("%14s - %s", id, summary); } public boolean isResolved() { return ticketStatus.isResolved(); } - public boolean isReleaseTicketFor(ModuleIteration moduleIteration) { - return summary.equals(Tracker.releaseTicketSummary(moduleIteration)); + /** + * Returns whether the current {@link Ticket} is the release ticket for the given {@link ModuleIteration}. + * + * @param module must not be {@literal null}. + * @return + */ + public boolean isReleaseTicketFor(ModuleIteration module) { + + Assert.notNull(module, "Module must not be null!"); + return summary.equals(Tracker.releaseTicketSummary(module)); } - public boolean isReleaseTicketFor(TrainIteration iteration) { - return iteration.stream().filter(this::isReleaseTicketFor).findFirst().isPresent(); + /** + * Returns whether the current {@link Ticket} is a release ticket for the given {@link TrainIteration}. + * + * @param train must not be {@literal null}. + * @return + */ + public boolean isReleaseTicketFor(TrainIteration train) { + return train.stream().anyMatch(this::isReleaseTicketFor); } } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/TicketStatus.java b/release-tools/src/main/java/org/springframework/data/release/issues/TicketStatus.java similarity index 81% rename from release-tools/src/main/java/org/springframework/data/release/jira/TicketStatus.java rename to release-tools/src/main/java/org/springframework/data/release/issues/TicketStatus.java index 081a122..90dabcc 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/TicketStatus.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/TicketStatus.java @@ -14,14 +14,24 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues; /** * @author Mark Paluch */ public interface TicketStatus { + /** + * Returns + * + * @return + */ String getLabel(); + /** + * Returns whether the ticket is marked as resolved. + * + * @return + */ boolean isResolved(); } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/Tickets.java b/release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java similarity index 84% rename from release-tools/src/main/java/org/springframework/data/release/jira/Tickets.java rename to release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java index 8c1d746..9b74234 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/Tickets.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/Tickets.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues; + +import lombok.RequiredArgsConstructor; +import lombok.Value; import java.util.ArrayList; import java.util.Collections; @@ -33,9 +36,6 @@ import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.TrainIteration; import org.springframework.util.StringUtils; -import lombok.RequiredArgsConstructor; -import lombok.Value; - /** * Value object to represent a list of {@link Ticket}s. * @@ -46,8 +46,8 @@ import lombok.Value; @RequiredArgsConstructor public class Tickets implements Streamable { - private final List tickets; - private final int overallTotal; + List tickets; + int overallTotal; public Tickets(List tickets) { this(Collections.unmodifiableList(tickets), tickets.size()); @@ -68,9 +68,7 @@ public class Tickets implements Streamable { public Ticket getReleaseTicket(ModuleIteration moduleIteration) { - Optional releaseTicket = findReleaseTicket(moduleIteration); - - return releaseTicket.orElseThrow( + return findReleaseTicket(moduleIteration).orElseThrow( () -> new IllegalStateException(String.format("Did not find a release ticket for %s!", moduleIteration))); } @@ -84,19 +82,26 @@ public class Tickets implements Streamable { return stream().// filter(ticket -> ticket.isReleaseTicketFor(iteration)).// + distinct().// collect(toTicketsCollector()); } private Optional findReleaseTicket(ModuleIteration moduleIteration) { + return stream().// filter(ticket -> ticket.isReleaseTicketFor(moduleIteration)).// findFirst(); } + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ @Override public String toString() { StringBuilder builder = new StringBuilder(); + builder.append(String.format("Train only tickets: %s of %s", tickets.size(), overallTotal)); builder.append("\n"); builder.append(StringUtils.collectionToDelimitedString(tickets, "\n")); @@ -112,16 +117,29 @@ public class Tickets implements Streamable { public static Collector toTicketsCollector() { return new Collector, Tickets>() { + + /* + * (non-Javadoc) + * @see java.util.stream.Collector#supplier() + */ @Override public Supplier> supplier() { return ArrayList::new; } + /* + * (non-Javadoc) + * @see java.util.stream.Collector#accumulator() + */ @Override public BiConsumer, Ticket> accumulator() { return List::add; } + /* + * (non-Javadoc) + * @see java.util.stream.Collector#combiner() + */ @Override public BinaryOperator> combiner() { return (left, right) -> { @@ -130,16 +148,23 @@ public class Tickets implements Streamable { }; } + /* + * (non-Javadoc) + * @see java.util.stream.Collector#finisher() + */ @Override public Function, Tickets> finisher() { return tickets -> new Tickets(tickets); } + /* + * (non-Javadoc) + * @see java.util.stream.Collector#characteristics() + */ @Override public Set characteristics() { return Collections.emptySet(); } - }; } } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHub.java similarity index 73% rename from release-tools/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java rename to release-tools/src/main/java/org/springframework/data/release/issues/github/GitHub.java index 2c085db..8afaf25 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/GitHubIssueTracker.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHub.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.github; import java.net.URI; import java.util.ArrayList; @@ -23,19 +23,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Stream; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.ParameterizedTypeReference; import org.springframework.data.release.git.GitProject; -import org.springframework.data.release.git.GitProperties; -import org.springframework.data.release.model.Iteration; +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.Tickets; +import org.springframework.data.release.issues.github.GitHubIssue.Milestone; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; -import org.springframework.data.release.model.Projects; -import org.springframework.data.release.model.ReleaseTrains; import org.springframework.data.release.model.Tracker; import org.springframework.data.release.model.TrainIteration; import org.springframework.data.release.utils.Logger; @@ -43,19 +45,18 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.web.client.HttpStatusCodeException; import org.springframework.web.client.RestOperations; import org.springframework.web.util.UriTemplate; -import lombok.RequiredArgsConstructor; - /** * @author Oliver Gierke * @author Mark Paluch */ -@RequiredArgsConstructor -class GitHubIssueTracker implements IssueTracker { +@Component +class GitHub implements IssueTracker { private static final String MILESTONE_URI = "{githubBaseUrl}/repos/spring-projects/{repoName}/milestones?state={state}"; private static final String ISSUES_BY_MILESTONE_AND_ASSIGNEE_URI_TEMPLATE = "{githubBaseUrl}/repos/spring-projects/{repoName}/issues?milestone={id}&state=all&assignee={assignee}"; @@ -64,13 +65,26 @@ class GitHubIssueTracker implements IssueTracker { private static final String ISSUE_BY_ID_URI_TEMPLATE = "{githubBaseUrl}/repos/spring-projects/{repoName}/issues/{id}"; private static final String ISSUES_URI_TEMPLATE = "{githubBaseUrl}/repos/spring-projects/{repoName}/issues"; - private static final ParameterizedTypeReference> MILESTONES_TYPE = new ParameterizedTypeReference>() {}; + private static final ParameterizedTypeReference> MILESTONES_TYPE = new ParameterizedTypeReference>() {}; private static final ParameterizedTypeReference> ISSUES_TYPE = new ParameterizedTypeReference>() {}; private static final ParameterizedTypeReference ISSUE_TYPE = new ParameterizedTypeReference() {}; private final RestOperations operations; private final Logger logger; - private final GitProperties properties; + private final GitHubProperties properties; + + /** + * @param operations + * @param logger + * @param properties + */ + @Autowired + public GitHub(@Qualifier("tracker") RestOperations operations, Logger logger, GitHubProperties properties) { + + this.operations = operations; + this.logger = logger; + this.properties = properties; + } /* * (non-Javadoc) @@ -103,24 +117,29 @@ class GitHubIssueTracker implements IssueTracker { String repositoryName = GitProject.of(project).getRepositoryName(); List tickets = new ArrayList<>(); - for (String ticketId : ticketIds) { + + ticketIds.forEach(ticketId -> { Map parameters = newUrlTemplateVariables(); parameters.put("repoName", repositoryName); parameters.put("id", ticketId); try { + GitHubIssue gitHubIssue = operations.exchange(ISSUE_BY_ID_URI_TEMPLATE, HttpMethod.GET, new HttpEntity<>(newUserScopedHttpHeaders()), ISSUE_TYPE, parameters).getBody(); tickets.add(toTicket(gitHubIssue)); + } catch (HttpStatusCodeException e) { + if (e.getStatusCode() == HttpStatus.NOT_FOUND) { - continue; + return; } + throw e; } - } + }); return tickets; } @@ -133,13 +152,13 @@ class GitHubIssueTracker implements IssueTracker { @Cacheable("changelogs") public Changelog getChangelogFor(ModuleIteration moduleIteration) { - Tickets tickets = getIssuesFor(moduleIteration, false).stream().// + Tickets tickets = getIssuesFor(moduleIteration, false).// map(issue -> toTicket(issue)).// collect(Tickets.toTicketsCollector()); logger.log(moduleIteration, "Created changelog with %s entries.", tickets.getOverallTotal()); - return new Changelog(moduleIteration, tickets); + return Changelog.of(moduleIteration, tickets); } /* @@ -151,11 +170,6 @@ class GitHubIssueTracker implements IssueTracker { return project.uses(Tracker.GITHUB); } - @Cacheable("tickets") - public Tickets getTicketsFor(ModuleIteration iteration) { - return getTicketsFor(iteration, false); - } - @Override public Tickets getTicketsFor(TrainIteration iteration) { return getTicketsFor(iteration, false); @@ -182,14 +196,17 @@ class GitHubIssueTracker implements IssueTracker { return tickets; } + /* + * (non-Javadoc) + * @see org.springframework.data.release.tracker.IssueTracker#createReleaseVersion(org.springframework.data.release.model.ModuleIteration) + */ @Override public void createReleaseVersion(ModuleIteration moduleIteration) { Assert.notNull(moduleIteration, "ModuleIteration must not be null."); String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName(); - - Optional milestone = findMilestone(moduleIteration, repositoryName); + Optional milestone = findMilestone(moduleIteration, repositoryName); if (milestone.isPresent()) { return; @@ -206,13 +223,17 @@ class GitHubIssueTracker implements IssueTracker { new HttpEntity(githubMilestone.toMilestone(), httpHeaders), GitHubIssue.Milestone.class, parameters); } + /* + * + * (non-Javadoc) + * @see org.springframework.data.release.tracker.IssueTracker#createReleaseTicket(org.springframework.data.release.model.ModuleIteration) + */ @Override public void createReleaseTicket(ModuleIteration moduleIteration) { Assert.notNull(moduleIteration, "ModuleIteration must not be null."); HttpHeaders httpHeaders = newUserScopedHttpHeaders(); - Tickets tickets = getTicketsFor(moduleIteration); if (tickets.hasReleaseTicket(moduleIteration)) { @@ -220,59 +241,61 @@ class GitHubIssueTracker implements IssueTracker { } String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName(); + Milestone milestone = getMilestone(moduleIteration, repositoryName); + GitHubIssue gitHubIssue = GitHubIssue.of(Tracker.releaseTicketSummary(moduleIteration), milestone); Map parameters = newUrlTemplateVariables(); parameters.put("repoName", repositoryName); - GitHubIssue.Milestone milestone = getMilestone(moduleIteration, repositoryName); - logger.log(moduleIteration, "Creating release ticket…"); - GitHubIssue gitHubIssue = new GitHubIssue(Tracker.releaseTicketSummary(moduleIteration), milestone); - operations.exchange(ISSUES_URI_TEMPLATE, HttpMethod.POST, new HttpEntity(gitHubIssue, httpHeaders), GitHubIssue.class, parameters).getBody(); - } - private Tickets getTicketsFor(ModuleIteration moduleIteration, boolean forCurrentUser) { - - List issues = getIssuesFor(moduleIteration, forCurrentUser); - return issues.stream().map(this::toTicket).collect(Tickets.toTicketsCollector()); + @Cacheable("tickets") + public Tickets getTicketsFor(ModuleIteration iteration) { + return getTicketsFor(iteration, false); } - private List getIssuesFor(ModuleIteration moduleIteration, boolean forCurrentUser) { - - String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName(); - - GitHubIssue.Milestone milestone = getMilestone(moduleIteration, repositoryName); - - Map parameters = newUrlTemplateVariables(); - parameters.put("repoName", repositoryName); - parameters.put("id", milestone.getNumber()); - - if (forCurrentUser) { - parameters.put("assignee", properties.getUsername()); - - return operations.exchange(ISSUES_BY_MILESTONE_AND_ASSIGNEE_URI_TEMPLATE, HttpMethod.GET, - new HttpEntity<>(newUserScopedHttpHeaders()), ISSUES_TYPE, parameters).getBody(); - } - - return operations.exchange(ISSUES_BY_MILESTONE_URI_TEMPLATE, HttpMethod.GET, - new HttpEntity<>(newUserScopedHttpHeaders()), ISSUES_TYPE, parameters).getBody(); + /* + * + * (non-Javadoc) + * @see org.springframework.data.release.jira.IssueTracker#assignTicketToMe(org.springframework.data.release.jira.Ticket) + */ + @Override + public void assignTicketToMe(Ticket ticket) { + logger.log("Ticket", "Skipping ticket assignment for %s", ticket); } - private GitHubIssue.Milestone getMilestone(ModuleIteration moduleIteration, String repositoryName) { + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.IssueTracker#assignReleaseTicketToMe(org.springframework.data.release.model.ModuleIteration) + */ + @Override + public Ticket assignReleaseTicketToMe(ModuleIteration module) { - Optional milestone = findMilestone(moduleIteration, repositoryName); - return milestone - .orElseThrow(() -> new IllegalStateException(String.format("No milestone for %s found containing %s!", // - moduleIteration.getProject().getFullName(), // - moduleIteration.getShortVersionString()))); + logger.log("Ticket", "Skipping ticket assignment for %s", module); + return null; } - @Cacheable("milestone") - protected Optional findMilestone(ModuleIteration moduleIteration, String repositoryName) { + private HttpHeaders newUserScopedHttpHeaders() { + + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", properties.getHttpCredentials().toString()); + + return headers; + } + + private Map newUrlTemplateVariables() { + + Map parameters = new HashMap<>(); + parameters.put("githubBaseUrl", properties.getApiUrl()); + + return parameters; + } + + private Optional findMilestone(ModuleIteration moduleIteration, String repositoryName) { for (String state : Arrays.asList("close", "open")) { @@ -288,7 +311,7 @@ class GitHubIssueTracker implements IssueTracker { new HttpEntity<>(newUserScopedHttpHeaders()), MILESTONES_TYPE, parameters).getBody(); Optional milestone = milestones.stream(). // - filter(m -> m.matchesIteration(moduleIteration)). // + filter(m -> m.matches(moduleIteration)). // findFirst(). // map(m -> { logger.log(moduleIteration, "Found milestone %s.", m); @@ -303,38 +326,50 @@ class GitHubIssueTracker implements IssueTracker { return Optional.empty(); } - private HttpHeaders newUserScopedHttpHeaders() { + private Tickets getTicketsFor(ModuleIteration moduleIteration, boolean forCurrentUser) { - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", properties.getHttpCredentials().toString()); - - return headers; + return getIssuesFor(moduleIteration, forCurrentUser).// + map(GitHub::toTicket).// + collect(Tickets.toTicketsCollector()); } - private Map newUrlTemplateVariables() { - Map parameters = new HashMap<>(); - parameters.put("githubBaseUrl", properties.getGithubApiBaseUrl()); - return parameters; + private Stream getIssuesFor(ModuleIteration moduleIteration, boolean forCurrentUser) { + + String repositoryName = GitProject.of(moduleIteration.getProject()).getRepositoryName(); + + GitHubIssue.Milestone milestone = getMilestone(moduleIteration, repositoryName); + + Map parameters = newUrlTemplateVariables(); + parameters.put("repoName", repositoryName); + parameters.put("id", milestone.getNumber()); + + if (forCurrentUser) { + parameters.put("assignee", properties.getUsername()); + + return getForIssues(ISSUES_BY_MILESTONE_AND_ASSIGNEE_URI_TEMPLATE, parameters); + } + + return getForIssues(ISSUES_BY_MILESTONE_URI_TEMPLATE, parameters); } - private Ticket toTicket(GitHubIssue issue) { + private Stream getForIssues(String template, Map parameters) { + + return operations + .exchange(template, HttpMethod.GET, new HttpEntity<>(newUserScopedHttpHeaders()), ISSUES_TYPE, parameters) + .getBody().stream(); + } + + private Milestone getMilestone(ModuleIteration moduleIteration, String repositoryName) { + + Optional milestone = findMilestone(moduleIteration, repositoryName); + + return milestone + .orElseThrow(() -> new IllegalStateException(String.format("No milestone for %s found containing %s!", // + moduleIteration.getProject().getFullName(), // + moduleIteration.getShortVersionString()))); + } + + private static Ticket toTicket(GitHubIssue issue) { return new Ticket(issue.getId(), issue.getTitle(), new GithubTicketStatus(issue.getState())); } - - public static void main(String[] args) { - - try (ConfigurableApplicationContext context = new ClassPathXmlApplicationContext( - "META-INF/spring/spring-shell-plugin.xml")) { - - IssueTracker tracker = context.getBean("gitHubIssueTracker", IssueTracker.class); - - TrainIteration iteration = new TrainIteration(ReleaseTrains.CODD, Iteration.SR2); - ModuleIteration module = iteration.getModule(Projects.BUILD); - - Changelog changelog = tracker.getChangelogFor(module); - System.out.println(changelog); - - System.out.println(tracker.getReleaseTicketFor(module)); - } - } } diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubIssue.java b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubIssue.java new file mode 100644 index 0000000..a5a8526 --- /dev/null +++ b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubIssue.java @@ -0,0 +1,60 @@ +/* + * Copyright 2014-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.release.issues.github; + +import lombok.RequiredArgsConstructor; +import lombok.Value; + +import org.springframework.data.release.model.ModuleIteration; + +/** + * @author Oliver Gierke + * @author Mark Paluch + */ +@Value +@RequiredArgsConstructor +class GitHubIssue { + + String number, title, state; + Object milestone; + + public static GitHubIssue of(String title, Milestone milestone) { + return new GitHubIssue(null, title, null, milestone.number); + } + + public String getId() { + return number == null ? null : "#".concat(number); + } + + /** + * @author Oliver Gierke + * @author Mark Paluch + */ + @Value + static class Milestone { + + Long number; + String title, description; + + public static Milestone of(String title, String description) { + return new Milestone(null, title, description); + } + + public boolean matches(ModuleIteration moduleIteration) { + return title.contains(moduleIteration.getShortVersionString()); + } + } +} diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/GitHubMilestone.java b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubMilestone.java similarity index 80% rename from release-tools/src/main/java/org/springframework/data/release/jira/GitHubMilestone.java rename to release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubMilestone.java index 166b816..6aa995b 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/GitHubMilestone.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubMilestone.java @@ -13,19 +13,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; - -import org.springframework.data.release.model.ModuleIteration; +package org.springframework.data.release.issues.github; import lombok.Value; +import org.springframework.data.release.issues.github.GitHubIssue.Milestone; +import org.springframework.data.release.model.ModuleIteration; + /** * @author Mark Paluch */ @Value class GithubMilestone { - private ModuleIteration module; + ModuleIteration module; + + public String getDescription() { + return module.getTrain().getName() + " " + module.getIteration().getName(); + } + + public Milestone toMilestone() { + return Milestone.of(toString(), getDescription()); + } /* * (non-Javadoc) @@ -35,12 +44,4 @@ class GithubMilestone { public String toString() { return module.getMediumVersionString(); } - - public String getDescription() { - return module.getTrain().getName() + " " + module.getIteration().getName(); - } - - public GitHubIssue.Milestone toMilestone() { - return new GitHubIssue.Milestone(toString(), getDescription()); - } } diff --git a/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubProperties.java b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubProperties.java new file mode 100644 index 0000000..fda66d9 --- /dev/null +++ b/release-tools/src/main/java/org/springframework/data/release/issues/github/GitHubProperties.java @@ -0,0 +1,57 @@ +/* + * Copyright 2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.release.issues.github; + +import lombok.AccessLevel; +import lombok.Data; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.data.release.git.GitProperties; +import org.springframework.data.release.utils.HttpBasicCredentials; +import org.springframework.stereotype.Component; +import org.springframework.util.Assert; + +/** + * @author Oliver Gierke + */ +@Data +@Component +@ConfigurationProperties(prefix = "github") +@RequiredArgsConstructor(onConstructor = @__(@Autowired) ) +public class GitHubProperties { + + private final @Getter(AccessLevel.NONE) GitProperties gitProperties; + + private String apiUrl; + + public String getUsername() { + return gitProperties.getUsername(); + } + + public HttpBasicCredentials getHttpCredentials() { + return gitProperties.getHttpCredentials(); + } + + @PostConstruct + public void init() { + Assert.hasText(apiUrl, "No GitHub API base url configured!"); + } +} diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/GithubTicketStatus.java b/release-tools/src/main/java/org/springframework/data/release/issues/github/GithubTicketStatus.java similarity index 60% rename from release-tools/src/main/java/org/springframework/data/release/jira/GithubTicketStatus.java rename to release-tools/src/main/java/org/springframework/data/release/issues/github/GithubTicketStatus.java index c39ef51..81de37f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/GithubTicketStatus.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/github/GithubTicketStatus.java @@ -14,25 +14,42 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.github; -import lombok.AllArgsConstructor; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import lombok.experimental.FieldDefaults; + +import org.springframework.data.release.issues.TicketStatus; /** * Value object for a GitHub ticket status. * * @author Mark Paluch */ -@AllArgsConstructor +@EqualsAndHashCode +@ToString +@RequiredArgsConstructor +@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) class GithubTicketStatus implements TicketStatus { private final String status; + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.TicketStatus#getLabel() + */ @Override public String getLabel() { return status; } + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.TicketStatus#isResolved() + */ @Override public boolean isResolved() { return "closed".equalsIgnoreCase(status); diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/CreatedJiraIssue.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/CreatedJiraIssue.java similarity index 77% rename from release-tools/src/main/java/org/springframework/data/release/jira/CreatedJiraIssue.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/CreatedJiraIssue.java index 85521a3..c6eccf4 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/CreatedJiraIssue.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/CreatedJiraIssue.java @@ -14,19 +14,17 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; -import lombok.Data; +import lombok.Value; /** - * Value object for a created Jira issue. + * Value object for a created JIRA issue. * * @author Mark Paluch + * @author Oliver Gierke */ -@Data -public class CreatedJiraIssue { - - private String id; - private String key; - +@Value +class CreatedJiraIssue { + String id, key; } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/Credentials.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/Credentials.java similarity index 82% rename from release-tools/src/main/java/org/springframework/data/release/jira/Credentials.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/Credentials.java index 56dc81a..c1cae96 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/Credentials.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/Credentials.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,19 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; - -import javax.xml.bind.DatatypeConverter; +package org.springframework.data.release.issues.jira; import lombok.Value; +import javax.xml.bind.DatatypeConverter; + /** * @author Oliver Gierke */ @Value -public class Credentials { +class Credentials { - private final String username, password; + String username, password; public String asBase64() { return DatatypeConverter.printBase64Binary(String.format("%s:%s", username, password).getBytes()); diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/Jira.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java similarity index 86% rename from release-tools/src/main/java/org/springframework/data/release/jira/Jira.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java index 4130ece..82fe8df 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/Jira.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/Jira.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; import java.net.URI; import java.util.ArrayList; @@ -25,19 +25,21 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import org.springframework.boot.SpringApplication; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.data.release.Application; -import org.springframework.data.release.jira.JiraIssue.Component; -import org.springframework.data.release.jira.JiraIssue.Fields; -import org.springframework.data.release.model.Iteration; +import org.springframework.data.release.issues.Changelog; +import org.springframework.data.release.issues.Ticket; +import org.springframework.data.release.issues.Tickets; +import org.springframework.data.release.issues.jira.JiraIssue.Component; +import org.springframework.data.release.issues.jira.JiraIssue.Fields; +import org.springframework.data.release.issues.jira.JiraIssue.Resolution; +import org.springframework.data.release.issues.jira.JiraIssue.Status; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; import org.springframework.data.release.model.ProjectKey; -import org.springframework.data.release.model.ReleaseTrains; import org.springframework.data.release.model.Tracker; import org.springframework.data.release.model.TrainIteration; import org.springframework.data.release.utils.Logger; @@ -48,13 +50,11 @@ import org.springframework.util.Assert; import org.springframework.web.client.RestOperations; import org.springframework.web.util.UriTemplate; -import lombok.RequiredArgsConstructor; - /** * @author Oliver Gierke * @author Mark Paluch */ -@RequiredArgsConstructor +@org.springframework.stereotype.Component class Jira implements JiraConnector { private static final String BASE_URI = "{jiraBaseUrl}/rest/api/2"; @@ -69,9 +69,21 @@ class Jira implements JiraConnector { private final RestOperations operations; private final Logger logger; - private final JiraProperties jiraProperties; + /** + * @param operations + * @param logger + * @param jiraProperties + */ + @Autowired + public Jira(@Qualifier("tracker") RestOperations operations, Logger logger, JiraProperties jiraProperties) { + + this.operations = operations; + this.logger = logger; + this.jiraProperties = jiraProperties; + } + /* * (non-Javadoc) * @see org.springframework.data.release.jira.JiraConnector#reset() @@ -93,13 +105,11 @@ class Jira implements JiraConnector { JiraIssues issues = getJiraIssues(query, new HttpHeaders(), 0); - if (issues.getIssues().isEmpty()) { + if (!issues.hasIssues()) { throw new IllegalArgumentException(String.format("Did not find a release ticket for %s!", moduleIteration)); } - JiraIssue issue = issues.getIssues().get(0); - - return toTicket(issue); + return toTicket(issues.stream().findFirst().get()); } /* @@ -125,19 +135,27 @@ class Jira implements JiraConnector { JiraIssues issues = operations.exchange(SEARCH_TEMPLATE, HttpMethod.GET, null, JiraIssues.class, parameters) .getBody(); - return issues.getIssues().stream().// + return issues.stream().// map(this::toTicket).// collect(Collectors.toList()); } - @Cacheable("tickets") + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.IssueTracker#getTicketsFor(org.springframework.data.release.model.TrainIteration) + */ @Override + @Cacheable("tickets") public Tickets getTicketsFor(TrainIteration iteration) { return getTicketsFor(iteration, false); } - @Cacheable("tickets") + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.IssueTracker#getTicketsFor(org.springframework.data.release.model.TrainIteration, boolean) + */ @Override + @Cacheable("tickets") public Tickets getTicketsFor(TrainIteration trainIteration, boolean forCurrentUser) { JqlQuery query = JqlQuery @@ -208,7 +226,7 @@ class Jira implements JiraConnector { JiraVersion jiraVersion = new JiraVersion(moduleIteration); logger.log(moduleIteration, "Creating Jira release version %s", jiraVersion); - JiraReleaseVersion jiraReleaseVersion = new JiraReleaseVersion(moduleIteration, jiraVersion); + JiraReleaseVersion jiraReleaseVersion = JiraReleaseVersion.of(moduleIteration, jiraVersion); operations.exchange(VERSIONS_TEMPLATE, HttpMethod.POST, new HttpEntity(jiraReleaseVersion, httpHeaders), JiraReleaseVersion.class, parameters).getBody(); @@ -235,6 +253,10 @@ class Jira implements JiraConnector { return versionsForModuleIteration.stream().findFirst(); } + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.IssueTracker#createReleaseTicket(org.springframework.data.release.model.ModuleIteration) + */ @Override public void createReleaseTicket(ModuleIteration moduleIteration) { @@ -250,8 +272,7 @@ class Jira implements JiraConnector { return; } - Optional jiraReleaseVersion = findJiraReleaseVersion(moduleIteration); - jiraReleaseVersion.orElseThrow( + findJiraReleaseVersion(moduleIteration).orElseThrow( () -> new IllegalStateException(String.format("Did not find a release version for %s", moduleIteration))); JiraComponents jiraComponents = getJiraComponents(moduleIteration.getProjectKey()); @@ -264,6 +285,10 @@ class Jira implements JiraConnector { CreatedJiraIssue.class, parameters).getBody(); } + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.JiraConnector#assignTicketToMe(org.springframework.data.release.jira.Ticket) + */ @Override public void assignTicketToMe(Ticket ticket) { @@ -280,19 +305,16 @@ class Jira implements JiraConnector { String.class, parameters).getBody(); } - private JiraIssue prepareJiraIssueToCreate(ModuleIteration moduleIteration, JiraComponents jiraComponents) { + /* + * (non-Javadoc) + * @see org.springframework.data.release.jira.IssueTracker#assignReleaseTicketToMe(org.springframework.data.release.model.ModuleIteration) + */ + @Override + public Ticket assignReleaseTicketToMe(ModuleIteration module) { - JiraIssue jiraIssue = JiraIssue.createTask(); - jiraIssue.project(moduleIteration.getProjectKey()).summary(Tracker.releaseTicketSummary(moduleIteration)) - .fixVersion(moduleIteration); - - Fields fields = jiraIssue.getFields(); - - Optional component = jiraComponents.findComponent(INFRASTRUCTURE_COMPONENT_NAME); - component.ifPresent( - jiraComponent -> fields.setComponents(Collections.singletonList(Component.from(jiraComponent.getName())))); - - return jiraIssue; + Ticket ticket = getReleaseTicketFor(module); + assignTicketToMe(ticket); + return ticket; } /* @@ -304,8 +326,8 @@ class Jira implements JiraConnector { // for each module for (ModuleIteration moduleIteration : trainIteration) { - Tickets tickets = getTicketsFor(moduleIteration); + Tickets tickets = getTicketsFor(moduleIteration); Ticket releaseTicket = tickets.getReleaseTicket(moduleIteration); if (releaseTicket.isResolved()) { @@ -366,7 +388,7 @@ class Jira implements JiraConnector { Tickets tickets = issues.stream().map(this::toTicket).collect(Tickets.toTicketsCollector()); logger.log(moduleIteration, "Created changelog with %s entries.", tickets.getOverallTotal()); - return new Changelog(moduleIteration, tickets); + return Changelog.of(moduleIteration, tickets); } /* @@ -391,6 +413,21 @@ class Jira implements JiraConnector { return JiraComponents.of(components); } + private JiraIssue prepareJiraIssueToCreate(ModuleIteration moduleIteration, JiraComponents jiraComponents) { + + JiraIssue jiraIssue = JiraIssue.createTask(); + jiraIssue.project(moduleIteration.getProjectKey()).summary(Tracker.releaseTicketSummary(moduleIteration)) + .fixVersion(moduleIteration); + + Fields fields = jiraIssue.getFields(); + + Optional component = jiraComponents.findComponent(INFRASTRUCTURE_COMPONENT_NAME); + component.ifPresent( + jiraComponent -> fields.setComponents(Collections.singletonList(Component.of(jiraComponent.getName())))); + + return jiraIssue; + } + private JiraIssues execute(String context, JqlQuery query, HttpHeaders headers, JiraIssuesCallback callback) { JiraIssues issues; @@ -458,15 +495,16 @@ class Jira implements JiraConnector { private Ticket toTicket(JiraIssue issue) { - JiraIssue.Fields fields = issue.getFields(); - + Fields fields = issue.getFields(); JiraTicketStatus jiraTicketStatus; - if (fields.getStatus() != null && fields.getResolution() != null) { - JiraIssue.Status status = fields.getStatus(); - boolean resolved = status.getStatusCategory().getKey().equals("done"); - JiraIssue.Resolution resolution = fields.getResolution(); - jiraTicketStatus = new JiraTicketStatus(resolved, status.getName(), resolution.getName()); + if (fields.hasStatusAndResolution()) { + + Status status = fields.getStatus(); + boolean resolved = status.getStatusCategory().getKey().equals("done"); + Resolution resolution = fields.getResolution(); + + jiraTicketStatus = JiraTicketStatus.of(resolved, status.getName(), resolution.getName()); } else { jiraTicketStatus = JiraTicketStatus.UNKNOWN; } @@ -486,24 +524,9 @@ class Jira implements JiraConnector { return headers; } - public static void main(String[] args) { - - try (ConfigurableApplicationContext context = SpringApplication.run(Application.class, args)) { - - JiraConnector tracker = context.getBean(JiraConnector.class); - TrainIteration iteration = new TrainIteration(ReleaseTrains.GOSLING, Iteration.SR1); - ModuleIteration module = iteration.getModule("JPA"); - - // Changelog changelog = tracker.getChangelogFor(module); - // System.out.println(changelog); - - System.out.println(tracker.getReleaseTicketFor(module)); - } - } - private Map newUrlTemplateVariables() { Map parameters = new HashMap<>(); - parameters.put("jiraBaseUrl", jiraProperties.getUrl()); + parameters.put("jiraBaseUrl", jiraProperties.getApiUrl()); return parameters; } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraComponent.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraComponent.java similarity index 70% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraComponent.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraComponent.java index d41fdf0..cdd066d 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraComponent.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraComponent.java @@ -13,30 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -package org.springframework.data.release.jira; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; +package org.springframework.data.release.issues.jira; import lombok.Value; -/* +/** * Value object to bind REST responses to. * * @author Mark Paluch + * @author Oliver Gierke */ @Value class JiraComponent { - private String id; - private String name; - - @JsonCreator - public JiraComponent(@JsonProperty("id") String id, @JsonProperty("name") String name) { - this.id = id; - this.name = name; - } + String id, name; public boolean hasName(String name) { return this.name.equals(name); diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraComponents.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraComponents.java similarity index 71% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraComponents.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraComponents.java index c3285b7..b803bcc 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraComponents.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraComponents.java @@ -14,28 +14,25 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; + +import lombok.NonNull; +import lombok.Value; import java.util.Collection; import java.util.Iterator; import java.util.Optional; -import org.springframework.util.Assert; - -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NonNull; - -/* +/** * Value object to represent a list of {@link JiraComponent}s. + * * @author Mark Paluch + * @author Oliver Gierke */ -@Data -@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Value(staticConstructor = "of") class JiraComponents implements Iterable { - @NonNull private Collection jiraComponents; + @NonNull Collection jiraComponents; /** * Try to find a component by its {@code name}. @@ -47,12 +44,10 @@ class JiraComponents implements Iterable { return jiraComponents.stream().filter(jiraComponent -> jiraComponent.hasName(name)).findFirst(); } - public static JiraComponents of(Collection jiraComponents) { - - Assert.notNull(jiraComponents, "JiraComponents must not be null!"); - return new JiraComponents(jiraComponents); - } - + /* + * (non-Javadoc) + * @see java.lang.Iterable#iterator() + */ @Override public Iterator iterator() { return jiraComponents.iterator(); diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraConnector.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraConnector.java similarity index 76% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraConnector.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraConnector.java index 7137581..61a9f0f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraConnector.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraConnector.java @@ -13,10 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; import java.util.Optional; +import org.springframework.data.release.issues.IssueTracker; +import org.springframework.data.release.issues.Tickets; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.TrainIteration; @@ -24,32 +26,28 @@ import org.springframework.data.release.model.TrainIteration; * @author Oliver Gierke * @author Mark Paluch */ -public interface JiraConnector extends IssueTracker { +interface JiraConnector extends IssueTracker { /** * Verifies the state of all {@link Tickets} before releasing. In particular: Check whether the release ticket exists, * check whether all other issue tickets are in a resolved state. * - * @param iteration + * @param iteration must not be {@literal null}. */ void verifyBeforeRelease(TrainIteration iteration); + /** + * Closes the given {@link TrainIteration}. + * + * @param iteration must not be {@literal null}. + */ void closeIteration(TrainIteration iteration); /** - * Lookup a Jira release version. + * Lookup a JIRA release version. * * @param moduleIteration must not be {@literal null}. * @return */ Optional findJiraReleaseVersion(ModuleIteration moduleIteration); - - /** - * Assigns the ticket to the current user. - * - * @param ticket must not be {@literal null}. - * @param credentials must not be {@literal null}. - */ - void assignTicketToMe(Ticket ticket); - } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraIssue.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraIssue.java similarity index 77% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraIssue.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraIssue.java index 9adfc4f..b92a59a 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraIssue.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraIssue.java @@ -13,69 +13,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; + +import lombok.Data; +import lombok.Value; import java.util.Collections; import java.util.List; +import org.springframework.data.release.issues.Ticket; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ProjectKey; import org.springframework.data.release.model.Tracker; import org.springframework.data.release.model.Train; import org.springframework.util.Assert; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - /** * Value object to bind REST responses to. * * @author Oliver Gierke * @author Mark Paluch */ -@Data +@Value class JiraIssue { - private String key; - private Fields fields; - - /** - * Returns whether the ticket is only fixed in the given {@link Train}. {@literal false} indicates the {@link Ticket} - * has been resolved for - * - * @param train - * @return - */ - public boolean wasBackportedFrom(Train train) { - - List fixVersions = fields.getFixVersions(); - return fixVersions != null && wasBackportedFrom(train, fixVersions); - } - - private boolean wasBackportedFrom(Train train, List fixVersions) { - return fixVersions.size() > 1 && isPresent(train, fixVersions); - } - - private boolean isPresent(Train train, List fixVersions) { - return fixVersions.stream().// - filter(fixVersion -> fixVersion.isTrain(train)).// - findFirst().// - isPresent(); - } - - /** - * Returns whether the ticket is a release ticket. - * - * @param moduleIteration - * @return - */ - public boolean isReleaseTicket(ModuleIteration moduleIteration) { - - List fixVersions = fields.getFixVersions(); - return fixVersions.size() == 1 && isPresent(moduleIteration.getTrain(), fixVersions) - && fields.hasSummary(Tracker.releaseTicketSummary(moduleIteration)); - } + String key; + Fields fields; /** * Creates a new Jira issue value object. @@ -83,10 +46,7 @@ class JiraIssue { * @return */ public static JiraIssue create() { - - JiraIssue jiraIssue = new JiraIssue(); - jiraIssue.setFields(new Fields()); - return jiraIssue; + return new JiraIssue(null, new Fields()); } /** @@ -100,6 +60,32 @@ class JiraIssue { return jiraIssue; } + /** + * Returns whether the ticket is only fixed in the given {@link Train}. {@literal false} indicates the {@link Ticket} + * has been resolved for + * + * @param train + * @return + */ + public boolean wasBackportedFrom(Train train) { + + List fixVersions = fields.getFixVersions(); + return fixVersions != null && wasBackportedFrom(train, fixVersions); + } + + /** + * Returns whether the ticket is a release ticket. + * + * @param moduleIteration + * @return + */ + public boolean isReleaseTicket(ModuleIteration moduleIteration) { + + List fixVersions = fields.getFixVersions(); + return fixVersions.size() == 1 && isPresent(moduleIteration.getTrain(), fixVersions) + && fields.hasSummary(Tracker.releaseTicketSummary(moduleIteration)); + } + /** * Assign to the user specified in {@link Credentials}. * @@ -131,7 +117,7 @@ class JiraIssue { */ public JiraIssue project(ProjectKey projectKey) { - getFields().setProject(new Project(projectKey)); + getFields().setProject(Project.from(projectKey)); return this; } @@ -156,18 +142,29 @@ class JiraIssue { public JiraIssue fixVersion(ModuleIteration moduleIteration) { Assert.notNull(moduleIteration, "ModuleIteration must not be null!"); - getFields().setFixVersions(Collections.singletonList(new JiraVersion(moduleIteration).toFixVersions())); + getFields().setFixVersions(Collections.singletonList(new JiraVersion(moduleIteration).toFixVersion())); return this; } + private static boolean wasBackportedFrom(Train train, List fixVersions) { + return fixVersions.size() > 1 && isPresent(train, fixVersions); + } + + private static boolean isPresent(Train train, List fixVersions) { + return fixVersions.stream().// + filter(fixVersion -> fixVersion.isTrain(train)).// + findFirst().// + isPresent(); + } + @Data static class Fields { Project project; IssueType issuetype; String summary; - List fixVersions; + List fixVersions; List components; Status status; Resolution resolution; @@ -176,33 +173,31 @@ class JiraIssue { public boolean hasSummary(String other) { return summary.equals(other); } + + public boolean hasStatusAndResolution() { + return status != null && resolution != null; + } } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class Component { - String id; - String name; + String id, name; - public static Component from(String name) { + public static Component of(String name) { Assert.hasText(name, "Name must not be empty!"); return new Component(null, name); } } - @Data - @NoArgsConstructor - @AllArgsConstructor - static class FixVersions { + @Value + static class FixVersion { - String id; - String name; + String id, name; /** - * Returns whether this {@link FixVersions} matches the given {@link Train}. + * Returns whether this {@link FixVersion} matches the given {@link Train}. * * @param train * @return @@ -212,9 +207,7 @@ class JiraIssue { } } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class IssueType { public final static IssueType TASK = new IssueType("Task"); @@ -222,50 +215,39 @@ class JiraIssue { String name; } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class Status { String name; StatusCategory statusCategory; } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class Project { String key; - public Project(ProjectKey projectKey) { - this.key = projectKey.getKey(); + public static Project from(ProjectKey projectKey) { + return new Project(projectKey.getKey()); } } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class Resolution { String name; } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class StatusCategory { String key; } - @Data - @NoArgsConstructor - @AllArgsConstructor + @Value static class JiraUser { - String name; - String displayName; + String name, displayName; static JiraUser from(String username) { return new JiraUser(username, null); diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraIssues.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraIssues.java similarity index 75% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraIssues.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraIssues.java index 3413527..47fbfaf 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraIssues.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraIssues.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,26 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; +import lombok.Getter; +import lombok.Value; + +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.springframework.data.release.Streamable; -import lombok.Data; - /** * @author Oliver Gierke */ -@Data +@Value class JiraIssues implements Streamable { - private int startAt; - private int maxResults; - private int total; - - private List issues; + int startAt, maxResult; + @Getter int total; + List issues = new ArrayList<>(); public int getNextStartAt() { return startAt + issues.size(); @@ -42,6 +42,10 @@ class JiraIssues implements Streamable { return startAt + issues.size() < total; } + public boolean hasIssues() { + return !issues.isEmpty(); + } + /* * (non-Javadoc) * @see java.lang.Iterable#iterator() diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraProperties.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraProperties.java similarity index 88% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraProperties.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraProperties.java index c4ac05c..bf8c71f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraProperties.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraProperties.java @@ -14,7 +14,11 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; + +import lombok.AccessLevel; +import lombok.Data; +import lombok.Getter; import javax.annotation.PostConstruct; @@ -22,12 +26,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.util.Assert; -import lombok.AccessLevel; -import lombok.Data; -import lombok.Getter; - /** - * Configurable properties for Git. + * Configurable properties for JIRA. * * @author Mark Paluch */ @@ -37,14 +37,14 @@ import lombok.Getter; class JiraProperties { private @Getter(AccessLevel.PRIVATE) String password; - private String username, url; + private String username, apiUrl; @PostConstruct public void init() { Assert.hasText(username, "No Jira username (jira.username) configured!"); Assert.hasText(password, "No Jira password (jira.password) configured!"); - Assert.hasText(url, "No Jira url (jira.url) configured!"); + Assert.hasText(apiUrl, "No Jira url (jira.api-url) configured!"); } /** @@ -55,5 +55,4 @@ class JiraProperties { public Credentials getCredentials() { return new Credentials(username, password); } - } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraReleaseVersion.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraReleaseVersion.java similarity index 55% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraReleaseVersion.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraReleaseVersion.java index 7ce3942..fa2b164 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraReleaseVersion.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraReleaseVersion.java @@ -14,46 +14,30 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; -import lombok.Data; +import lombok.Value; import org.springframework.data.release.model.ModuleIteration; import org.springframework.util.Assert; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - /** * Value object to bind REST responses to. * * @author Mark Paluch */ -@Data -public class JiraReleaseVersion { +@Value +class JiraReleaseVersion { - private String id; - private String name; - private String project; - private String description; + String id, name, project, description; - @JsonCreator - public JiraReleaseVersion(@JsonProperty("id") String id, @JsonProperty("name") String name, - @JsonProperty("string") String project, @JsonProperty("description") String description) { - this.id = id; - this.name = name; - this.project = project; - this.description = description; - } - - public JiraReleaseVersion(ModuleIteration moduleIteration, JiraVersion jiraVersion) { + public static JiraReleaseVersion of(ModuleIteration moduleIteration, JiraVersion jiraVersion) { Assert.notNull(moduleIteration, "ModuleIteration must not be null."); Assert.notNull(jiraVersion, "JiraVersion must not be null."); - project = moduleIteration.getProjectKey().getKey(); - name = jiraVersion.toString(); - description = jiraVersion.getDescription(); + return new JiraReleaseVersion(null, jiraVersion.toString(), moduleIteration.getProjectKey().getKey(), + jiraVersion.getDescription()); } public boolean hasSameNameAs(JiraVersion jiraVersion) { diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraReleaseVersions.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraReleaseVersions.java similarity index 85% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraReleaseVersions.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraReleaseVersions.java index 75b1c60..8694603 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraReleaseVersions.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraReleaseVersions.java @@ -13,28 +13,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; +import lombok.Value; + +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.springframework.data.release.Streamable; -import lombok.Data; - /** * Value object to bind REST responses to. * * @author Mark Paluch */ -@Data +@Value class JiraReleaseVersions implements Streamable { - private int startAt; - private int maxResults; - private int total; - - private List values; + int startAt, maxResults, total; + List values = new ArrayList<>(); public int getNextStartAt() { return startAt + values.size(); diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraTicketStatus.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraTicketStatus.java similarity index 70% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraTicketStatus.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraTicketStatus.java index 3ba953b..5cbb88b 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraTicketStatus.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraTicketStatus.java @@ -14,21 +14,25 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; -import lombok.RequiredArgsConstructor; +import lombok.NonNull; +import lombok.Value; + +import org.springframework.data.release.issues.TicketStatus; /** * @author Mark Paluch + * @author Oliver Gierke */ -@RequiredArgsConstructor -public class JiraTicketStatus implements TicketStatus { +@Value(staticConstructor = "of") +class JiraTicketStatus implements TicketStatus { - public static final JiraTicketStatus UNKNOWN = new JiraTicketStatus(false, "unknown", null); + public static final JiraTicketStatus UNKNOWN = JiraTicketStatus.of(false, "unknown", null); - private final boolean resolved; - private final String status; - private final String resolution; + boolean resolved; + @NonNull String status; + String resolution; /* * (non-Javadoc) diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JiraVersion.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraVersion.java similarity index 81% rename from release-tools/src/main/java/org/springframework/data/release/jira/JiraVersion.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraVersion.java index 99a761d..dd2169a 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JiraVersion.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JiraVersion.java @@ -13,20 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; - -import org.springframework.data.release.jira.JiraIssue.FixVersions; -import org.springframework.data.release.model.ModuleIteration; +package org.springframework.data.release.issues.jira; import lombok.Value; +import org.springframework.data.release.issues.jira.JiraIssue.FixVersion; +import org.springframework.data.release.model.ModuleIteration; + /** * @author Oliver Gierke */ @Value class JiraVersion { - private ModuleIteration module; + ModuleIteration module; /* * (non-Javadoc) @@ -41,7 +41,7 @@ class JiraVersion { return module.getTrain().getName() + " " + module.getIteration().getName(); } - public FixVersions toFixVersions() { - return new FixVersions(null, toString()); + public FixVersion toFixVersion() { + return new FixVersion(null, toString()); } } diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/JqlQuery.java b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JqlQuery.java similarity index 83% rename from release-tools/src/main/java/org/springframework/data/release/jira/JqlQuery.java rename to release-tools/src/main/java/org/springframework/data/release/issues/jira/JqlQuery.java index 40d0b26..95ef22f 100644 --- a/release-tools/src/main/java/org/springframework/data/release/jira/JqlQuery.java +++ b/release-tools/src/main/java/org/springframework/data/release/issues/jira/JqlQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; + +import lombok.Value; import java.util.ArrayList; import java.util.Collection; @@ -22,10 +24,9 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.springframework.data.release.model.ModuleIteration; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; -import lombok.Value; - /** * @author Oliver Gierke * @author Mark Paluch @@ -38,16 +39,16 @@ class JqlQuery { private final String query; - public JqlQuery and(String clause) { - return new JqlQuery(String.format("(%s) AND %s", query, clause)); - } - - public JqlQuery orderBy(String orderBy) { - return new JqlQuery(String.format("%s ORDER BY %s", query, orderBy)); - } - + /** + * Creates a new {@link JqlQuery} for the given {@link ModuleIteration}. + * + * @param iteration must not be {@literal null}. + * @return + */ public static JqlQuery from(ModuleIteration iteration) { + Assert.notNull(iteration, "Module iteration must not be null!"); + JiraVersion version = new JiraVersion(iteration); return new JqlQuery(String.format(PROJECT_VERSION_TEMPLATE, iteration.getProjectKey(), version)); @@ -72,6 +73,18 @@ class JqlQuery { return new JqlQuery(StringUtils.collectionToDelimitedString(parts, " OR ")); } + public JqlQuery and(String clause) { + return new JqlQuery(String.format("(%s) AND %s", query, clause)); + } + + public JqlQuery orderBy(String orderBy) { + return new JqlQuery(String.format("%s ORDER BY %s", query, orderBy)); + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ @Override public String toString() { return query; diff --git a/release-tools/src/main/java/org/springframework/data/release/jira/GitHubIssue.java b/release-tools/src/main/java/org/springframework/data/release/jira/GitHubIssue.java deleted file mode 100644 index 6a9c211..0000000 --- a/release-tools/src/main/java/org/springframework/data/release/jira/GitHubIssue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.release.jira; - -import org.springframework.data.release.model.ModuleIteration; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import lombok.Value; - -/** - * @author Oliver Gierke - * @author Mark Paluch - */ -@Value -class GitHubIssue { - - private String number; - private String title; - private String state; - private Object milestone; - - @JsonCreator - public GitHubIssue(@JsonProperty("number") String number, @JsonProperty("title") String title, - @JsonProperty("state") String state, @JsonProperty("milestone") Object milestone) { - this.number = number; - this.title = title; - this.state = state; - this.milestone = milestone; - } - - public GitHubIssue(String title, Milestone milestone) { - - this.title = title; - this.milestone = milestone.getNumber(); - this.number = null; - this.state = null; - } - - public String getId() { - - if (number == null) { - return null; - } - return "#".concat(number); - } - - /** - * @author Oliver Gierke - * @author Mark Paluch - */ - @Value - static class Milestone { - - private final String title; - private final Long number; - private final String description; - - @JsonCreator - public Milestone(@JsonProperty("title") String title, @JsonProperty("number") Long number, - @JsonProperty("description") String description) { - this.title = title; - this.number = number; - this.description = description; - } - - public Milestone(String title, String description) { - this.number = null; - this.title = title; - this.description = description; - } - - public boolean matchesIteration(ModuleIteration moduleIteration) { - return title.contains(moduleIteration.getShortVersionString()); - } - } -} diff --git a/release-tools/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java b/release-tools/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java index b270720..222e286 100644 --- a/release-tools/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java +++ b/release-tools/src/main/java/org/springframework/data/release/misc/ReleaseOperations.java @@ -24,8 +24,8 @@ import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.git.GitOperations; import org.springframework.data.release.io.Workspace; -import org.springframework.data.release.jira.Changelog; -import org.springframework.data.release.jira.IssueTracker; +import org.springframework.data.release.issues.Changelog; +import org.springframework.data.release.issues.IssueTracker; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Project; diff --git a/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java b/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java index 4708427..3f0598a 100644 --- a/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java +++ b/release-tools/src/main/java/org/springframework/data/release/utils/ExecutionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.data.release.utils; import java.util.Collection; import java.util.concurrent.CompletableFuture; import java.util.function.Function; +import java.util.stream.Collector; import java.util.stream.Collectors; import org.springframework.data.release.Streamable; @@ -62,16 +63,22 @@ public class ExecutionUtils { * @return */ public static Collection runAndReturn(Streamable streamable, Function function) { + return runAndReturn(streamable, function, Collectors.toList()); + } + + public static R runAndReturn(Streamable streamable, Function function, + Collector collector) { Assert.notNull(streamable, "Iterable must not be null!"); Assert.notNull(function, "Consumer must not be null!"); return streamable.stream().// map(it -> CompletableFuture.supplyAsync(() -> function.apply(it))).// + filter(it -> it != null).// collect(Collectors.toList()).// stream().// map(future -> future.join()).// - collect(Collectors.toList()); + collect(collector); } public static interface ConsumerWithException { diff --git a/release-tools/src/main/resources/application.properties b/release-tools/src/main/resources/application.properties index 08e8d40..7def374 100644 --- a/release-tools/src/main/resources/application.properties +++ b/release-tools/src/main/resources/application.properties @@ -1,7 +1,7 @@ io.work-dir=~/temp/spring-data-shell/workspace # Maven setup -maven.localRepository=~/temp/spring-data-shell/repository +maven.local-repository=~/temp/spring-data-shell/repository maven.plugins.versions=org.codehaus.mojo:versions-maven-plugin:2.2 deployment.server.uri=https://repo.spring.io @@ -12,4 +12,10 @@ deployment.username=buildmaster # GPG setup deployment.gpg.executable=/usr/local/bin/gpg2 # deployment.gpg.keyname -# deployment.gpg.password \ No newline at end of file +# deployment.gpg.password + +# JIRA +jira.api-url=https://jira.spring.io + +# GitHub +github.api-url=https://api.github.com \ No newline at end of file diff --git a/release-tools/src/test/java/org/springframework/data/release/build/MavenIntegrationTests.java b/release-tools/src/test/java/org/springframework/data/release/build/MavenIntegrationTests.java index aaa8d8e..177d9d1 100644 --- a/release-tools/src/test/java/org/springframework/data/release/build/MavenIntegrationTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/build/MavenIntegrationTests.java @@ -30,7 +30,6 @@ import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Projects; import org.springframework.data.release.model.ReleaseTrains; import org.springframework.data.release.model.TrainIteration; -import org.springframework.data.release.model.UpdateInformation; import org.xmlbeam.ProjectionFactory; import org.xmlbeam.io.XBFileIO; @@ -75,7 +74,7 @@ public class MavenIntegrationTests extends AbstractIntegrationTests { TrainIteration iteration = new TrainIteration(ReleaseTrains.HOPPER, Iteration.M1); ModuleIteration build = iteration.getModule(Projects.BUILD); - UpdateInformation information = new UpdateInformation(iteration, Phase.PREPARE); + UpdateInformation information = UpdateInformation.of(iteration, Phase.PREPARE); maven.updateProjectDescriptors(build, information); maven.prepareVersion(build, Phase.PREPARE); diff --git a/release-tools/src/test/java/org/springframework/data/release/model/UpdateInformationUnitTests.java b/release-tools/src/test/java/org/springframework/data/release/build/UpdateInformationUnitTests.java similarity index 66% rename from release-tools/src/test/java/org/springframework/data/release/model/UpdateInformationUnitTests.java rename to release-tools/src/test/java/org/springframework/data/release/build/UpdateInformationUnitTests.java index 5284f7d..247794a 100644 --- a/release-tools/src/test/java/org/springframework/data/release/model/UpdateInformationUnitTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/build/UpdateInformationUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.model; +package org.springframework.data.release.build; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; @@ -21,6 +21,11 @@ import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Test; +import org.springframework.data.release.model.Iteration; +import org.springframework.data.release.model.Phase; +import org.springframework.data.release.model.Projects; +import org.springframework.data.release.model.ReleaseTrains; +import org.springframework.data.release.model.TrainIteration; /** * Unit tests for {@link UpdateInformation}. @@ -33,17 +38,17 @@ public class UpdateInformationUnitTests { @Test(expected = IllegalArgumentException.class) public void rejectsNullTrainIteration() { - new UpdateInformation(null, Phase.CLEANUP); + UpdateInformation.of(null, Phase.CLEANUP); } @Test(expected = IllegalArgumentException.class) public void rejectsNullPhase() { - new UpdateInformation(hopperM1, null); + UpdateInformation.of(hopperM1, null); } @Test public void exposesMilestoneRepositoryForMilestone() { - assertThat(new UpdateInformation(hopperM1, Phase.PREPARE).getRepository().getId(), is("spring-libs-milestone")); + assertThat(UpdateInformation.of(hopperM1, Phase.PREPARE).getRepository().getId(), is("spring-libs-milestone")); } @Test @@ -51,7 +56,7 @@ public class UpdateInformationUnitTests { Arrays.asList(Iteration.GA, Iteration.SR1).forEach(iteration -> { TrainIteration trainIteration = new TrainIteration(ReleaseTrains.HOPPER, iteration); - assertThat(new UpdateInformation(trainIteration, Phase.PREPARE).getRepository().getId(), + assertThat(UpdateInformation.of(trainIteration, Phase.PREPARE).getRepository().getId(), is("spring-libs-release")); }); } @@ -59,10 +64,10 @@ public class UpdateInformationUnitTests { @Test public void calculatesProjectVersionToSetCorrectly() { - UpdateInformation updateInformation = new UpdateInformation(hopperM1, Phase.PREPARE); + UpdateInformation updateInformation = UpdateInformation.of(hopperM1, Phase.PREPARE); assertThat(updateInformation.getProjectVersionToSet(Projects.JPA).toString(), is("1.10.0.M1")); - updateInformation = new UpdateInformation(hopperM1, Phase.CLEANUP); + updateInformation = UpdateInformation.of(hopperM1, Phase.CLEANUP); assertThat(updateInformation.getProjectVersionToSet(Projects.JPA).toString(), is("1.10.0.BUILD-SNAPSHOT")); } } diff --git a/release-tools/src/test/java/org/springframework/data/release/jira/GitHubIssueTrackerIntegrationTests.java b/release-tools/src/test/java/org/springframework/data/release/issues/github/GitHubIssueTrackerIntegrationTests.java similarity index 90% rename from release-tools/src/test/java/org/springframework/data/release/jira/GitHubIssueTrackerIntegrationTests.java rename to release-tools/src/test/java/org/springframework/data/release/issues/github/GitHubIssueTrackerIntegrationTests.java index f4167e7..1fbcbf0 100644 --- a/release-tools/src/test/java/org/springframework/data/release/jira/GitHubIssueTrackerIntegrationTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/issues/github/GitHubIssueTrackerIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.github; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.*; @@ -25,25 +25,31 @@ import java.util.Arrays; import java.util.Collection; import org.hamcrest.Matchers; +import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.AbstractIntegrationTests; +import org.springframework.data.release.issues.Ticket; +import org.springframework.data.release.issues.github.GitHub; +import org.springframework.data.release.issues.github.GitHubProperties; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.Projects; import org.springframework.data.release.model.ReleaseTrains; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; import com.github.tomakehurst.wiremock.common.ClasspathFileSource; import com.github.tomakehurst.wiremock.junit.WireMockRule; /** - * Integration Tests for {@link GitHubIssueTracker} using a local {@link WireMockRule} server. + * Integration Tests for {@link GitHub} using a local {@link WireMockRule} server. * * @author Mark Paluch */ @@ -59,11 +65,17 @@ public class GitHubIssueTrackerIntegrationTests extends AbstractIntegrationTests @Rule public ExpectedException expectedException = ExpectedException.none(); - @Autowired IssueTracker github; + @Autowired GitHub github; + @Autowired GitHubProperties properties; @Before public void before() throws Exception { + + UriComponents uriComponents = UriComponentsBuilder.fromUriString(properties.getApiUrl()).build(); + Assume.assumeThat(uriComponents.getHost(), is("localhost")); + github.reset(); + } /** diff --git a/release-tools/src/test/java/org/springframework/data/release/jira/GithubMilestoneUnitTests.java b/release-tools/src/test/java/org/springframework/data/release/issues/github/GithubMilestoneUnitTests.java similarity index 95% rename from release-tools/src/test/java/org/springframework/data/release/jira/GithubMilestoneUnitTests.java rename to release-tools/src/test/java/org/springframework/data/release/issues/github/GithubMilestoneUnitTests.java index 4260219..c76139e 100644 --- a/release-tools/src/test/java/org/springframework/data/release/jira/GithubMilestoneUnitTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/issues/github/GithubMilestoneUnitTests.java @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.github; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import org.junit.Test; +import org.springframework.data.release.issues.github.GithubMilestone; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ReleaseTrains; diff --git a/release-tools/src/test/java/org/springframework/data/release/jira/JiraComponentsUnitTests.java b/release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraComponentsUnitTests.java similarity index 90% rename from release-tools/src/test/java/org/springframework/data/release/jira/JiraComponentsUnitTests.java rename to release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraComponentsUnitTests.java index edf5092..24eced6 100644 --- a/release-tools/src/test/java/org/springframework/data/release/jira/JiraComponentsUnitTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraComponentsUnitTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; import static org.hamcrest.core.Is.*; import static org.junit.Assert.*; @@ -22,6 +22,8 @@ import static org.junit.Assert.*; import java.util.Collections; import org.junit.Test; +import org.springframework.data.release.issues.jira.JiraComponent; +import org.springframework.data.release.issues.jira.JiraComponents; /** * Unit tests for {@link JiraComponents}. diff --git a/release-tools/src/test/java/org/springframework/data/release/jira/JiraIntegrationTests.java b/release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraConnectorIntegrationTests.java similarity index 92% rename from release-tools/src/test/java/org/springframework/data/release/jira/JiraIntegrationTests.java rename to release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraConnectorIntegrationTests.java index 6b55437..6a4090a 100644 --- a/release-tools/src/test/java/org/springframework/data/release/jira/JiraIntegrationTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraConnectorIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.*; @@ -26,12 +26,18 @@ import java.util.Collection; import java.util.Optional; import org.hamcrest.Matchers; +import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.release.AbstractIntegrationTests; +import org.springframework.data.release.issues.Ticket; +import org.springframework.data.release.issues.jira.Jira; +import org.springframework.data.release.issues.jira.JiraConnector; +import org.springframework.data.release.issues.jira.JiraProperties; +import org.springframework.data.release.issues.jira.JiraReleaseVersion; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ProjectKey; @@ -39,6 +45,8 @@ import org.springframework.data.release.model.Projects; import org.springframework.data.release.model.ReleaseTrains; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; import com.github.tomakehurst.wiremock.common.ClasspathFileSource; @@ -49,7 +57,7 @@ import com.github.tomakehurst.wiremock.junit.WireMockRule; * * @author Mark Paluch */ -public class JiraIntegrationTests extends AbstractIntegrationTests { +public class JiraConnectorIntegrationTests extends AbstractIntegrationTests { public static final String CREATE_ISSUE_URI = "/rest/api/2/issue"; public static final String CREATE_VERSION_URI = "/rest/api/2/version"; @@ -64,9 +72,14 @@ public class JiraIntegrationTests extends AbstractIntegrationTests { @Rule public ExpectedException expectedException = ExpectedException.none(); @Autowired JiraConnector jira; + @Autowired JiraProperties properties; @Before public void before() throws Exception { + + UriComponents uriComponents = UriComponentsBuilder.fromUriString(properties.getApiUrl()).build(); + Assume.assumeThat(uriComponents.getHost(), is("localhost")); + jira.reset(); } diff --git a/release-tools/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java b/release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraVersionUnitTests.java similarity index 95% rename from release-tools/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java rename to release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraVersionUnitTests.java index 2c02e09..afbe1b8 100644 --- a/release-tools/src/test/java/org/springframework/data/release/jira/JiraVersionUnitTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/issues/jira/JiraVersionUnitTests.java @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import org.junit.Test; +import org.springframework.data.release.issues.jira.JiraVersion; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ReleaseTrains; diff --git a/release-tools/src/test/java/org/springframework/data/release/jira/TicketsUnitTests.java b/release-tools/src/test/java/org/springframework/data/release/issues/jira/TicketsUnitTests.java similarity index 93% rename from release-tools/src/test/java/org/springframework/data/release/jira/TicketsUnitTests.java rename to release-tools/src/test/java/org/springframework/data/release/issues/jira/TicketsUnitTests.java index 424eb0e..e981326 100644 --- a/release-tools/src/test/java/org/springframework/data/release/jira/TicketsUnitTests.java +++ b/release-tools/src/test/java/org/springframework/data/release/issues/jira/TicketsUnitTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.data.release.jira; +package org.springframework.data.release.issues.jira; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; @@ -23,6 +23,9 @@ import static org.springframework.test.util.AssertionErrors.fail; import java.util.Collections; import org.junit.Test; +import org.springframework.data.release.issues.Ticket; +import org.springframework.data.release.issues.Tickets; +import org.springframework.data.release.issues.jira.JiraTicketStatus; import org.springframework.data.release.model.Iteration; import org.springframework.data.release.model.ReleaseTrains; @@ -93,5 +96,4 @@ public class TicketsUnitTests { .getReleaseTickets(ReleaseTrains.HOPPER.getModuleIteration(Iteration.GA, "JPA").getTrainIteration()); assertThat(result.getTickets().contains(ticket), is(true)); } - } diff --git a/release-tools/src/test/resources/application-test.properties b/release-tools/src/test/resources/application-test.properties index 4dfd272..8acb6a1 100644 --- a/release-tools/src/test/resources/application-test.properties +++ b/release-tools/src/test/resources/application-test.properties @@ -2,11 +2,12 @@ logging.level.org.springframework=WARN logging.level.org.springframework.data.release=INFO logging.level.org.springframework.web.client=TRACE +logging.level.org.springframework.http=DEBUG # Deployment deployment.repository-prefix=test- jira.username=dummy jira.password=dummy -jira.url=http://localhost:8888 -github.api.url=http://localhost:8888 \ No newline at end of file +jira.api-url=http://localhost:8888 +github.api-url=http://localhost:8888 \ No newline at end of file