This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch feature/SLING-8337 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git
commit b4162bf8be940e12cbcc127e7731cb783868a5b5 Author: Robert Munteanu <[email protected]> AuthorDate: Fri Apr 19 11:07:21 2019 +0300 SLING-8364 - Support releases with multiple artifacts Teach Release.fromString to return multiple versions, if found, and adapt the rest of the codebase to that change. --- .gitignore | 1 + .../apache/sling/cli/impl/jira/VersionFinder.java | 13 +++++-- .../cli/impl/release/PrepareVoteEmailCommand.java | 36 +++++++++++++++---- .../org/apache/sling/cli/impl/release/Release.java | 42 +++++++++++++--------- .../sling/cli/impl/release/TallyVotesCommand.java | 13 +++++-- .../cli/impl/release/UpdateLocalSiteCommand.java | 10 ++++-- .../cli/impl/release/UpdateReporterCommand.java | 30 ++++++++-------- .../apache/sling/cli/impl/release/ReleaseTest.java | 38 +++++++++++++++++--- 8 files changed, 132 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index a49f72d..84d2b34 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ docker-env +/target/ diff --git a/src/main/java/org/apache/sling/cli/impl/jira/VersionFinder.java b/src/main/java/org/apache/sling/cli/impl/jira/VersionFinder.java index 7dbcbee..a752be0 100644 --- a/src/main/java/org/apache/sling/cli/impl/jira/VersionFinder.java +++ b/src/main/java/org/apache/sling/cli/impl/jira/VersionFinder.java @@ -21,6 +21,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; import java.util.List; +import java.util.stream.Collectors; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -35,12 +36,14 @@ import com.google.gson.reflect.TypeToken; @Component(service = VersionFinder.class) public class VersionFinder { - public Version find(String versionName) throws IOException { + public Version find(String versionName) { Version version; try (CloseableHttpClient client = HttpClients.createDefault()) { version = findVersion(versionName, client); populateRelatedIssuesCount(client, version); + } catch ( IOException e ) { + throw new RuntimeException(e); } return version; @@ -58,9 +61,13 @@ public class VersionFinder { Gson gson = new Gson(); Type collectionType = TypeToken.getParameterized(List.class, Version.class).getType(); List<Version> versions = gson.fromJson(reader, collectionType); - Release filter = Release.fromString(versionName); + List<String> filter = Release.fromString(versionName) + .stream() + .map( Release::getName ) + .collect(Collectors.toList()); + version = versions.stream() - .filter(v -> filter.equals(Release.fromString(v.getName()))) + .filter(v -> filter.contains(v.getName())) .findFirst() .orElseThrow( () -> new IllegalArgumentException("No version found with name " + versionName)); } diff --git a/src/main/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommand.java b/src/main/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommand.java index 21b72f8..4cc4222 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommand.java +++ b/src/main/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommand.java @@ -17,6 +17,8 @@ package org.apache.sling.cli.impl.release; import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; import org.apache.sling.cli.impl.Command; import org.apache.sling.cli.impl.jira.Version; @@ -44,8 +46,9 @@ public class PrepareVoteEmailCommand implements Command { "\n" + "Hi,\n" + "\n" + - "We solved ##FIXED_ISSUES_COUNT## issues in this release:\n" + - "https://issues.apache.org/jira/browse/SLING/fixforversion/##VERSION_ID##\n" + + "We solved ##FIXED_ISSUES_COUNT## issue(s) in ##RELEASE_OR_RELEASES##:\n" + + "\n" + + "##RELEASE_JIRA_LINKS##\n" + "\n" + "Staging repository:\n" + "https://repository.apache.org/content/repositories/orgapachesling-##RELEASE_ID##/\n" + @@ -68,6 +71,9 @@ public class PrepareVoteEmailCommand implements Command { "##USER_NAME##\n" + "\n"; + private static final String RELEASE_TEMPLATE = + "https://issues.apache.org/jira/browse/SLING/fixforversion/##VERSION_ID##"; + private final Logger logger = LoggerFactory.getLogger(getClass()); @Reference @@ -81,14 +87,30 @@ public class PrepareVoteEmailCommand implements Command { try { int repoId = Integer.parseInt(target); StagingRepository repo = repoFinder.find(repoId); - Release release = Release.fromString(repo.getDescription()); - Version version = versionFinder.find(release.getName()); + List<Release> releases = Release.fromString(repo.getDescription()); + List<Version> versions = releases.stream() + .map( r -> versionFinder.find(r.getName())) + .collect(Collectors.toList()); + + String releaseName = releases.stream() + .map( Release::getFullName ) + .collect(Collectors.joining(", ")); + + int fixedIssueCounts = versions.stream().mapToInt( Version::getIssuesFixedCount).sum(); + String releaseOrReleases = versions.size() > 1 ? + "these releases" : "this release"; + + String releaseJiraLinks = versions.stream() + .map( v -> RELEASE_TEMPLATE.replace("##VERSION_ID##", String.valueOf(v.getId()))) + .collect(Collectors.joining("\n")); + String emailContents = EMAIL_TEMPLATE - .replace("##RELEASE_NAME##", release.getFullName()) + .replace("##RELEASE_NAME##", releaseName) .replace("##RELEASE_ID##", String.valueOf(repoId)) - .replace("##VERSION_ID##", String.valueOf(version.getId())) - .replace("##FIXED_ISSUES_COUNT##", String.valueOf(version.getIssuesFixedCount())) + .replace("##RELEASE_OR_RELEASES##", releaseOrReleases) + .replace("##RELEASE_JIRA_LINKS##", releaseJiraLinks) + .replace("##FIXED_ISSUES_COUNT##", String.valueOf(fixedIssueCounts)) .replace("##USER_NAME##", membersFinder.getCurrentMember().getName()); logger.info(emailContents); diff --git a/src/main/java/org/apache/sling/cli/impl/release/Release.java b/src/main/java/org/apache/sling/cli/impl/release/Release.java index 5086962..d75f424 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/Release.java +++ b/src/main/java/org/apache/sling/cli/impl/release/Release.java @@ -16,6 +16,8 @@ */ package org.apache.sling.cli.impl.release; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -31,24 +33,32 @@ public final class Release { private static final Pattern RELEASE_PATTERN = Pattern.compile("^\\h*(Apache Sling\\h*)?([()a-zA-Z0-9\\-.\\h]+)\\h([0-9\\-.]+)" + "\\h?(RC[0-9.]+)?\\h*$"); - public static Release fromString(String repositoryDescription) { - - Release rel = new Release(); - Matcher matcher = RELEASE_PATTERN.matcher(repositoryDescription); - if (matcher.matches()) { - rel.component = matcher.group(2).trim(); - rel.version = matcher.group(3); - rel.name = rel.component + " " + rel.version; - StringBuilder fullName = new StringBuilder(); - if (matcher.group(1) != null) { - fullName.append(matcher.group(1).trim()).append(" "); - } - fullName.append(rel.name); - rel.fullName = fullName.toString(); - + public static List<Release> fromString(String repositoryDescription) { + List<Release> releases = new ArrayList<>(); + for (String item : repositoryDescription.split(",") ) { + + Matcher matcher = RELEASE_PATTERN.matcher(item); + if (matcher.matches()) { + Release rel = new Release(); + rel.component = matcher.group(2).trim(); + rel.version = matcher.group(3); + rel.name = rel.component + " " + rel.version; + StringBuilder fullName = new StringBuilder(); + if (matcher.group(1) != null) { + fullName.append(matcher.group(1).trim()).append(" "); + } + fullName.append(rel.name); + rel.fullName = fullName.toString(); + + releases.add(rel); + } } - return rel; + + if ( releases.isEmpty() ) + throw new IllegalArgumentException("No releases found in '" + repositoryDescription + "'"); + + return releases; } private String fullName; diff --git a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java index 90244eb..fb3ca95 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java +++ b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java @@ -76,8 +76,15 @@ public class TallyVotesCommand implements Command { try { StagingRepository repository = repoFinder.find(Integer.parseInt(target)); - Release release = Release.fromString(repository.getDescription()); - EmailThread voteThread = voteThreadFinder.findVoteThread(release.getFullName()); + String releaseName = Release.fromString(repository.getDescription()) + .stream() + .map(Release::getName) + .collect(Collectors.joining(", ")); + String releaseFullName = Release.fromString(repository.getDescription()) + .stream() + .map(Release::getFullName) + .collect(Collectors.joining(", ")); + EmailThread voteThread = voteThreadFinder.findVoteThread(releaseName); Set<String> bindingVoters = new HashSet<>(); Set<String> nonBindingVoters = new HashSet<>(); @@ -96,7 +103,7 @@ public class TallyVotesCommand implements Command { } } String email = EMAIL_TEMPLATE - .replace("##RELEASE_NAME##", release.getFullName()) + .replace("##RELEASE_NAME##", releaseFullName) .replace("##BINDING_VOTERS##", String.join(", ", bindingVoters)) .replace("##USER_NAME##", membersFinder.getCurrentMember().getName()); if (nonBindingVoters.isEmpty()) { diff --git a/src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java b/src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java index 4bf4530..99ab368 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java +++ b/src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDateTime; +import java.util.List; import org.apache.sling.cli.impl.Command; import org.apache.sling.cli.impl.jbake.JBakeContentUpdater; @@ -58,14 +59,17 @@ public class UpdateLocalSiteCommand implements Command { try ( Git git = Git.open(new File(GIT_CHECKOUT)) ) { StagingRepository repository = repoFinder.find(Integer.parseInt(target)); - Release release = Release.fromString(repository.getDescription()); + List<Release> releases = Release.fromString(repository.getDescription()); JBakeContentUpdater updater = new JBakeContentUpdater(); Path templatePath = Paths.get(GIT_CHECKOUT, "src", "main", "jbake", "templates", "downloads.tpl"); Path releasesPath = Paths.get(GIT_CHECKOUT, "src", "main", "jbake", "content", "releases.md"); - updater.updateDownloads(templatePath, release.getComponent(), release.getVersion()); - updater.updateReleases(releasesPath, release.getComponent(), release.getVersion(), LocalDateTime.now()); + LocalDateTime now = LocalDateTime.now(); + for ( Release release : releases ) { + updater.updateDownloads(templatePath, release.getComponent(), release.getVersion()); + updater.updateReleases(releasesPath, release.getComponent(), release.getVersion(), now); + } git.diff() .setOutputStream(System.out) diff --git a/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java b/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java index 0a33043..fdf0ef2 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java +++ b/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java @@ -70,22 +70,24 @@ public class UpdateReporterCommand implements Command { public void execute(String target) { try { StagingRepository repository = repoFinder.find(Integer.parseInt(target)); - Release release = Release.fromString(repository.getDescription()); + try (CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build()) { - HttpPost post = new HttpPost("https://reporter.apache.org/addrelease.py"); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); - List<NameValuePair> parameters = new ArrayList<>(); - Date now = new Date(); - parameters.add(new BasicNameValuePair("date", Long.toString(now.getTime() / 1000))); - parameters.add(new BasicNameValuePair("committee", "sling")); - parameters.add(new BasicNameValuePair("version", release.getFullName())); - parameters.add(new BasicNameValuePair("xdate", simpleDateFormat.format(now))); - post.setEntity(new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8)); - try (CloseableHttpResponse response = client.execute(post)) { - if (response.getStatusLine().getStatusCode() != 200) { - throw new IOException(String.format("The Apache Reporter System update failed. Got response code %s instead of " + - "200.", response.getStatusLine().getStatusCode())); + for ( Release release : Release.fromString(repository.getDescription()) ) { + HttpPost post = new HttpPost("https://reporter.apache.org/addrelease.py"); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + List<NameValuePair> parameters = new ArrayList<>(); + Date now = new Date(); + parameters.add(new BasicNameValuePair("date", Long.toString(now.getTime() / 1000))); + parameters.add(new BasicNameValuePair("committee", "sling")); + parameters.add(new BasicNameValuePair("version", release.getFullName())); + parameters.add(new BasicNameValuePair("xdate", simpleDateFormat.format(now))); + post.setEntity(new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8)); + try (CloseableHttpResponse response = client.execute(post)) { + if (response.getStatusLine().getStatusCode() != 200) { + throw new IOException(String.format("The Apache Reporter System update failed. Got response code %s instead of " + + "200.", response.getStatusLine().getStatusCode())); + } } } } diff --git a/src/test/java/org/apache/sling/cli/impl/release/ReleaseTest.java b/src/test/java/org/apache/sling/cli/impl/release/ReleaseTest.java index 182191a..fbab0a2 100644 --- a/src/test/java/org/apache/sling/cli/impl/release/ReleaseTest.java +++ b/src/test/java/org/apache/sling/cli/impl/release/ReleaseTest.java @@ -18,16 +18,16 @@ package org.apache.sling.cli.impl.release; import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.net.URISyntaxException; +import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import org.junit.Ignore; import org.junit.Test; public class ReleaseTest { @@ -35,8 +35,14 @@ public class ReleaseTest { @Test public void fromRepositoryDescription() { - Release rel1 = Release.fromString("Apache Sling Resource Merger 1.3.10 RC1"); - Release rel2 = Release.fromString(" Apache Sling Resource Merger 1.3.10 "); + List<Release> releases1 = Release.fromString("Apache Sling Resource Merger 1.3.10 RC1"); + List<Release> releases2 = Release.fromString(" Apache Sling Resource Merger 1.3.10 "); + + assertEquals(1, releases1.size()); + assertEquals(1, releases2.size()); + + Release rel1 = releases1.get(0); + Release rel2 = releases2.get(0); assertEquals("Resource Merger 1.3.10", rel1.getName()); assertEquals("Apache Sling Resource Merger 1.3.10", rel1.getFullName()); @@ -47,11 +53,33 @@ public class ReleaseTest { } @Test + public void fromRepositoryDescriptionWithMultipleArtifacts() { + List<Release> releases = Release.fromString("Apache Sling Parent 35, Apache Sling Bundle Parent 35"); + assertEquals(2, releases.size()); + } + + @Test(expected = IllegalArgumentException.class) + public void noReleasesFailsFast() { + Release.fromString(""); + } + + @Test + @Ignore("Broken after refactoring, needs separate issue") + public void releaseWithRCSuffixOnly() { + List<Release> releases = Release.fromString("Apache Sling Resource Resolver 1.6.12 RC"); + + assertEquals(1, releases.size()); + assertEquals("Apache Sling Resource Resolver 1.6.12", releases.get(0).getFullName()); + } + + @Test public void testReleaseParsingWithJIRAInfo() throws URISyntaxException, IOException { BufferedReader reader = new BufferedReader(new FileReader(new File(getClass().getResource("/jira_versions.txt").toURI()))); reader.lines().forEach(line -> { if (!line.startsWith("#") && !"".equals(line)) { - Release jiraRelease = Release.fromString(line); + List<Release> jiraReleases = Release.fromString(line); + assertEquals(1, jiraReleases.size()); + Release jiraRelease = jiraReleases.get(0); String releaseFullName = jiraRelease.getFullName(); if (releaseFullName == null) { fail("Failed to parse JIRA version: " + line);
