You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2019/07/01 10:17:23 UTC

[sling-org-apache-sling-committer-cli] 01/01: SLING-8545 - Mails are missing proper date header

This is an automated email from the ASF dual-hosted git repository.

radu pushed a commit to branch issue/SLING-8545
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 1ea482cddf459ebcea344dc9e63206d7e6e2a6c4
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Jul 1 12:17:02 2019 +0200

    SLING-8545 - Mails are missing proper date header
---
 pom.xml                                            | 15 +++++++
 src/main/features/app.json                         |  3 ++
 .../cli/impl/release/PrepareVoteEmailCommand.java  | 49 ++++++++--------------
 .../sling/cli/impl/release/TallyVotesCommand.java  | 37 ++++++++--------
 src/main/resources/templates/release.email         | 30 +++++++++++++
 src/main/resources/templates/tally-votes.email     | 18 ++++++++
 .../impl/release/PrepareVoteEmailCommandTest.java  | 23 +++++++++-
 .../cli/impl/release/TallyVotesCommandTest.java    | 28 +++++++++----
 8 files changed, 144 insertions(+), 59 deletions(-)

diff --git a/pom.xml b/pom.xml
index 0e21a19..4a00263 100644
--- a/pom.xml
+++ b/pom.xml
@@ -167,6 +167,15 @@
                     <skip>true</skip>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>src/main/resources/templates/*</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 
@@ -236,6 +245,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
diff --git a/src/main/features/app.json b/src/main/features/app.json
index 739d561..aee3a84 100644
--- a/src/main/features/app.json
+++ b/src/main/features/app.json
@@ -73,6 +73,9 @@
         },
         {
             "id": "info.picocli:picocli:4.0.0-beta-2"
+        },
+        {
+            "id": "commons-io:commons-io:2.6"
         }
     ]
 }
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 99dbb96..6caeea0 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,11 +17,15 @@
 package org.apache.sling.cli.impl.release;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
 import java.util.List;
 import java.util.stream.Collectors;
 
 import javax.mail.internet.InternetAddress;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.sling.cli.impl.Command;
 import org.apache.sling.cli.impl.InputOption;
 import org.apache.sling.cli.impl.UserInput;
@@ -78,37 +82,18 @@ public class PrepareVoteEmailCommand implements Command {
     @CommandLine.Spec
     CommandLine.Model.CommandSpec spec;
 
-    // TODO - replace with file template
-    private static final String EMAIL_TEMPLATE =
-            "From: ##FROM##\n" +
-            "To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
-            "Subject: [VOTE] Release ##RELEASE_NAME##\n" + 
-            "\n" + 
-            "Hi,\n" + 
-            "\n" + 
-            "We solved ##FIXED_ISSUES_COUNT## issue(s) in ##RELEASE_OR_RELEASES##:\n" +
-            "##RELEASE_JIRA_LINKS##\n" +
-            "\n" +
-            "Staging repository:\n" +
-            "https://repository.apache.org/content/repositories/orgapachesling-##RELEASE_ID##/\n" +
-            "\n" +
-            "You can use this UNIX script to download the release and verify the signatures:\n" +
-            "https://gitbox.apache.org/repos/asf?p=sling-tooling-release.git;a=blob;f=check_staged_release.sh;hb=HEAD\n" +
-            "\n" +
-            "Usage:\n" +
-            "sh check_staged_release.sh ##RELEASE_ID## /tmp/sling-staging\n" +
-            "\n" +
-            "Please vote to approve this release:\n" +
-            "\n" +
-            "  [ ] +1 Approve the release\n" +
-            "  [ ]  0 Don't care\n" +
-            "  [ ] -1 Don't release, because ...\n" +
-            "\n" +
-            "This majority vote is open for at least 72 hours.\n" +
-            "\n" +
-            "Regards,\n" +
-            "##USER_NAME##\n" +
-            "\n";
+    private static final String EMAIL_TEMPLATE;
+
+    static {
+        try {
+            EMAIL_TEMPLATE = IOUtils.toString(
+                    PrepareVoteEmailCommand.class.getClassLoader().getResourceAsStream("templates/release.email"),
+                    StandardCharsets.UTF_8
+            );
+        } catch (IOException e) {
+            throw new IllegalStateException("Unable to read embedded email template.", e);
+        }
+    }
 
     private static final String RELEASE_TEMPLATE =
             "https://issues.apache.org/jira/browse/SLING/fixforversion/##VERSION_ID##";
@@ -139,8 +124,10 @@ public class PrepareVoteEmailCommand implements Command {
                         .collect(Collectors.joining("\n"));
 
                 Member currentMember = membersFinder.getCurrentMember();
+                SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
                 String emailContents = EMAIL_TEMPLATE
                         .replace("##FROM##", new InternetAddress(currentMember.getEmail(), currentMember.getName()).toString())
+                        .replace("##DATE##", sdf.format(Calendar.getInstance().getTime()))
                         .replace("##RELEASE_NAME##", releaseName)
                         .replace("##RELEASE_ID##", String.valueOf(repositoryId))
                         .replace("##RELEASE_OR_RELEASES##", releaseOrReleases)
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 8235819..c417b28 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
@@ -17,8 +17,11 @@
 package org.apache.sling.cli.impl.release;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.text.Collator;
+import java.text.SimpleDateFormat;
 import java.util.Arrays;
+import java.util.Calendar;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
@@ -27,6 +30,7 @@ import java.util.stream.Collectors;
 
 import javax.mail.internet.InternetAddress;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.sling.cli.impl.Command;
 import org.apache.sling.cli.impl.InputOption;
 import org.apache.sling.cli.impl.UserInput;
@@ -76,25 +80,18 @@ public class TallyVotesCommand implements Command {
     @CommandLine.Mixin
     private ReusableCLIOptions reusableCLIOptions;
 
-    // TODO - move to file
-    private static final String EMAIL_TEMPLATE =
-            "From: ##FROM## \n" +
-            "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
-            "Subject: [RESULT] [VOTE] Release ##RELEASE_NAME##\n" + 
-            "\n" + 
-            "Hi,\n" + 
-            "\n" + 
-            "The vote has passed with the following result:\n" +
-            "\n" + 
-            "+1 (binding): ##BINDING_VOTERS##\n" + 
-            "+1 (non-binding): ##NON_BINDING_VOTERS##\n" +
-            "\n" +
-            "I will copy this release to the Sling dist directory and\n" + 
-            "promote the artifacts to the central Maven repository.\n" +
-            "\n" +
-            "Regards,\n" +
-            "##USER_NAME##\n" +
-            "\n";
+    private static final String EMAIL_TEMPLATE;
+
+    static {
+        try {
+            EMAIL_TEMPLATE = IOUtils.toString(
+                    TallyVotesCommand.class.getClassLoader().getResourceAsStream("templates/tally-votes.email"),
+                    StandardCharsets.UTF_8
+            );
+        } catch (IOException e) {
+            throw new IllegalStateException("Unable to read embedded email template.", e);
+        }
+    }
 
     @Override
     public void run() {
@@ -128,8 +125,10 @@ public class TallyVotesCommand implements Command {
                         }
                 );
                 Member currentMember = membersFinder.getCurrentMember();
+                SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
                 String email = EMAIL_TEMPLATE
                         .replace("##FROM##", new InternetAddress(currentMember.getEmail(), currentMember.getName()).toUnicodeString())
+                        .replace("##DATE##", sdf.format(Calendar.getInstance().getTime()))
                         .replace("##RELEASE_NAME##", releaseFullName)
                         .replace("##BINDING_VOTERS##", String.join(", ", bindingVoters))
                         .replace("##USER_NAME##", membersFinder.getCurrentMember().getName());
diff --git a/src/main/resources/templates/release.email b/src/main/resources/templates/release.email
new file mode 100644
index 0000000..235d9fa
--- /dev/null
+++ b/src/main/resources/templates/release.email
@@ -0,0 +1,30 @@
+From: ##FROM##
+To: "Sling Developers List" <de...@sling.apache.org>
+Reply-To: "Sling Developers List" <de...@sling.apache.org>
+Date: ##DATE##
+Subject: [VOTE] Release ##RELEASE_NAME##
+
+Hi,
+
+We solved ##FIXED_ISSUES_COUNT## issue(s) in ##RELEASE_OR_RELEASES##:
+##RELEASE_JIRA_LINKS##
+
+Staging repository:
+https://repository.apache.org/content/repositories/orgapachesling-##RELEASE_ID##/
+
+You can use this UNIX script to download the release and verify the signatures:
+https://gitbox.apache.org/repos/asf?p=sling-tooling-release.git;a=blob;f=check_staged_release.sh;hb=HEAD
+
+Usage:
+sh check_staged_release.sh ##RELEASE_ID## /tmp/sling-staging
+
+Please vote to approve this release:
+
+  [ ] +1 Approve the release
+  [ ]  0 Don't care
+  [ ] -1 Don't release, because ...
+
+This majority vote is open for at least 72 hours.
+
+Regards,
+##USER_NAME##
diff --git a/src/main/resources/templates/tally-votes.email b/src/main/resources/templates/tally-votes.email
new file mode 100644
index 0000000..af68d64
--- /dev/null
+++ b/src/main/resources/templates/tally-votes.email
@@ -0,0 +1,18 @@
+From: ##FROM##
+To: "Sling Developers List" <de...@sling.apache.org>
+Reply-To: "Sling Developers List" <de...@sling.apache.org>
+Date: ##DATE##
+Subject: [RESULT] [VOTE] Release ##RELEASE_NAME##
+
+Hi,
+
+The vote has passed with the following result:
+
++1 (binding): ##BINDING_VOTERS##
++1 (non-binding): ##NON_BINDING_VOTERS##
+
+I will copy this release to the Sling dist directory and
+promote the artifacts to the central Maven repository.
+
+Regards,
+##USER_NAME##
diff --git a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
index e408509..9fad4d6 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
@@ -19,6 +19,7 @@
 package org.apache.sling.cli.impl.release;
 
 import java.io.IOException;
+import java.util.Calendar;
 
 import org.apache.sling.cli.impl.Command;
 import org.apache.sling.cli.impl.ExecutionMode;
@@ -32,7 +33,11 @@ import org.apache.sling.cli.impl.people.MembersFinder;
 import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.osgi.framework.ServiceReference;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
 import org.powermock.reflect.Whitebox;
 
 import picocli.CommandLine;
@@ -41,7 +46,16 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
 
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(PrepareVoteEmailCommand.class)
+@PowerMockIgnore({
+                         // https://github.com/powermock/powermock/issues/864
+                         "com.sun.org.apache.xerces.*",
+                         "javax.xml.*",
+                         "org.w3c.dom.*"
+                 })
 public class PrepareVoteEmailCommandTest {
 
     @Rule
@@ -49,6 +63,10 @@ public class PrepareVoteEmailCommandTest {
 
     @Test
     public void testPrepareEmailGeneration() throws Exception {
+        mockStatic(Calendar.class);
+        Calendar calendar = mock(Calendar.class);
+        when(calendar.getTimeInMillis()).thenReturn(0L);
+        when(Calendar.getInstance()).thenReturn(calendar);
         Mailer mailer = mock(Mailer.class);
         prepareExecution(mailer);
         PrepareVoteEmailCommand prepareVoteEmailCommand = spy(new PrepareVoteEmailCommand());
@@ -70,6 +88,8 @@ public class PrepareVoteEmailCommandTest {
         verify(mailer).send(
                 "From: John Doe <jo...@apache.org>\n" +
                         "To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
+                        "Reply-To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
+                        "Date: Thu, 1 Jan 1970 01:00:00 +0100\n" +
                         "Subject: [VOTE] Release Apache Sling CLI Test 1.0.0\n" +
                         "\n" +
                         "Hi,\n" +
@@ -95,8 +115,7 @@ public class PrepareVoteEmailCommandTest {
                         "This majority vote is open for at least 72 hours.\n" +
                         "\n" +
                         "Regards,\n" +
-                        "John Doe\n" +
-                        "\n");
+                        "John Doe\n");
     }
 
     private void prepareExecution(Mailer mailer) throws IOException {
diff --git a/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java
index c61cc7f..2a2832e 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java
@@ -20,6 +20,7 @@ package org.apache.sling.cli.impl.release;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -38,6 +39,7 @@ import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
 import org.apache.sling.cli.impl.people.Member;
 import org.apache.sling.cli.impl.people.MembersFinder;
 import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -62,12 +64,22 @@ import static org.powermock.api.mockito.PowerMockito.mockStatic;
                          "javax.xml.*",
                          "org.w3c.dom.*"
                  })
+@PrepareForTest(TallyVotesCommand.class)
 public class TallyVotesCommandTest {
+
+    @BeforeClass
+    public static void beforeClass() {
+        mockStatic(Calendar.class);
+        Calendar calendar = mock(Calendar.class);
+        when(calendar.getTimeInMillis()).thenReturn(0L);
+        when(Calendar.getInstance()).thenReturn(calendar);
+    }
+
     @Rule
     public final OsgiContext osgiContext = new OsgiContext();
 
     @Test
-    @PrepareForTest({LoggerFactory.class})
+    @PrepareForTest({TallyVotesCommand.class, LoggerFactory.class})
     public void testDryRun() throws Exception {
         mockStatic(LoggerFactory.class);
         Logger logger = mock(Logger.class);
@@ -92,8 +104,10 @@ public class TallyVotesCommandTest {
         Command command = (Command) osgiContext.bundleContext().getService(reference);
         command.run();
         verify(logger).info(
-                "From: John Doe <jo...@apache.org> \n" +
+                "From: John Doe <jo...@apache.org>\n" +
                 "To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
+                "Reply-To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
+                "Date: Thu, 1 Jan 1970 01:00:00 +0100\n" +
                 "Subject: [RESULT] [VOTE] Release Apache Sling CLI Test 1.0.0\n" +
                 "\n" +
                 "Hi,\n" +
@@ -107,8 +121,7 @@ public class TallyVotesCommandTest {
                 "promote the artifacts to the central Maven repository.\n" +
                 "\n" +
                 "Regards,\n" +
-                "John Doe\n" +
-                "\n"
+                "John Doe\n"
         );
     }
 
@@ -165,8 +178,10 @@ public class TallyVotesCommandTest {
         Command command = (Command) osgiContext.bundleContext().getService(reference);
         command.run();
         verify(mailer).send(
-                "From: John Doe <jo...@apache.org> \n" +
+                "From: John Doe <jo...@apache.org>\n" +
                         "To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
+                        "Reply-To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
+                        "Date: Thu, 1 Jan 1970 01:00:00 +0100\n" +
                         "Subject: [RESULT] [VOTE] Release Apache Sling CLI Test 1.0.0\n" +
                         "\n" +
                         "Hi,\n" +
@@ -180,8 +195,7 @@ public class TallyVotesCommandTest {
                         "promote the artifacts to the central Maven repository.\n" +
                         "\n" +
                         "Regards,\n" +
-                        "John Doe\n" +
-                        "\n"
+                        "John Doe\n"
         );
     }