You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2019/04/16 15:41:56 UTC

[sling-org-apache-sling-committer-cli] branch master created (now e11e596)

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

rombert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git.


      at e11e596  SLING-8339 - CLI hangs when an unhandled exception occurs

This branch includes the following new commits:

     new abbd20f  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new d37ac21  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new e54afe1  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new d5e841e  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new ad74b22  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 7675184  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 57f0942  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 292bc15  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new c2beebd  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 3cba59d  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 6b9e300  re-add the space in between the subject's tags
     new e8e5d79  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 45adcd8  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 7a4c927  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 95330f1  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 9da1f2c  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 1945c87  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 05ae0d8  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new d9ae571  SLING-8311 - Investigate creating a Sling CLI tool for development task automation
     new 2a914e4  Add explicity dependecy on javax.mail
     new e11e596  SLING-8339 - CLI hangs when an unhandled exception occurs

The 21 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-org-apache-sling-committer-cli] 20/21: Add explicity dependecy on javax.mail

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 2a914e4ae524921e612b35e544963d0c8c7e8e65
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Mar 29 17:41:41 2019 +0100

    Add explicity dependecy on javax.mail
    
    We should not rely on the classpath populated by the feature model.
---
 pom.xml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/pom.xml b/pom.xml
index b27394e..735bc46 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,6 +71,9 @@
                 <artifactId>slingfeature-maven-plugin</artifactId>
                 <version>0.8.0</version>
                 <extensions>true</extensions>
+                <configuration>
+                    <skipAddFeatureDependencies>true</skipAddFeatureDependencies>
+                </configuration>
                 <executions>
                     <execution>
                         <id>feature-dependencies</id>
@@ -180,6 +183,12 @@
           <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+            <version>1.5.0-b01</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>


[sling-org-apache-sling-committer-cli] 11/21: re-add the space in between the subject's tags

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 6b9e300a84a0279814dbe665d09dff993992576a
Author: Radu Cotescu <17...@users.noreply.github.com>
AuthorDate: Wed Mar 20 15:06:15 2019 +0100

    re-add the space in between the subject's tags
---
 src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 cbda427..86742bb 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
@@ -41,7 +41,7 @@ public class TallyVotesCommand implements Command {
     // TODO - move to file
     private static final String EMAIL_TEMPLATE =
             "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
-            "Subject: [RESULT][VOTE] Release ##RELEASE_NAME##\n" + 
+            "Subject: [RESULT] [VOTE] Release ##RELEASE_NAME##\n" + 
             "\n" + 
             "Hi,\n" + 
             "\n" + 


[sling-org-apache-sling-committer-cli] 15/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 95330f1312369738740edca534816d70e763ccdc
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Mar 28 17:41:06 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * added support for updating a release in the Apache Reporter System
    * added a service for extracting the user's credentials from the environment
    * switched Docker image to the openjdk11 provided by azul
    * used jlink to create a minimal JRE
---
 Dockerfile                                         |  10 +-
 pom.xml                                            |  13 ++-
 src/main/features/app.json                         |  14 +--
 .../org/apache/sling/cli/impl/Credentials.java     |  38 +++++++
 .../apache/sling/cli/impl/CredentialsService.java  |  55 +++++++++
 .../cli/impl/nexus/StagingRepositoryFinder.java    |  32 ++----
 .../sling/cli/impl/people/MembersFinder.java       |  17 +--
 .../cli/impl/release/UpdateReporterCommand.java    | 124 +++++++++++++++++++++
 src/main/resources/scripts/launcher.sh             |  24 ++--
 9 files changed, 268 insertions(+), 59 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index c29cd1e..ca438e9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,12 +9,16 @@
 # either express or implied. See the License for the specific language governing permissions
 # and limitations under the License.
 # ----------------------------------------------------------------------------------------
-
-FROM openjdk:8-jre-alpine
+FROM azul/zulu-openjdk-alpine:11 as builder
 MAINTAINER dev@sling.apache.org
+RUN jlink --add-modules java.logging,java.naming,java.xml,java.security.jgss,java.sql,jdk.crypto.ec \
+          --output /opt/jre --strip-debug --compress=2 --no-header-files --no-man-pages
+
+FROM alpine
+COPY --from=builder /opt/jre /opt/jre
 
 # Generate class data sharing
-RUN java -Xshare:dump
+RUN /opt/jre/bin/java -Xshare:dump
 
 # escaping required to properly handle arguments with spaces
 ENTRYPOINT ["/usr/share/sling-cli/bin/launcher.sh"]
diff --git a/pom.xml b/pom.xml
index 1f717d7..b27394e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,8 +16,8 @@
 
     <parent>
         <groupId>org.apache.sling</groupId>
-        <artifactId>sling</artifactId>
-        <version>34</version>
+        <artifactId>sling-bundle-parent</artifactId>
+        <version>35-SNAPSHOT</version>
         <relativePath />
     </parent>
 
@@ -28,6 +28,7 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <sling.java.version>11</sling.java.version>
     </properties>
 
     <build>
@@ -123,6 +124,14 @@
                     </buildArgs>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>biz.aQute.bnd</groupId>
+                <artifactId>bnd-baseline-maven-plugin</artifactId>
+                <configuration>
+                    <!-- We don't export an API, so it should be safe to skip baseline. -->
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/src/main/features/app.json b/src/main/features/app.json
index 4d310c4..5fb7cd2 100644
--- a/src/main/features/app.json
+++ b/src/main/features/app.json
@@ -1,9 +1,5 @@
 {
 	"id": "${project.groupId}:${project.artifactId}:slingfeature:app:${project.version}",
-	"variables": {
-    	"asf.username":"change-me",
-    	"asf.password": "change-me"
-    },
 	"bundles": [
 		{
 			"id": "${project.groupId}:${project.artifactId}:${project.version}",
@@ -69,11 +65,5 @@
 			"id": "org.apache.servicemix.bundles:org.apache.servicemix.bundles.jsch:0.1.55_1",
 			"start-level": "3"
 		}
-	],
-	"configurations": {
-		"org.apache.sling.cli.impl.nexus.StagingRepositoryFinder": {
-			"username": "${asf.username}",
-			"password": "${asf.password}"
-		}
-	}
-}
\ No newline at end of file
+	]
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/Credentials.java b/src/main/java/org/apache/sling/cli/impl/Credentials.java
new file mode 100644
index 0000000..2df5a32
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/Credentials.java
@@ -0,0 +1,38 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you 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.apache.sling.cli.impl;
+
+public class Credentials {
+
+    private final String user;
+    private final String password;
+
+    public Credentials(String user, String password) {
+        this.user = user;
+        this.password = password;
+    }
+
+    public String getUsername() {
+        return user;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/CredentialsService.java b/src/main/java/org/apache/sling/cli/impl/CredentialsService.java
new file mode 100644
index 0000000..3ddbcca
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/CredentialsService.java
@@ -0,0 +1,55 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you 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.apache.sling.cli.impl;
+
+import java.util.Optional;
+
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+
+@Component(service = CredentialsService.class)
+public class CredentialsService {
+
+    private static final String USER_SYS_PROP = "asf.username";
+    private static final String PASSWORD_SYS_PROP = "asf.password";
+    private static final String USER_ENV_PROP = "ASF_USERNAME";
+    private static final String PASSWORD_ENV_PROP = "ASF_PASSWORD";
+
+    private volatile Credentials credentials;
+
+    @Activate
+    private void activate() {
+        Optional<String> username =
+                Optional.ofNullable(System.getProperty(USER_SYS_PROP)).or(() -> Optional.ofNullable(System.getenv(USER_ENV_PROP)));
+        Optional<String> password =
+                Optional.ofNullable(System.getProperty(PASSWORD_SYS_PROP)).or(() -> Optional.ofNullable(System.getenv(PASSWORD_ENV_PROP)));
+        credentials = new Credentials(
+                username.orElseThrow(() -> new IllegalStateException(
+                        String.format("Cannot detect user information after looking for %s system property and %s environment variable.",
+                                USER_SYS_PROP, USER_ENV_PROP))),
+                password.orElseThrow(() -> new IllegalStateException(
+                        String.format("Cannot detect password after looking for %s system property and %s environment variable.",
+                                PASSWORD_SYS_PROP, PASSWORD_ENV_PROP)))
+        );
+    }
+
+    public Credentials getCredentials() {
+        return credentials;
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
index 21b30ff..9093a04 100644
--- a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
+++ b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
@@ -30,45 +30,35 @@ import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
+import org.apache.sling.cli.impl.Credentials;
+import org.apache.sling.cli.impl.CredentialsService;
 import org.apache.sling.cli.impl.nexus.StagingRepository.Status;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.ConfigurationPolicy;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.osgi.service.component.annotations.Reference;
 
 import com.google.gson.Gson;
 
-@Component(
-    configurationPolicy = ConfigurationPolicy.REQUIRE,
-    service = StagingRepositoryFinder.class
-)
-@Designate(ocd = StagingRepositoryFinder.Config.class)
+@Component(service = StagingRepositoryFinder.class)
 public class StagingRepositoryFinder {
     
     private static final String REPOSITORY_PREFIX = "orgapachesling-";
 
-    @ObjectClassDefinition
-    static @interface Config {
-        @AttributeDefinition(name="Username")
-        String username();
-        
-        @AttributeDefinition(name="Password")
-        String password();
-    }
+    @Reference
+    private CredentialsService credentialsService;
 
     private BasicCredentialsProvider credentialsProvider;
     
     @Activate
-    protected void activate(Config cfg) {
+    private void activate() {
+        Credentials credentials = credentialsService.getCredentials();
         credentialsProvider = new BasicCredentialsProvider();
         credentialsProvider.setCredentials(new AuthScope("repository.apache.org", 443), 
-                new UsernamePasswordCredentials(cfg.username(), cfg.password()));
+                new UsernamePasswordCredentials(credentials.getUsername(), credentials.getPassword()));
     }
     
     public List<StagingRepository> list() throws IOException {
-        return this. <List<StagingRepository>> withStagingRepositories( reader -> {
+        return this.withStagingRepositories( reader -> {
             Gson gson = new Gson();
             return gson.fromJson(reader, StagingRepositories.class).getData().stream()
                     .filter( r -> r.getType() == Status.closed)
@@ -78,7 +68,7 @@ public class StagingRepositoryFinder {
     }
 
     public StagingRepository find(int stagingRepositoryId) throws IOException {
-        return this.<StagingRepository> withStagingRepositories( reader -> {
+        return this.withStagingRepositories( reader -> {
             Gson gson = new Gson();
             return gson.fromJson(reader, StagingRepositories.class).getData().stream()
                     .filter( r -> r.getType() == Status.closed)
diff --git a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
index a27bf6c..70b5469 100644
--- a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
+++ b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
@@ -29,7 +29,9 @@ import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
+import org.apache.sling.cli.impl.CredentialsService;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,6 +49,9 @@ public class MembersFinder {
     private Set<Member> members = Collections.emptySet();
     private long lastCheck = 0;
 
+    @Reference
+    private CredentialsService credentialsService;
+
     public synchronized Set<Member> findMembers() {
         final Set<Member> _members = new HashSet<>();
         if (lastCheck == 0 || System.currentTimeMillis() > lastCheck + STALENESS_IN_HOURS * 3600 * 1000) {
@@ -108,17 +113,7 @@ public class MembersFinder {
     }
 
     public Member getCurrentMember() {
-        final String currentUserId;
-        if (System.getProperty("asf.username") != null) {
-            currentUserId = System.getProperty("asf.username");
-        } else {
-            currentUserId = System.getenv("ASF_USERNAME");
-        }
-        if (currentUserId == null) {
-            throw new IllegalStateException(String.format("Expected to find the current user defined either through the %s system " +
-                    "property or through the %s environment variable.", "asf.username", "ASF_USERNAME"));
-        }
-         return getMemberById(currentUserId);
+         return getMemberById(credentialsService.getCredentials().getUsername());
     }
 
 }
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
new file mode 100644
index 0000000..4c0c127
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/release/UpdateReporterCommand.java
@@ -0,0 +1,124 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you 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.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSocket;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ssl.DefaultHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.Credentials;
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = Command.class,
+    property = {
+        Command.PROPERTY_NAME_COMMAND + "=release",
+        Command.PROPERTY_NAME_SUBCOMMAND + "=update-reporter",
+        Command.PROPERTY_NAME_SUMMARY + "=Updates the Apache Reporter System with the new release information"
+    }
+)
+public class UpdateReporterCommand implements Command {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(UpdateReporterCommand.class);
+
+    @Reference
+    private StagingRepositoryFinder repoFinder;
+
+    @Reference
+    private CredentialsService credentialsService;
+
+    private CredentialsProvider credentialsProvider;
+
+    @Override
+    public void execute(String target) {
+        try {
+            StagingRepository repository = repoFinder.find(Integer.parseInt(target));
+            Release release = Release.fromString(repository.getDescription());
+            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
+            sslContext.init(null, null, null);
+            SSLContext.setDefault(sslContext);
+            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
+                    sslContext,
+                    new String[] {"TLSv1.2"},
+                    new String[] {
+                            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
+                    },
+                    new DefaultHostnameVerifier()
+            );
+            try (CloseableHttpClient client =
+                         HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).setSSLSocketFactory(sslConnectionSocketFactory).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()));
+                    }
+                }
+            }
+        } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
+            LOGGER.error(String.format("Unable to update reporter service; passed command: %s.", target), e);
+        }
+
+    }
+
+    @Activate
+    private void activate() {
+        Credentials credentials = credentialsService.getCredentials();
+        credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(new AuthScope("reporter.apache.org", 443),
+                new UsernamePasswordCredentials(credentials.getUsername(), credentials.getPassword()));
+    }
+}
diff --git a/src/main/resources/scripts/launcher.sh b/src/main/resources/scripts/launcher.sh
index 7b306ba..08f103f 100755
--- a/src/main/resources/scripts/launcher.sh
+++ b/src/main/resources/scripts/launcher.sh
@@ -18,13 +18,17 @@
 ARGS_PROP="exec.args=$@"
 
 # Use exec to become pid 1, see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
-exec /usr/bin/java \
-     -Xshare:on \
-	 -Dorg.slf4j.simpleLogger.logFile=/dev/null \
-	 -Dlogback.configurationFile=file:/usr/share/sling-cli/conf/logback-default.xml \
-	 -jar /usr/share/sling-cli/launcher/org.apache.sling.feature.launcher.jar \
-	 -f /usr/share/sling-cli/sling-cli.feature \
-	 -c /usr/share/sling-cli/artifacts \
-	 -D "$ARGS_PROP" \
-	 -V "asf.username=${ASF_USERNAME}" \
-	 -V "asf.password=${ASF_PASSWORD}"
+exec /opt/jre/bin/java \
+    --add-opens=java.base/java.lang=ALL-UNNAMED \
+    --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED \
+    --add-opens=java.base/java.net=ALL-UNNAMED \
+    --add-opens=java.base/java.security=ALL-UNNAMED \
+    -Xshare:on \
+    -Dorg.slf4j.simpleLogger.logFile=/dev/null \
+    -Dlogback.configurationFile=file:/usr/share/sling-cli/conf/logback-default.xml \
+    -jar /usr/share/sling-cli/launcher/org.apache.sling.feature.launcher.jar \
+    -f /usr/share/sling-cli/sling-cli.feature \
+    -c /usr/share/sling-cli/artifacts \
+    -D "$ARGS_PROP" \
+    -V "asf.username=${ASF_USERNAME}" \
+    -V "asf.password=${ASF_PASSWORD}"


[sling-org-apache-sling-committer-cli] 12/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit e8e5d79917e041ae173b261c5193d99948f531ac
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Mar 25 12:33:02 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * improved release parsing
---
 .../apache/sling/cli/impl/jira/VersionFinder.java  |    4 +-
 .../cli/impl/release/PrepareVoteEmailCommand.java  |    6 +-
 .../org/apache/sling/cli/impl/release/Release.java |   97 +
 .../sling/cli/impl/release/ReleaseVersion.java     |   59 -
 .../sling/cli/impl/release/TallyVotesCommand.java  |    6 +-
 .../cli/impl/release/UpdateLocalSiteCommand.java   |    6 +-
 .../apache/sling/cli/impl/release/ReleaseTest.java |   68 +
 .../sling/cli/impl/release/ReleaseVersionTest.java |   35 -
 src/test/resources/jira_versions.txt               | 1993 ++++++++++++++++++++
 9 files changed, 2170 insertions(+), 104 deletions(-)

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 5bf0406..7dbcbee 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
@@ -26,6 +26,7 @@ import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
+import org.apache.sling.cli.impl.release.Release;
 import org.osgi.service.component.annotations.Component;
 
 import com.google.gson.Gson;
@@ -57,8 +58,9 @@ 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);
                 version = versions.stream()
-                    .filter(v -> v.getName().equals(versionName))
+                    .filter(v -> filter.equals(Release.fromString(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 5b8df75..9819107 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
@@ -73,11 +73,11 @@ public class PrepareVoteEmailCommand implements Command {
         try {
             int repoId = Integer.parseInt(target);
             StagingRepository repo = repoFinder.find(repoId);
-            ReleaseVersion releaseVersion = ReleaseVersion.fromRepositoryDescription(repo.getDescription());
-            Version version = versionFinder.find(releaseVersion.getName());
+            Release release = Release.fromString(repo.getDescription());
+            Version version = versionFinder.find(release.getName());
             
             String emailContents = EMAIL_TEMPLATE
-                    .replace("##RELEASE_NAME##", releaseVersion.getFullName())
+                    .replace("##RELEASE_NAME##", release.getFullName())
                     .replace("##RELEASE_ID##", String.valueOf(repoId))
                     .replace("##VERSION_ID##", String.valueOf(version.getId()))
                     .replace("##FIXED_ISSUES_COUNT##", String.valueOf(version.getIssuesFixedCount()));
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
new file mode 100644
index 0000000..5086962
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/release/Release.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
+
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class Release {
+
+    /*
+        Group 1: Apache Sling and any trailing whitespace (optional)
+        Group 2: Release component
+        Group 3: Release version
+        Group 4: RC status (optional)
+     */
+    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();
+
+
+        }
+        return rel;
+    }
+    
+    private String fullName;
+    private String name;
+    private String component;
+    private String version;
+
+    private Release() {
+        
+    }
+    
+    public String getFullName() {
+        return fullName;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public String getVersion() {
+        return version;
+    }
+
+    public String getComponent() {
+        return component;
+    }
+
+    @Override
+    public int hashCode() {
+        return fullName.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Release)) {
+            return false;
+        }
+        Release other = (Release) obj;
+        return Objects.equals(name, other.name);
+    }
+
+    @Override
+    public String toString() {
+        return fullName;
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java b/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
deleted file mode 100644
index 0f0ef96..0000000
--- a/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
-
-public final class ReleaseVersion {
-    
-    public static ReleaseVersion fromRepositoryDescription(String repositoryDescription) {
-        
-        ReleaseVersion rel = new ReleaseVersion();
-        
-        rel.fullName = repositoryDescription
-            .replaceAll(" RC[0-9]*$", ""); // 'release candidate' suffix
-        rel.name = rel.fullName
-            .replace("Apache Sling ", ""); // Apache Sling prefix
-        rel.version = rel.fullName.substring(rel.fullName.lastIndexOf(' ') + 1);
-        rel.component = rel.name.substring(0, rel.name.lastIndexOf(' '));
-        
-        return rel;
-    }
-    
-    private String fullName;
-    private String name;
-    private String component;
-    private String version;
-
-    private ReleaseVersion() {
-        
-    }
-    
-    public String getFullName() {
-        return fullName;
-    }
-    
-    public String getName() {
-        return name;
-    }
-    
-    public String getVersion() {
-        return version;
-    }
-
-    public String getComponent() {
-        return component;
-    }
-}
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 86742bb..6046405 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
@@ -64,8 +64,8 @@ public class TallyVotesCommand implements Command {
         try {
             
             StagingRepository repository = repoFinder.find(Integer.parseInt(target));
-            ReleaseVersion releaseVersion = ReleaseVersion.fromRepositoryDescription(repository.getDescription()); 
-            EmailThread voteThread = voteThreadFinder.findVoteThread(releaseVersion.getFullName());
+            Release release = Release.fromString(repository.getDescription());
+            EmailThread voteThread = voteThreadFinder.findVoteThread(release.getFullName());
 
             // TODO - validate which voters are binding and list them separately in the email
             String bindingVoters = voteThread.getEmails().stream()
@@ -74,7 +74,7 @@ public class TallyVotesCommand implements Command {
                 .collect(Collectors.joining(", "));
             
             String email = EMAIL_TEMPLATE
-                .replace("##RELEASE_NAME##", releaseVersion.getFullName())
+                .replace("##RELEASE_NAME##", release.getFullName())
                 .replace("##BINDING_VOTERS##", bindingVoters);
             
             logger.info(email);
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 613afe0..4bf4530 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
@@ -58,14 +58,14 @@ public class UpdateLocalSiteCommand implements Command {
             try ( Git git = Git.open(new File(GIT_CHECKOUT)) ) {
                 
                 StagingRepository repository = repoFinder.find(Integer.parseInt(target));
-                ReleaseVersion releaseVersion = ReleaseVersion.fromRepositoryDescription(repository.getDescription());
+                Release release = 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, releaseVersion.getComponent(), releaseVersion.getVersion());
-                updater.updateReleases(releasesPath, releaseVersion.getComponent(), releaseVersion.getVersion(), LocalDateTime.now());
+                updater.updateDownloads(templatePath, release.getComponent(), release.getVersion());
+                updater.updateReleases(releasesPath, release.getComponent(), release.getVersion(), LocalDateTime.now());
         
                 git.diff()
                     .setOutputStream(System.out)
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
new file mode 100644
index 0000000..182191a
--- /dev/null
+++ b/src/test/java/org/apache/sling/cli/impl/release/ReleaseTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.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 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.Test;
+
+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   ");
+
+        assertEquals("Resource Merger 1.3.10", rel1.getName());
+        assertEquals("Apache Sling Resource Merger 1.3.10", rel1.getFullName());
+        assertEquals("1.3.10", rel1.getVersion());
+        assertEquals("Resource Merger", rel1.getComponent());
+
+        assertEquals(rel1, rel2);
+    }
+
+    @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);
+                String releaseFullName = jiraRelease.getFullName();
+                if (releaseFullName == null) {
+                    fail("Failed to parse JIRA version: " + line);
+                }
+                int indexComponent = line.indexOf(jiraRelease.getComponent());
+                int indexVersion = line.indexOf(jiraRelease.getVersion());
+                assertTrue(indexComponent >= 0 && indexVersion > indexComponent);
+            }
+        });
+        reader.close();
+    }
+
+
+}
diff --git a/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java b/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
deleted file mode 100644
index fc63a5f..0000000
--- a/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ReleaseVersionTest {
-
-    @Test
-    public void fromRepositoryDescription() {
-        
-        ReleaseVersion rel = ReleaseVersion.fromRepositoryDescription("Apache Sling Resource Merger 1.3.10 RC1");
-        
-        assertEquals("Resource Merger 1.3.10", rel.getName());
-        assertEquals("Apache Sling Resource Merger 1.3.10", rel.getFullName());
-        assertEquals("1.3.10", rel.getVersion());
-        assertEquals("Resource Merger", rel.getComponent());
-    }
-}
diff --git a/src/test/resources/jira_versions.txt b/src/test/resources/jira_versions.txt
new file mode 100644
index 0000000..7786c55
--- /dev/null
+++ b/src/test/resources/jira_versions.txt
@@ -0,0 +1,1993 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+ Commons Mime 2.0.4
+ Commons Testing 2.0.4
+ Extensions Web Console Branding 1.0.0
+ JCR Classloader 2.0.4
+ JCR Jackrabbit Access Manager 2.0.4
+ JCR Jackrabbit Client 2.0.4
+ Launchpad Base 2.2.0
+ Maven JSPC Plugin 2.0.4
+ Scripting JavaScript 2.0.4
+ Servlets Resolver 2.0.6
+ i18n 2.2.0
+API 2.0.2
+API 2.0.4
+API 2.0.6
+API 2.0.8
+API 2.1.0
+API 2.11.0
+API 2.12.0
+API 2.14.0
+API 2.14.2
+API 2.15.0
+API 2.16.0
+API 2.16.2
+API 2.16.4
+API 2.18.0
+API 2.18.2
+API 2.18.4
+API 2.2.0
+API 2.2.2
+API 2.2.4
+API 2.20.0
+API 2.20.2
+API 2.3.0
+API 2.4.0
+API 2.4.2
+API 2.5.0
+API 2.6.0
+API 2.7.0
+API 2.8.0
+API 2.9.0
+Adapter 2.0.10
+Adapter 2.0.12
+Adapter 2.0.14
+Adapter 2.0.16
+Adapter 2.0.2
+Adapter 2.0.4
+Adapter 2.0.6
+Adapter 2.0.8
+Adapter 2.1.0
+Adapter 2.1.10
+Adapter 2.1.2
+Adapter 2.1.4
+Adapter 2.1.6
+Adapter 2.1.8
+Adapter Annotations 1.0.0
+Adapter Annotations 1.0.2
+Apache Sling Capabilities 0.1.0
+Apache Sling Capabilities 0.2.0
+Apache Sling Capabilities 0.4.0
+Apache Sling Capabilities JCR 0.1.0
+Apache Sling Capabilities JCR 0.2.0
+Apache Sling Capabilities JCR 0.4.0
+Apache Sling Server Setup Tools 1.0.0
+Apache Sling Server Setup Tools 1.0.1
+Apache Sling Testing Clients 1.0.0
+Apache Sling Testing Clients 1.0.1
+Apache Sling Testing Clients 1.1.0
+Apache Sling Testing Clients 1.1.12
+Apache Sling Testing Clients 1.1.4
+Apache Sling Testing Clients 1.2.0
+Apache Sling Testing Clients 1.2.2
+Apache Sling Testing Rules 1.0.0
+Apache Sling Testing Rules 1.0.1
+Apache Sling Testing Rules 1.0.10
+Apache Sling Testing Rules 1.0.6
+Apache Sling Testing Rules 1.0.8
+App CMS 0.10.0
+App CMS 0.11.0
+App CMS 0.11.2
+Archetype Parent 1
+Archetype Parent 4
+Archetype Parent 5
+Archetype Parent 6
+Auth Core 1.0.0
+Auth Core 1.0.2
+Auth Core 1.0.4
+Auth Core 1.0.6
+Auth Core 1.1.0
+Auth Core 1.1.2
+Auth Core 1.1.4
+Auth Core 1.1.6
+Auth Core 1.1.8
+Auth Core 1.2.0
+Auth Core 1.3.0
+Auth Core 1.3.10
+Auth Core 1.3.12
+Auth Core 1.3.14
+Auth Core 1.3.16
+Auth Core 1.3.18
+Auth Core 1.3.2
+Auth Core 1.3.20
+Auth Core 1.3.22
+Auth Core 1.3.24
+Auth Core 1.3.26
+Auth Core 1.3.4
+Auth Core 1.3.6
+Auth Core 1.3.8
+Auth Core 1.4.0
+Auth Core 1.4.2
+Auth Core 1.4.4
+Auth Selector 1.0.0
+Auth Selector 1.0.2
+Auth Selector 1.0.4
+Auth Selector 1.0.6
+Auth Selector 1.0.8
+Authentication XING API 0.0.2
+Authentication XING API 0.0.4
+Authentication XING Login 0.0.2
+Authentication XING Login 0.0.4
+Authentication XING OAuth 0.0.2
+Authentication XING OAuth 0.0.4
+Background Servlets 1.0.0
+Background Servlets 1.0.10
+Background Servlets 1.0.2
+Background Servlets 1.0.6
+Background Servlets 1.0.8
+Bundle Archetype 1.0.0
+Bundle Archetype 1.0.2
+Bundle Archetype 1.0.4
+Bundle Archetype 1.0.6
+Bundle Archetype 1.0.8
+Bundle Parent 35
+Bundle Resource 2.0.2
+Bundle Resource 2.0.4
+Bundle Resource 2.0.6
+Bundle Resource 2.1.0
+Bundle Resource 2.1.2
+Bundle Resource 2.2.0
+Bundle Resource 2.3.0
+Bundle Resource 2.3.2
+Clam 1.0.0
+Clam 1.0.2
+Clam 1.1.0
+ClassLoader Leak Detector 1.0.0
+Commons Clam 1.0.0
+Commons Clam 1.0.2
+Commons Clam 2.0.0
+Commons ClassLoader 0.9.0
+Commons ClassLoader 1.0.0
+Commons ClassLoader 1.1.0
+Commons ClassLoader 1.1.2
+Commons ClassLoader 1.1.4
+Commons ClassLoader 1.2.0
+Commons ClassLoader 1.2.2
+Commons ClassLoader 1.2.4
+Commons ClassLoader 1.3.0
+Commons ClassLoader 1.3.2
+Commons ClassLoader 1.3.6
+Commons ClassLoader 1.3.8
+Commons ClassLoader 1.4.0
+Commons ClassLoader 1.4.2
+Commons ClassLoader 1.4.4
+Commons ClassLoader 1.4.6
+Commons Compiler 1.0.0
+Commons Compiler 2.0.0
+Commons Compiler 2.0.2
+Commons Compiler 2.0.4
+Commons Compiler 2.0.6
+Commons Compiler 2.1.0
+Commons Compiler 2.2.0
+Commons Compiler 2.3.0
+Commons Compiler 2.3.2
+Commons Compiler 2.3.4
+Commons Compiler 2.3.6
+Commons Compiler 2.3.8
+Commons HTML 0.9.0
+Commons HTML 1.0.0
+Commons HTML 1.0.2
+Commons HTML 1.1.0
+Commons HTML 1.1.2
+Commons JCR File 1.0.0
+Commons JSON 2.0.10
+Commons JSON 2.0.12
+Commons JSON 2.0.16
+Commons JSON 2.0.18
+Commons JSON 2.0.2
+Commons JSON 2.0.20
+Commons JSON 2.0.4
+Commons JSON 2.0.6
+Commons JSON 2.0.8
+Commons Johnzon 1.0.0
+Commons Johnzon 1.1.0
+Commons Johnzon 1.1.2
+Commons Johnzon 1.1.4
+Commons Log 2.0.2
+Commons Log 2.0.4
+Commons Log 2.0.6
+Commons Log 2.1.0
+Commons Log 2.1.2
+Commons Log 3.0.0
+Commons Log 3.0.2
+Commons Log 4.0.0
+Commons Log 4.0.2
+Commons Log 4.0.4
+Commons Log 4.0.6
+Commons Log 5.0.0
+Commons Log 5.0.2
+Commons Log 5.1.0
+Commons Log 5.1.10
+Commons Log 5.1.12
+Commons Log 5.1.2
+Commons Log 5.1.4
+Commons Log 5.1.6
+Commons Log 5.1.8
+Commons Log Service 1.0.0
+Commons Log Service 1.0.2
+Commons Log Service 1.0.4
+Commons Log Service 1.0.6
+Commons Log Service 1.0.8
+Commons Log WebConsole 1.0.0
+Commons Log WebConsole 1.0.2
+Commons Messaging 1.0.0
+Commons Messaging Mail 1.0.0
+Commons Metrics 1.0.0
+Commons Metrics 1.2.0
+Commons Metrics 1.2.2
+Commons Metrics 1.2.6
+Commons Metrics 1.2.8
+Commons Metrics RRD4J 1.0.0
+Commons Metrics RRD4J 1.0.2
+Commons Metrics RRD4J 1.0.4
+Commons Mime 2.0.2
+Commons Mime 2.1.0
+Commons Mime 2.1.10
+Commons Mime 2.1.2
+Commons Mime 2.1.4
+Commons Mime 2.1.6
+Commons Mime 2.1.8
+Commons Mime 2.2.0
+Commons Mime 2.2.2
+Commons OSGi 2.0.2
+Commons OSGi 2.0.4
+Commons OSGi 2.0.6
+Commons OSGi 2.1.0
+Commons OSGi 2.2.0
+Commons OSGi 2.2.2
+Commons OSGi 2.3.0
+Commons OSGi 2.4.0
+Commons OSGi 2.4.2
+Commons Scheduler 2.0.2
+Commons Scheduler 2.0.4
+Commons Scheduler 2.1.0
+Commons Scheduler 2.2.0
+Commons Scheduler 2.3.0
+Commons Scheduler 2.3.2
+Commons Scheduler 2.3.4
+Commons Scheduler 2.4.0
+Commons Scheduler 2.4.10
+Commons Scheduler 2.4.12
+Commons Scheduler 2.4.14
+Commons Scheduler 2.4.2
+Commons Scheduler 2.4.4
+Commons Scheduler 2.4.6
+Commons Scheduler 2.4.8
+Commons Scheduler 2.5.0
+Commons Scheduler 2.5.2
+Commons Scheduler 2.6.0
+Commons Scheduler 2.6.2
+Commons Scheduler 2.7.0
+Commons Scheduler 2.7.2
+Commons Scheduler 2.7.4
+Commons Testing 2.0.10
+Commons Testing 2.0.12
+Commons Testing 2.0.14
+Commons Testing 2.0.16
+Commons Testing 2.0.18
+Commons Testing 2.0.2
+Commons Testing 2.0.22
+Commons Testing 2.0.24
+Commons Testing 2.0.26
+Commons Testing 2.0.6
+Commons Testing 2.0.8
+Commons Testing 2.1.0
+Commons Testing 2.1.2
+Commons Testing 2.1.4
+Commons Threads 2.0.2
+Commons Threads 2.0.4
+Commons Threads 3.0.0
+Commons Threads 3.0.2
+Commons Threads 3.1.0
+Commons Threads 3.2.0
+Commons Threads 3.2.10
+Commons Threads 3.2.16
+Commons Threads 3.2.18
+Commons Threads 3.2.2
+Commons Threads 3.2.20
+Commons Threads 3.2.4
+Commons Threads 3.2.6
+Content Detection Support 1.0.2
+Content Detection Support 1.0.4
+Content Distribution 0.1.0
+Content Distribution API 0.4.0
+Content Distribution Core 0.1.1
+Content Distribution Core 0.1.10
+Content Distribution Core 0.1.12
+Content Distribution Core 0.1.14
+Content Distribution Core 0.1.16
+Content Distribution Core 0.1.18
+Content Distribution Core 0.1.2
+Content Distribution Core 0.1.4
+Content Distribution Core 0.1.6
+Content Distribution Core 0.1.8
+Content Distribution Core 0.2.0
+Content Distribution Core 0.2.10
+Content Distribution Core 0.2.4
+Content Distribution Core 0.2.6
+Content Distribution Core 0.2.8
+Content Distribution Core 0.3.0
+Content Distribution Core 0.3.4
+Content Distribution Core 0.4.0
+Content Distribution Extensions 0.1.0
+Context-Aware Configuration API 1.0.0
+Context-Aware Configuration API 1.1.0
+Context-Aware Configuration API 1.1.2
+Context-Aware Configuration API 1.1.4
+Context-Aware Configuration Impl 1.0.0
+Context-Aware Configuration Impl 1.1.0
+Context-Aware Configuration Impl 1.2.0
+Context-Aware Configuration Impl 1.3.0
+Context-Aware Configuration Impl 1.3.2
+Context-Aware Configuration Impl 1.4.0
+Context-Aware Configuration Impl 1.4.10
+Context-Aware Configuration Impl 1.4.12
+Context-Aware Configuration Impl 1.4.14
+Context-Aware Configuration Impl 1.4.16
+Context-Aware Configuration Impl 1.4.2
+Context-Aware Configuration Impl 1.4.4
+Context-Aware Configuration Impl 1.4.6
+Context-Aware Configuration Impl 1.4.8
+Context-Aware Configuration Mock Plugin 1.0.0
+Context-Aware Configuration Mock Plugin 1.1.0
+Context-Aware Configuration Mock Plugin 1.2.0
+Context-Aware Configuration Mock Plugin 1.3.0
+Context-Aware Configuration Mock Plugin 1.3.2
+Context-Aware Configuration Mock Plugin 1.3.4
+Context-Aware Configuration SPI 1.0.0
+Context-Aware Configuration SPI 1.1.0
+Context-Aware Configuration SPI 1.2.0
+Context-Aware Configuration SPI 1.3.0
+Context-Aware Configuration SPI 1.3.2
+Context-Aware Configuration SPI 1.3.4
+Context-Aware Configuration SPI 1.3.6
+Context-Aware Configuration bnd Plugin 1.0.0
+Context-Aware Configuration bnd Plugin 1.0.2
+Context-Aware Configuration bnd Plugin 1.0.4
+Crankstart Launcher 2.0.0
+Crankstart Test Services 2.0.0
+DataSource Provider 1.0.0
+DataSource Provider 1.0.2
+DataSource Provider 1.0.4
+DataSource Provider 1.1.0
+Discovery API 1.0.0
+Discovery API 1.0.2
+Discovery API 1.0.4
+Discovery Base 1.0.0
+Discovery Base 1.0.2
+Discovery Base 1.1.0
+Discovery Base 1.1.2
+Discovery Base 1.1.4
+Discovery Base 1.1.6
+Discovery Base 2.0.0
+Discovery Base 2.0.10
+Discovery Base 2.0.4
+Discovery Base 2.0.8
+Discovery Commons 1.0.0
+Discovery Commons 1.0.10
+Discovery Commons 1.0.12
+Discovery Commons 1.0.16
+Discovery Commons 1.0.18
+Discovery Commons 1.0.2
+Discovery Commons 1.0.20
+Discovery Commons 1.0.24
+Discovery Commons 1.0.4
+Discovery Commons 1.0.6
+Discovery Commons 1.0.8
+Discovery Impl 1.0.0
+Discovery Impl 1.0.10
+Discovery Impl 1.0.12
+Discovery Impl 1.0.2
+Discovery Impl 1.0.4
+Discovery Impl 1.0.6
+Discovery Impl 1.0.8
+Discovery Impl 1.1.0
+Discovery Impl 1.1.2
+Discovery Impl 1.1.4
+Discovery Impl 1.1.6
+Discovery Impl 1.1.8
+Discovery Impl 1.2.0
+Discovery Impl 1.2.10
+Discovery Impl 1.2.12
+Discovery Impl 1.2.14
+Discovery Impl 1.2.2
+Discovery Impl 1.2.6
+Discovery Impl 1.2.8
+Discovery Oak 1.0.0
+Discovery Oak 1.0.2
+Discovery Oak 1.1.0
+Discovery Oak 1.2.0
+Discovery Oak 1.2.10
+Discovery Oak 1.2.12
+Discovery Oak 1.2.14
+Discovery Oak 1.2.16
+Discovery Oak 1.2.18
+Discovery Oak 1.2.2
+Discovery Oak 1.2.20
+Discovery Oak 1.2.22
+Discovery Oak 1.2.28
+Discovery Oak 1.2.30
+Discovery Oak 1.2.4
+Discovery Oak 1.2.6
+Discovery Oak 1.2.8
+Discovery Standalone 1.0.0
+Discovery Standalone 1.0.2
+Discovery Standalone 1.0.4
+Discovery Support 1.0.0
+Discovery Support 1.0.4
+Distributed Event Admin 1.0.0
+Distributed Event Admin 1.0.2
+Distributed Event Admin 1.0.4
+Distributed Event Admin 1.1.0
+Distributed Event Admin 1.1.2
+Distributed Event Admin 1.1.4
+Distributed Event Admin 1.1.6
+Distribution Core 0.3.6
+Dynamic Include 3.0.0
+Dynamic Include 3.1.0
+Dynamic Include 3.1.2
+Dynamic Include 3.1.4
+Engine 2.0.2
+Engine 2.0.4
+Engine 2.0.6
+Engine 2.1.0
+Engine 2.2.0
+Engine 2.2.10
+Engine 2.2.2
+Engine 2.2.4
+Engine 2.2.6
+Engine 2.2.8
+Engine 2.3.0
+Engine 2.3.10
+Engine 2.3.2
+Engine 2.3.4
+Engine 2.3.6
+Engine 2.3.8
+Engine 2.4.0
+Engine 2.4.2
+Engine 2.4.4
+Engine 2.4.6
+Engine 2.5.0
+Engine 2.6.0
+Engine 2.6.10
+Engine 2.6.12
+Engine 2.6.14
+Engine 2.6.16
+Engine 2.6.18
+Engine 2.6.2
+Engine 2.6.20
+Engine 2.6.4
+Engine 2.6.6
+Engine 2.6.8
+Event 2.0.2
+Event 2.0.4
+Event 2.0.6
+Event 2.1.0
+Event 2.2.0
+Event 2.3.0
+Event 2.4.0
+Event 2.4.2
+Event 3.0.0
+Event 3.0.2
+Event 3.1.0
+Event 3.1.2
+Event 3.1.4
+Event 3.2.0
+Event 3.3.0
+Event 3.3.10
+Event 3.3.12
+Event 3.3.14
+Event 3.3.2
+Event 3.3.4
+Event 3.3.6
+Event 3.4.0
+Event 3.4.2
+Event 3.4.4
+Event 3.5.0
+Event 3.5.2
+Event 3.5.4
+Event 3.6.0
+Event 3.7.0
+Event 3.7.2
+Event 3.7.4
+Event 3.7.6
+Event 4.0.0
+Event 4.0.2
+Event 4.1.0
+Event 4.2.0
+Event 4.2.10
+Event 4.2.12
+Event 4.2.14
+Event 4.2.2
+Event 4.2.4
+Event 4.2.6
+Event 4.2.8
+Event API 1.0.0
+Event API 1.1.0
+Extensions APT Parser 2.0.2
+Extensions APT Server 2.0.2
+Extensions APT Server 2.0.4
+Extensions Adapter 2.0.2
+Extensions OpenID Authentication 0.9.0
+Extensions Thread Dumper 0.1.2
+Extensions Thread Dumper 0.2.0
+Extensions Thread Dumper 0.2.2
+Extensions Thread Dumper 0.2.4
+Extensions Web Console Branding 1.0.2
+Extensions Web Console Branding 1.0.4
+Extensions httpauth 2.0.2
+Extensions httpauth 2.0.4
+Extensions httpauth 2.0.6
+FTP Server 1.0.0
+Failing Server-Side Tests 1.0.6
+Failing Server-Side Tests 1.0.8
+Feature Flags 1.0.0
+Feature Flags 1.0.2
+Feature Flags 1.1.0
+Feature Flags 1.2.0
+Feature Flags 1.2.2
+Feature Flags 1.2.4
+Feature Model 0.1.0
+Feature Model 0.1.2
+Feature Model 0.2.0
+Feature Model 0.8.0
+Feature Model 1.0.0
+Feature Model 1.0.2
+Feature Model Analyser 0.1.0
+Feature Model Analyser 0.1.2
+Feature Model Analyser 0.2.0
+Feature Model Analyser 0.8.0
+Feature Model Analyser 1.0.0
+Feature Model Converter 0.1.0
+Feature Model Converter 0.1.2
+Feature Model Converter 0.2.0
+Feature Model Converter 0.8.0
+Feature Model Converter 1.0.0
+Feature Model IO 0.1.0
+Feature Model IO 0.1.2
+Feature Model IO 0.2.0
+Feature Model IO 0.8.0
+Feature Model IO 1.0.0
+Feature Model IO 1.0.2
+Feature Model Launcher 0.2.0
+Feature Model Launcher 0.8.0
+Feature Model Launcher 1.0.0
+File Installer 1.0.0
+File Installer 1.0.2
+File Installer 1.0.4
+File Installer 1.1.0
+File Installer 1.1.2
+File Optimization 0.9.2
+File System ClassLoader 1.0.0
+File System ClassLoader 1.0.10
+File System ClassLoader 1.0.2
+File System ClassLoader 1.0.4
+File System ClassLoader 1.0.6
+File System ClassLoader 1.0.8
+File System Resource Provider 0.9.2
+File System Resource Provider 1.0.0
+File System Resource Provider 1.0.2
+File System Resource Provider 1.1.0
+File System Resource Provider 1.1.2
+File System Resource Provider 1.1.4
+File System Resource Provider 1.2.2
+File System Resource Provider 1.3.0
+File System Resource Provider 1.4.0
+File System Resource Provider 1.4.10
+File System Resource Provider 1.4.2
+File System Resource Provider 1.4.4
+File System Resource Provider 1.4.6
+File System Resource Provider 1.4.8
+File System Resource Provider 2.0.0
+File System Resource Provider 2.1.0
+File System Resource Provider 2.1.10
+File System Resource Provider 2.1.12
+File System Resource Provider 2.1.14
+File System Resource Provider 2.1.16
+File System Resource Provider 2.1.2
+File System Resource Provider 2.1.4
+File System Resource Provider 2.1.6
+File System Resource Provider 2.1.8
+Form Based Authentication 1.0.0
+Form Based Authentication 1.0.10
+Form Based Authentication 1.0.12
+Form Based Authentication 1.0.14
+Form Based Authentication 1.0.2
+Form Based Authentication 1.0.4
+Form Based Authentication 1.0.6
+Form Based Authentication 1.0.8
+Framework Extension Fragment Activation 1.0.0
+Framework Extension Fragment Activation 1.0.2
+Framework Extension Fragment Activation 1.0.4
+Framework Extension Fragment Servlet API 1.0.0
+Framework Extension Fragment Transaction 1.0.0
+Framework Extension Fragment Transaction 1.0.2
+Framework Extension Fragment WS 1.0.0
+Framework Extension Fragment WS 1.0.2
+Framework Extension Fragment WS 1.0.4
+Framework Extension Fragment XML 1.0.0
+Framework Extension Fragment XML 1.0.2
+Framework Extension Fragment XML 1.0.4
+GWT Support 3.0.0
+GWT Support 3.0.2
+HApi 1.0.0
+HApi 1.1.0
+HApi Client 1.0.0
+HApi Client 1.0.2
+HTL Maven Plugin 1.0.0
+HTL Maven Plugin 1.0.2
+HTL Maven Plugin 1.0.4
+HTL Maven Plugin 1.0.6
+HTL Maven Plugin 1.0.8
+HTL Maven Plugin 1.1.0
+HTL Maven Plugin 1.1.2
+HTL Maven Plugin 1.1.4-1.3.1
+HTL Maven Plugin 1.1.6-1.4.0
+HTL Maven Plugin 1.1.8-1.4.0
+HTL Maven Plugin 1.2.0-1.4.0
+HTL Maven Plugin 1.2.2-1.4.0
+HTL Maven Plugin 1.2.4-1.4.0
+Health Check API 1.0.0
+Health Check API 1.0.2
+Health Check Annotations 1.0.2
+Health Check Annotations 1.0.4
+Health Check Annotations 1.0.6
+Health Check Core 1.0.4
+Health Check Core 1.0.6
+Health Check Core 1.1.0
+Health Check Core 1.1.2
+Health Check Core 1.2.0
+Health Check Core 1.2.10
+Health Check Core 1.2.12
+Health Check Core 1.2.2
+Health Check Core 1.2.4
+Health Check Core 1.2.6
+Health Check Core 1.2.8
+Health Check JMX 1.0.4
+Health Check JMX 1.0.6
+Health Check JUnit Bridge 1.0.2
+Health Check JUnit Bridge 1.0.4
+Health Check Support 1.0.4
+Health Check Support 1.0.6
+Health Check integration tests 1.0.4
+Health Check integration tests 1.0.6
+Health Check samples 1.0.4
+Health Check samples 1.0.6
+Health Check samples 1.0.8
+Health Check webconsole 1.0.4
+Health Check webconsole 1.1.0
+Health Check webconsole 1.1.2
+Health Check webconsole 1.1.4
+I18n 2.0.2
+I18n 2.0.4
+I18n 2.1.0
+I18n 2.1.2
+Initial Content Archetype 1.0.0
+Initial Content Archetype 1.0.4
+Initial Content Archetype 1.0.6
+Initial Content Archetype 1.0.8
+Installer API 1.0.0
+Installer Configuration Factory 1.0.0
+Installer Configuration Factory 1.0.10
+Installer Configuration Factory 1.0.12
+Installer Configuration Factory 1.0.14
+Installer Configuration Factory 1.0.2
+Installer Configuration Factory 1.0.4
+Installer Configuration Factory 1.0.8
+Installer Configuration Factory 1.1.0
+Installer Configuration Factory 1.1.2
+Installer Configuration Factory 1.2.0
+Installer Configuration Factory 1.2.2
+Installer Console 1.0.0
+Installer Console 1.0.2
+Installer Console 1.0.4
+Installer Core 3.0.0
+Installer Core 3.1.0
+Installer Core 3.1.2
+Installer Core 3.2.0
+Installer Core 3.2.2
+Installer Core 3.3.0
+Installer Core 3.3.2
+Installer Core 3.3.4
+Installer Core 3.3.6
+Installer Core 3.3.8
+Installer Core 3.4.0
+Installer Core 3.4.2
+Installer Core 3.4.4
+Installer Core 3.4.6
+Installer Core 3.5.0
+Installer Core 3.5.2
+Installer Core 3.5.4
+Installer Core 3.6.0
+Installer Core 3.6.2
+Installer Core 3.6.4
+Installer Core 3.6.6
+Installer Core 3.6.8
+Installer Core 3.7.0
+Installer Core 3.8.0
+Installer Core 3.8.10
+Installer Core 3.8.12
+Installer Core 3.8.2
+Installer Core 3.8.6
+Installer Core 3.8.8
+Installer Core 3.9.0
+Installer Core 3.9.2
+Installer Health Checks 1.0.0
+Installer Health Checks 2.0.0
+Installer Health Checks 2.0.2
+Installer Packages Factory 1.0.0
+Installer Subsystem Base Factory 1.0.0
+Installer Subsystems Factory 1.0.0
+Installer Subsystems Factory 1.0.2
+Installer Vault Package Install Hook 1.0.2
+Installer Vault Package Install Hook 1.0.4
+JCR API 2.0.2
+JCR API 2.0.4
+JCR API 2.0.6
+JCR API 2.1.0
+JCR API 2.2.0
+JCR API 2.3.0
+JCR API 2.4.0
+JCR API 2.4.2
+JCR Base 2.0.2
+JCR Base 2.0.4
+JCR Base 2.0.6
+JCR Base 2.1.0
+JCR Base 2.1.2
+JCR Base 2.2.0
+JCR Base 2.2.2
+JCR Base 2.3.0
+JCR Base 2.3.2
+JCR Base 2.4.0
+JCR Base 2.4.2
+JCR Base 3.0.0
+JCR Base 3.0.2
+JCR Base 3.0.4
+JCR Base 3.0.6
+JCR Base 3.0.8
+JCR ClassLoader 3.2.0
+JCR ClassLoader 3.2.2
+JCR ClassLoader 3.2.4
+JCR ClassLoader 3.2.6
+JCR Classloader 2.0.2
+JCR Classloader 2.0.6
+JCR Classloader 3.0.0
+JCR Classloader 3.1.0
+JCR Classloader 3.1.10
+JCR Classloader 3.1.12
+JCR Classloader 3.1.2
+JCR Classloader 3.1.4
+JCR Classloader 3.1.6
+JCR Classloader 3.1.8
+JCR Compiler 1.0.0
+JCR Compiler 2.0.0
+JCR Compiler 2.0.2
+JCR Compiler 2.0.4
+JCR Compiler 2.1.0
+JCR Compiler 2.1.2
+JCR Content Parser 1.0.0
+JCR Content Parser 1.1.0
+JCR Content Parser 1.2.0
+JCR Content Parser 1.2.2
+JCR Content Parser 1.2.4
+JCR Content Parser 1.2.6
+JCR Content Parser 1.2.8
+JCR ContentLoader 2.1.0
+JCR ContentLoader 2.1.10
+JCR ContentLoader 2.1.2
+JCR ContentLoader 2.1.4
+JCR ContentLoader 2.1.6
+JCR ContentLoader 2.1.8
+JCR ContentLoader 2.2.0
+JCR ContentLoader 2.2.2
+JCR ContentLoader 2.2.4
+JCR ContentLoader 2.2.6
+JCR ContentLoader 2.3.0
+JCR ContentLoader 2.3.2
+JCR Contentloader 2.0.2
+JCR Contentloader 2.0.4
+JCR Contentloader 2.0.6
+JCR DavEx 1.0.0
+JCR DavEx 1.1.0
+JCR DavEx 1.2.0
+JCR DavEx 1.2.2
+JCR DavEx 1.3.0
+JCR DavEx 1.3.2
+JCR Davex 1.3.10
+JCR Davex 1.3.12
+JCR Davex 1.3.4
+JCR Davex 1.3.8
+JCR File Transfer 1.0.0
+JCR Installer 3.0.0
+JCR Installer 3.0.2
+JCR Installer 3.0.4
+JCR Installer 3.1.0
+JCR Installer 3.1.14
+JCR Installer 3.1.16
+JCR Installer 3.1.18
+JCR Installer 3.1.2
+JCR Installer 3.1.22
+JCR Installer 3.1.24
+JCR Installer 3.1.26
+JCR Installer 3.1.28
+JCR Installer 3.1.4
+JCR Installer 3.1.6
+JCR Installer 3.1.8
+JCR Jackrabbit API 2.0.2
+JCR Jackrabbit Access Manager 2.0.2
+JCR Jackrabbit Access Manager 2.1.0
+JCR Jackrabbit Access Manager 2.1.2
+JCR Jackrabbit Access Manager 3.0.0
+JCR Jackrabbit Access Manager 3.0.2
+JCR Jackrabbit Access Manager 3.0.4
+JCR Jackrabbit Access Manager 3.0.6
+JCR Jackrabbit Client 2.0.2
+JCR Jackrabbit Server 2.0.2
+JCR Jackrabbit Server 2.0.4
+JCR Jackrabbit Server 2.0.6
+JCR Jackrabbit Server 2.1.0
+JCR Jackrabbit Server 2.1.2
+JCR Jackrabbit Server 2.2.0
+JCR Jackrabbit Server 2.3.0
+JCR Jackrabbit Server 2.3.2
+JCR Jackrabbit User Manager 2.0.2
+JCR Jackrabbit User Manager 2.0.4
+JCR Jackrabbit User Manager 2.1.0
+JCR Jackrabbit User Manager 2.2.0
+JCR Jackrabbit User Manager 2.2.10
+JCR Jackrabbit User Manager 2.2.2
+JCR Jackrabbit User Manager 2.2.4
+JCR Jackrabbit User Manager 2.2.6
+JCR Jackrabbit User Manager 2.2.8
+JCR OCM 2.0.2
+JCR OCM 2.0.4
+JCR OCM 2.0.6
+JCR Oak Server 1.0.0
+JCR Oak Server 1.1.0
+JCR Oak Server 1.1.2
+JCR Oak Server 1.1.4
+JCR Oak Server 1.2.0
+JCR Oak Server 1.2.2
+JCR Oak Server 1.2.4
+JCR Prefs 1.0.0
+JCR Prefs 1.0.2
+JCR Registration 1.0.0
+JCR Registration 1.0.2
+JCR Registration 1.0.4
+JCR Registration 1.0.6
+JCR Registration 1.0.8
+JCR Resource 2.0.10
+JCR Resource 2.0.2
+JCR Resource 2.0.4
+JCR Resource 2.0.6
+JCR Resource 2.0.8
+JCR Resource 2.1.0
+JCR Resource 2.2.0
+JCR Resource 2.2.2
+JCR Resource 2.2.4
+JCR Resource 2.2.6
+JCR Resource 2.2.8
+JCR Resource 2.3.0
+JCR Resource 2.3.10
+JCR Resource 2.3.12
+JCR Resource 2.3.2
+JCR Resource 2.3.4
+JCR Resource 2.3.6
+JCR Resource 2.3.8
+JCR Resource 2.4.2
+JCR Resource 2.4.4
+JCR Resource 2.5.0
+JCR Resource 2.5.2
+JCR Resource 2.5.4
+JCR Resource 2.5.6
+JCR Resource 2.7.0
+JCR Resource 2.7.2
+JCR Resource 2.7.4
+JCR Resource 2.8.0
+JCR Resource 2.8.2
+JCR Resource 2.8.4
+JCR Resource 2.9.0
+JCR Resource 2.9.2
+JCR Resource 3.0.0
+JCR Resource 3.0.10
+JCR Resource 3.0.14
+JCR Resource 3.0.16
+JCR Resource 3.0.18
+JCR Resource 3.0.2
+JCR Resource 3.0.20
+JCR Resource 3.0.4
+JCR Resource 3.0.6
+JCR Resource 3.0.8
+JCR Resource Security 1.0.0
+JCR Resource Security 1.0.2
+JCR Resource Security 1.0.4
+JCR Web Console 1.0.0
+JCR Web Console 1.0.2
+JCR Web Console 1.0.4
+JCR Webdav 2.0.2
+JCR Webdav 2.0.6
+JCR Webdav 2.0.8
+JCR Webdav 2.1.0
+JCR Webdav 2.1.2
+JCR Webdav 2.2.0
+JCR Webdav 2.2.2
+JCR Webdav 2.3.0
+JCR Webdav 2.3.10
+JCR Webdav 2.3.2
+JCR Webdav 2.3.4
+JCR Webdav 2.3.8
+JCR Wrapper 2.0.0
+JCRInstall Bundle Archetype 1.0.0
+JCRInstall Bundle Archetype 1.0.2
+JCRInstall Bundle Archetype 1.0.4
+JCRInstall Bundle Archetype 1.0.6
+JCRInstall Bundle Archetype 1.0.8
+JMX Resource Provider 0.5.0
+JMX Resource Provider 0.6.0
+JMX Resource Provider 1.0.0
+JMX Resource Provider 1.0.2
+JMX Resource Provider 1.0.4
+JUnit Core 1.0.10
+JUnit Core 1.0.12
+JUnit Core 1.0.14
+JUnit Core 1.0.16
+JUnit Core 1.0.18
+JUnit Core 1.0.20
+JUnit Core 1.0.22
+JUnit Core 1.0.23
+JUnit Core 1.0.24
+JUnit Core 1.0.26
+JUnit Core 1.0.6
+JUnit Core 1.0.8
+JUnit Health Check 1.0.6
+JUnit Health Check 1.0.8
+JUnit Remote Test Runners 1.0.12
+JUnit Remote Tests Runners 1.0.10
+JUnit Remote Tests Runners 1.0.6
+JUnit Remote Tests Runners 1.0.8
+JUnit Scriptable Tests Provider 1.0.10
+JUnit Scriptable Tests Provider 1.0.12
+JUnit Scriptable Tests Provider 1.0.6
+JUnit Scriptable Tests Provider 1.0.8
+JUnit Tests Teleporter 1.0.10
+JUnit Tests Teleporter 1.0.12
+JUnit Tests Teleporter 1.0.14
+JUnit Tests Teleporter 1.0.16
+JUnit Tests Teleporter 1.0.18
+JUnit Tests Teleporter 1.0.2
+JUnit Tests Teleporter 1.0.20
+JUnit Tests Teleporter 1.0.4
+JUnit Tests Teleporter 1.0.6
+JUnit Tests Teleporter 1.0.8
+Java Version Maven Plugin 1.0.0
+Java Version Maven Plugin 1.0.2
+Karaf 0.2.0
+Karaf Configs 0.2.0
+Karaf Distribution 0.2.0
+Karaf Features 0.2.0
+Karaf Integration Tests 0.2.0
+Karaf Launchpad Integration Tests (Oak Tar) 0.0.2
+Karaf repoinit 0.2.0
+Karaf repoinit 0.2.2
+Launchpad API 1.0.0
+Launchpad API 1.1.0
+Launchpad API 1.2.0
+Launchpad API 1.2.2
+Launchpad API 1.3.0
+Launchpad App 3
+Launchpad App 5
+Launchpad Base 2.0.2
+Launchpad Base 2.0.4
+Launchpad Base 2.1.0
+Launchpad Base 2.3.0
+Launchpad Base 2.4.0
+Launchpad Base 2.5.0
+Launchpad Base 2.5.2
+Launchpad Base 2.5.4
+Launchpad Base 2.5.6
+Launchpad Base 2.5.8
+Launchpad Base 2.6.0
+Launchpad Base 2.6.10
+Launchpad Base 2.6.12
+Launchpad Base 2.6.14
+Launchpad Base 2.6.16
+Launchpad Base 2.6.18
+Launchpad Base 2.6.2
+Launchpad Base 2.6.20
+Launchpad Base 2.6.22
+Launchpad Base 2.6.24
+Launchpad Base 2.6.26
+Launchpad Base 2.6.28
+Launchpad Base 2.6.30
+Launchpad Base 2.6.32
+Launchpad Base 2.6.34
+Launchpad Base 2.6.36
+Launchpad Base 2.6.4
+Launchpad Base 2.6.6
+Launchpad Base 2.6.8
+Launchpad Builder 6
+Launchpad Builder 7
+Launchpad Builder 8
+Launchpad Builder 9
+Launchpad Bundles 5
+Launchpad Content 2.0.12
+Launchpad Content 2.0.14
+Launchpad Content 2.0.2
+Launchpad Content 2.0.4
+Launchpad Content 2.0.6
+Launchpad Content 2.0.8
+Launchpad Installer 1.0.0
+Launchpad Installer 1.0.2
+Launchpad Installer 1.0.4
+Launchpad Installer 1.0.6
+Launchpad Installer 1.1.0
+Launchpad Installer 1.1.2
+Launchpad Installer 1.1.4
+Launchpad Installer 1.2.0
+Launchpad Installer 1.2.2
+Launchpad Installer 1.2.4
+Launchpad Integration Tests 1.0.0
+Launchpad Integration Tests 1.0.2
+Launchpad Integration Tests 1.0.4
+Launchpad Integration Tests 1.0.6
+Launchpad Integration Tests 1.0.8
+Launchpad Integration Tests 12
+Launchpad Standalone Archetype 1.0.0
+Launchpad Standalone Archetype 1.0.2
+Launchpad Test Fragment 2.0.16
+Launchpad Test Services 2.0.12
+Launchpad Test Services 2.0.14
+Launchpad Test Services 2.0.6
+Launchpad Testing 10
+Launchpad Testing 11
+Launchpad Testing 5
+Launchpad Testing 6
+Launchpad Testing Services 2.0.16
+Launchpad Testing War 10
+Launchpad Testing War 11
+Launchpad Webapp 3
+Launchpad Webapp 5
+Launchpad Webapp Archetype 1.0.0
+Launchpad Webapp Archetype 1.0.2
+Log Tail 1.0.0
+Log Tracer 0.0.2
+Log Tracer 1.0.0
+Log Tracer 1.0.2
+Log Tracer 1.0.4
+Log Tracer 1.0.6
+Log Tracer 1.0.8
+Maven JCROCM Plugin 2.0.2
+Maven JCROCM Plugin 2.0.4
+Maven JCROCM Plugin 2.0.6
+Maven JSPC Plugin 2.0.2
+Maven JSPC Plugin 2.0.6
+Maven JSPC Plugin 2.0.8
+Maven JSPC Plugin 2.1.0
+Maven JSPC Plugin 2.1.2
+Maven Launchpad Plugin 2.0.10
+Maven Launchpad Plugin 2.0.6
+Maven Launchpad Plugin 2.0.8
+Maven Launchpad Plugin 2.1.0
+Maven Launchpad Plugin 2.1.2
+Maven Launchpad Plugin 2.2.0
+Maven Launchpad Plugin 2.3.0
+Maven Launchpad Plugin 2.3.2
+Maven Launchpad Plugin 2.3.4
+Maven Launchpad Plugin 2.3.6
+Maven Sling Plugin 2.0.2
+Maven Sling Plugin 2.0.4
+Maven Sling Plugin 2.0.6
+Maven Sling Plugin 2.1.0
+Maven Sling Plugin 2.1.10
+Maven Sling Plugin 2.1.2
+Maven Sling Plugin 2.1.6
+Maven Sling Plugin 2.1.8
+Maven Sling Plugin 2.2.0
+Maven Sling Plugin 2.2.2
+Maven Sling Plugin 2.3.0
+Maven Sling Plugin 2.3.2
+Maven Sling Plugin 2.3.4
+Maven Sling Plugin 2.3.6
+Maven Sling Plugin 2.3.8
+MoM API 1.0.0
+MoM API 1.0.2
+MoM JMS 1.0.0
+MoM JMS 1.0.2
+MoM Jobs 1.0.0
+MoM Jobs 1.0.2
+Mongo Resource Provider 1.0.0
+NoSQL Couchbase Client 1.0.0
+NoSQL Couchbase Client 1.0.2
+NoSQL Couchbase Client 1.0.4
+NoSQL Couchbase Resource Provider 1.0.0
+NoSQL Couchbase Resource Provider 1.1.0
+NoSQL Couchbase Resource Provider 1.1.2
+NoSQL Generic Resource Provider 1.0.0
+NoSQL Generic Resource Provider 1.1.0
+NoSQL Generic Resource Provider 1.1.2
+NoSQL MongoDB Resource Provider 1.0.0
+NoSQL MongoDB Resource Provider 1.1.0
+NoSQL MongoDB Resource Provider 1.1.2
+Oak Restrictions 1.0.0
+Oak Restrictions 1.0.2
+Oak Restrictions 1.0.4
+OpenID Authentication 1.0.0
+OpenID Authentication 1.0.2
+OpenID Authentication 1.0.4
+OpenID Authentication 1.0.6
+Parent 10
+Parent 11
+Parent 12
+Parent 13
+Parent 14
+Parent 15
+Parent 16
+Parent 17
+Parent 18
+Parent 19
+Parent 20
+Parent 22
+Parent 23
+Parent 24
+Parent 25
+Parent 26
+Parent 27
+Parent 28
+Parent 29
+Parent 30
+Parent 31
+Parent 32
+Parent 33
+Parent 34
+Parent 35
+Parent 5
+Parent 6
+Parent 7
+Parent 8
+Parent 9
+Path Based RTP 2.0.2
+Path based RTP 2.0.4
+Pipes 0.0.10
+Pipes 1.0.4
+Pipes 1.1.0
+Pipes 2.0.2
+Pipes 3.0.2
+Pipes 3.1.0
+Pipes 3.2.0
+Portal Container 1.0.0
+Repoinit JCR 1.0.0
+Repoinit JCR 1.0.2
+Repoinit JCR 1.1.0
+Repoinit JCR 1.1.10
+Repoinit JCR 1.1.2
+Repoinit JCR 1.1.4
+Repoinit JCR 1.1.6
+Repoinit JCR 1.1.8
+Repoinit Parser 1.0.2
+Repoinit Parser 1.0.4
+Repoinit Parser 1.1.0
+Repoinit Parser 1.2.0
+Repoinit Parser 1.2.2
+Repoinit Parser 1.2.4
+Request Analyzer 1.0.0
+Resource Access Security 1.0.0
+Resource Access Security 1.0.2
+Resource Builder 1.0.0
+Resource Builder 1.0.2
+Resource Builder 1.0.4
+Resource Builder 1.0.6
+Resource Collections 1.0.0
+Resource Collections 1.0.2
+Resource Collections 1.0.4
+Resource Editor 1.0.2
+Resource Filter 1.0.0
+Resource Filter 1.0.2
+Resource Inventory 0.5.0
+Resource Inventory 1.0.0
+Resource Inventory 1.0.2
+Resource Inventory 1.0.4
+Resource Inventory 1.0.6
+Resource Inventory 1.0.8
+Resource Merger 1.0.0
+Resource Merger 1.1.0
+Resource Merger 1.1.2
+Resource Merger 1.2.0
+Resource Merger 1.2.10
+Resource Merger 1.2.4
+Resource Merger 1.2.6
+Resource Merger 1.2.8
+Resource Merger 1.3.0
+Resource Merger 1.3.10
+Resource Merger 1.3.2
+Resource Merger 1.3.4
+Resource Merger 1.3.6
+Resource Merger 1.3.8
+Resource Presence 0.0.2
+Resource Presence 0.0.4
+Resource Resolver 1.0.0
+Resource Resolver 1.0.2
+Resource Resolver 1.0.4
+Resource Resolver 1.0.6
+Resource Resolver 1.1.0
+Resource Resolver 1.1.10
+Resource Resolver 1.1.12
+Resource Resolver 1.1.14
+Resource Resolver 1.1.2
+Resource Resolver 1.1.4
+Resource Resolver 1.1.6
+Resource Resolver 1.1.8
+Resource Resolver 1.2.0
+Resource Resolver 1.2.2
+Resource Resolver 1.2.4
+Resource Resolver 1.2.6
+Resource Resolver 1.4.0
+Resource Resolver 1.4.10
+Resource Resolver 1.4.12
+Resource Resolver 1.4.14
+Resource Resolver 1.4.16
+Resource Resolver 1.4.18
+Resource Resolver 1.4.2
+Resource Resolver 1.4.4
+Resource Resolver 1.4.8
+Resource Resolver 1.5.0
+Resource Resolver 1.5.10
+Resource Resolver 1.5.12
+Resource Resolver 1.5.14
+Resource Resolver 1.5.18
+Resource Resolver 1.5.2
+Resource Resolver 1.5.20
+Resource Resolver 1.5.22
+Resource Resolver 1.5.24
+Resource Resolver 1.5.26
+Resource Resolver 1.5.28
+Resource Resolver 1.5.30
+Resource Resolver 1.5.32
+Resource Resolver 1.5.34
+Resource Resolver 1.5.36
+Resource Resolver 1.5.4
+Resource Resolver 1.5.6
+Resource Resolver 1.5.8
+Resource Resolver 1.6.0
+Resource Resolver 1.6.10
+Resource Resolver 1.6.4
+Resource Resolver 1.6.6
+Resource Resolver 1.6.8
+Rewriter 1.0.0
+Rewriter 1.0.2
+Rewriter 1.0.4
+Rewriter 1.1.0
+Rewriter 1.1.2
+Rewriter 1.1.4
+Rewriter 1.2.0
+Rewriter 1.2.2
+Rewriter 1.2.4
+SLF4J MDC Filter 1.0.0
+SLF4J MDC Filter 1.0.2
+Sample Integration Tests 1.0.6
+Sample Integration Tests 1.0.8
+Sample Server-Side Tests 1.0.6
+Sample Server-Side Tests 1.0.8
+Samples Fling 0.0.2
+Samples Simple Demo 2.0.2
+Samples Webloader Service 2.0.2
+Samples Webloader UI 2.0.2
+Scripting API 2.0.2
+Scripting API 2.1.0
+Scripting API 2.1.12
+Scripting API 2.1.2
+Scripting API 2.1.4
+Scripting API 2.1.6
+Scripting API 2.1.8
+Scripting API 2.2.0
+Scripting API 2.2.2
+Scripting Bundle Maven Plugin 0.1.0
+Scripting Bundle Tracker 0.1.0
+Scripting Console 1.0.0
+Scripting Console 1.0.2
+Scripting Core 2.0.10
+Scripting Core 2.0.14
+Scripting Core 2.0.16
+Scripting Core 2.0.18
+Scripting Core 2.0.2
+Scripting Core 2.0.20
+Scripting Core 2.0.22
+Scripting Core 2.0.24
+Scripting Core 2.0.26
+Scripting Core 2.0.28
+Scripting Core 2.0.30
+Scripting Core 2.0.32
+Scripting Core 2.0.34
+Scripting Core 2.0.36
+Scripting Core 2.0.38
+Scripting Core 2.0.4
+Scripting Core 2.0.40
+Scripting Core 2.0.44
+Scripting Core 2.0.46
+Scripting Core 2.0.48
+Scripting Core 2.0.50
+Scripting Core 2.0.52
+Scripting Core 2.0.54
+Scripting Core 2.0.56
+Scripting Core 2.0.58
+Scripting Core 2.0.6
+Scripting Core 2.0.8
+Scripting EL API Wrapper 1.0.0
+Scripting ESX 0.2.0
+Scripting FreeMarker 1.0.0
+Scripting FreeMarker 1.0.2
+Scripting Groovy 1.0.0
+Scripting Groovy 1.0.2
+Scripting Groovy 1.0.4
+Scripting Groovy 1.0.6
+Scripting HTL Compiler 1.0.0
+Scripting HTL Compiler 1.0.10
+Scripting HTL Compiler 1.0.12
+Scripting HTL Compiler 1.0.14
+Scripting HTL Compiler 1.0.16
+Scripting HTL Compiler 1.0.2
+Scripting HTL Compiler 1.0.20-1.3.1
+Scripting HTL Compiler 1.0.22-1.4.0
+Scripting HTL Compiler 1.0.4
+Scripting HTL Compiler 1.0.6
+Scripting HTL Compiler 1.0.8
+Scripting HTL Compiler 1.1.0-1.4.0
+Scripting HTL Compiler 1.1.2-1.4.0
+Scripting HTL Engine 1.0.20
+Scripting HTL Engine 1.0.22
+Scripting HTL Engine 1.0.24
+Scripting HTL Engine 1.0.26
+Scripting HTL Engine 1.0.28
+Scripting HTL Engine 1.0.30
+Scripting HTL Engine 1.0.32
+Scripting HTL Engine 1.0.34
+Scripting HTL Engine 1.0.36
+Scripting HTL Engine 1.0.38
+Scripting HTL Engine 1.0.40
+Scripting HTL Engine 1.0.42
+Scripting HTL Engine 1.0.44
+Scripting HTL Engine 1.0.46
+Scripting HTL Engine 1.0.48-1.3.1
+Scripting HTL Engine 1.0.52-1.3.1
+Scripting HTL Engine 1.0.54-1.4.0
+Scripting HTL Engine 1.0.56-1.4.0
+Scripting HTL Engine 1.1.0-1.4.0
+Scripting HTL Engine 1.1.2-1.4.0
+Scripting HTL JS Use Provider 1.0.12
+Scripting HTL JS Use Provider 1.0.14
+Scripting HTL JS Use Provider 1.0.16
+Scripting HTL JS Use Provider 1.0.18
+Scripting HTL JS Use Provider 1.0.20
+Scripting HTL JS Use Provider 1.0.22
+Scripting HTL JS Use Provider 1.0.24
+Scripting HTL JS Use Provider 1.0.26
+Scripting HTL JS Use Provider 1.0.28
+Scripting HTL Java Compiler 1.0.0
+Scripting HTL Java Compiler 1.0.10
+Scripting HTL Java Compiler 1.0.12
+Scripting HTL Java Compiler 1.0.14
+Scripting HTL Java Compiler 1.0.16
+Scripting HTL Java Compiler 1.0.18
+Scripting HTL Java Compiler 1.0.2
+Scripting HTL Java Compiler 1.0.22-1.3.1
+Scripting HTL Java Compiler 1.0.24-1.4.0
+Scripting HTL Java Compiler 1.0.26-1.4.0
+Scripting HTL Java Compiler 1.0.4
+Scripting HTL Java Compiler 1.0.6
+Scripting HTL Java Compiler 1.0.8
+Scripting HTL Java Compiler 1.1.0-1.4.0
+Scripting HTL Java Compiler 1.1.2-1.4.0
+Scripting HTL Models Use Provider 1.0.2
+Scripting HTL Models Use Provider 1.0.4
+Scripting HTL Models Use Provider 1.0.6
+Scripting HTL Models Use Provider 1.0.8
+Scripting HTL REPL 1.0.4
+Scripting HTL REPL 1.0.6
+Scripting HTL Runtime 1.0.0-1.4.0
+Scripting HTL Runtime 1.1.0-1.4.0
+Scripting HTL Testing 1.0.10-1.4.0
+Scripting HTL Testing 1.0.12-1.4.0
+Scripting HTL Testing 1.0.14-1.4.0
+Scripting HTL Testing 1.0.6-1.3.1
+Scripting HTL Testing 1.0.8-1.3.1
+Scripting HTL Testing Content 1.0.10-1.4.0
+Scripting HTL Testing Content 1.0.12-1.4.0
+Scripting HTL Testing Content 1.0.14-1.4.0
+Scripting HTL Testing Content 1.0.8-1.3.1
+Scripting JSP 2.0.10
+Scripting JSP 2.0.12
+Scripting JSP 2.0.14
+Scripting JSP 2.0.16
+Scripting JSP 2.0.18
+Scripting JSP 2.0.2
+Scripting JSP 2.0.20
+Scripting JSP 2.0.22
+Scripting JSP 2.0.24
+Scripting JSP 2.0.26
+Scripting JSP 2.0.28
+Scripting JSP 2.0.6
+Scripting JSP 2.0.8
+Scripting JSP 2.1.0
+Scripting JSP 2.1.4
+Scripting JSP 2.1.6
+Scripting JSP 2.1.8
+Scripting JSP 2.2.0
+Scripting JSP 2.2.2
+Scripting JSP 2.2.4
+Scripting JSP 2.2.6
+Scripting JSP 2.3.0
+Scripting JSP 2.3.2
+Scripting JSP 2.3.4
+Scripting JSP API Wrapper 1.0.0
+Scripting JSP Taglib 2.2.6
+Scripting JSP Taglib 2.3.0
+Scripting JSP Taglib 2.4.0
+Scripting JSP Taglib 2.4.2
+Scripting JSP Taglib Compat 1.0.0
+Scripting JSP-Atom-Taglib 1.0.0
+Scripting JSP-Taglib 2.0.2
+Scripting JSP-Taglib 2.0.4
+Scripting JSP-Taglib 2.0.6
+Scripting JSP-Taglib 2.1.0
+Scripting JSP-Taglib 2.1.2
+Scripting JSP-Taglib 2.1.6
+Scripting JSP-Taglib 2.1.8
+Scripting JSP-Taglib 2.2.0
+Scripting JSP-Taglib 2.2.2
+Scripting JSP-Taglib 2.2.4
+Scripting JSP-Taglib 2.2.6
+Scripting JST 2.0.4
+Scripting JST 2.0.6
+Scripting JST 2.0.8
+Scripting Java 1.0.0
+Scripting Java 2.0.0
+Scripting Java 2.0.10
+Scripting Java 2.0.12
+Scripting Java 2.0.14
+Scripting Java 2.0.2
+Scripting Java 2.0.4
+Scripting Java 2.0.6
+Scripting Java 2.1.0
+Scripting Java 2.1.2
+Scripting Java 2.1.4
+Scripting JavaScript 2.0.10
+Scripting JavaScript 2.0.12
+Scripting JavaScript 2.0.14
+Scripting JavaScript 2.0.16
+Scripting JavaScript 2.0.18
+Scripting JavaScript 2.0.2
+Scripting JavaScript 2.0.20
+Scripting JavaScript 2.0.22
+Scripting JavaScript 2.0.24
+Scripting JavaScript 2.0.26
+Scripting JavaScript 2.0.28
+Scripting JavaScript 2.0.30
+Scripting JavaScript 2.0.6
+Scripting JavaScript 2.0.8
+Scripting JavaScript 3.0.0
+Scripting JavaScript 3.0.2
+Scripting JavaScript 3.0.4
+Scripting JavaScript 3.0.6
+Scripting Scala 1.0.0
+Scripting Sightly Engine 1.0.0
+Scripting Sightly Engine 1.0.10
+Scripting Sightly Engine 1.0.12
+Scripting Sightly Engine 1.0.14
+Scripting Sightly Engine 1.0.16
+Scripting Sightly Engine 1.0.18
+Scripting Sightly Engine 1.0.2
+Scripting Sightly Engine 1.0.4
+Scripting Sightly Engine 1.0.6
+Scripting Sightly JS Use Provider 1.0.0
+Scripting Sightly JS Use Provider 1.0.10
+Scripting Sightly JS Use Provider 1.0.4
+Scripting Sightly JS Use Provider 1.0.6
+Scripting Sightly JS Use Provider 1.0.8
+Scripting Sightly Models Use Provider 1.0.0
+Scripting Sightly REPL 1.0.0
+Scripting Sightly REPL 1.0.2
+Scripting Thymeleaf 0.0.2
+Scripting Thymeleaf 0.0.4
+Scripting Thymeleaf 0.0.6
+Scripting Thymeleaf 1.0.0
+Scripting Thymeleaf 1.1.0
+Scripting Thymeleaf 2.0.0
+Scripting Thymeleaf 2.0.2
+Scripting Velocity 2.0.0
+Scripting Velocity 2.0.2
+Security 1.0.0
+Security 1.0.10
+Security 1.0.12
+Security 1.0.14
+Security 1.0.16
+Security 1.0.18
+Security 1.0.2
+Security 1.0.4
+Security 1.0.6
+Security 1.0.8
+Security 1.1.0
+Security 1.1.10
+Security 1.1.12
+Security 1.1.16
+Security 1.1.18
+Security 1.1.2
+Security 1.1.4
+Security 1.1.6
+Security 1.1.8
+Service User Mapper 1.0.0
+Service User Mapper 1.0.2
+Service User Mapper 1.0.4
+Service User Mapper 1.1.0
+Service User Mapper 1.2.0
+Service User Mapper 1.2.2
+Service User Mapper 1.2.4
+Service User Mapper 1.2.6
+Service User Mapper 1.3.0
+Service User Mapper 1.3.2
+Service User Mapper 1.3.4
+Service User Mapper 1.3.6
+Service User Mapper 1.4.0
+Service User Mapper 1.4.2
+Service User Mapper 1.4.4
+Service User Mapper 1.4.6
+Service User WebConsole 1.0.2
+Servlet Archetype 1.0.0
+Servlet Archetype 1.0.2
+Servlet Archetype 1.0.4
+Servlet Archetype 1.0.6
+Servlet Helpers 1.0.0
+Servlet Helpers 1.0.2
+Servlet Helpers 1.1.0
+Servlet Helpers 1.1.10
+Servlet Helpers 1.1.12
+Servlet Helpers 1.1.2
+Servlet Helpers 1.1.4
+Servlet Helpers 1.1.6
+Servlet Helpers 1.1.8
+Servlets Compat 1.0.0
+Servlets Get 2.0.2
+Servlets Get 2.0.4
+Servlets Get 2.0.6
+Servlets Get 2.0.8
+Servlets Get 2.1.0
+Servlets Get 2.1.10
+Servlets Get 2.1.12
+Servlets Get 2.1.14
+Servlets Get 2.1.18
+Servlets Get 2.1.2
+Servlets Get 2.1.20
+Servlets Get 2.1.22
+Servlets Get 2.1.24
+Servlets Get 2.1.26
+Servlets Get 2.1.28
+Servlets Get 2.1.30
+Servlets Get 2.1.32
+Servlets Get 2.1.34
+Servlets Get 2.1.36
+Servlets Get 2.1.38
+Servlets Get 2.1.4
+Servlets Get 2.1.40
+Servlets Get 2.1.42
+Servlets Get 2.1.6
+Servlets Get 2.1.8
+Servlets Post 2.0.2
+Servlets Post 2.0.4
+Servlets Post 2.1.0
+Servlets Post 2.1.2
+Servlets Post 2.2.0
+Servlets Post 2.3.0
+Servlets Post 2.3.10
+Servlets Post 2.3.12
+Servlets Post 2.3.14
+Servlets Post 2.3.16
+Servlets Post 2.3.18
+Servlets Post 2.3.2
+Servlets Post 2.3.20
+Servlets Post 2.3.22
+Servlets Post 2.3.24
+Servlets Post 2.3.26
+Servlets Post 2.3.28
+Servlets Post 2.3.30
+Servlets Post 2.3.4
+Servlets Post 2.3.6
+Servlets Post 2.3.8
+Servlets Resolver 2.0.4
+Servlets Resolver 2.0.8
+Servlets Resolver 2.1.0
+Servlets Resolver 2.1.2
+Servlets Resolver 2.2.0
+Servlets Resolver 2.2.4
+Servlets Resolver 2.3.0
+Servlets Resolver 2.3.2
+Servlets Resolver 2.3.4
+Servlets Resolver 2.3.6
+Servlets Resolver 2.3.8
+Servlets Resolver 2.4.0
+Servlets Resolver 2.4.10
+Servlets Resolver 2.4.12
+Servlets Resolver 2.4.14
+Servlets Resolver 2.4.2
+Servlets Resolver 2.4.20
+Servlets Resolver 2.4.22
+Servlets Resolver 2.4.24
+Servlets Resolver 2.4.4
+Servlets Resolver 2.4.6
+Servlets Resolver 2.4.8
+Servlets Resolver 2.5.2
+Settings 1.0.0
+Settings 1.0.2
+Settings 1.1.0
+Settings 1.2.0
+Settings 1.2.2
+Settings 1.3.0
+Settings 1.3.10
+Settings 1.3.12
+Settings 1.3.2
+Settings 1.3.4
+Settings 1.3.6
+Settings 1.3.8
+Sling Eclipse IDE 1.0.0
+Sling Eclipse IDE 1.0.10
+Sling Eclipse IDE 1.0.2
+Sling Eclipse IDE 1.0.4
+Sling Eclipse IDE 1.0.6
+Sling Eclipse IDE 1.0.8
+Sling Eclipse IDE 1.1.0
+Sling Eclipse IDE 1.2.0
+Sling Eclipse IDE 1.2.2
+Sling Eclipse IDE 1.2.4
+Sling Explorer 1.0.0
+Sling Explorer 1.0.2
+Sling Explorer 1.0.4
+Sling Explorer 1.0.6
+Sling JUnit Performance 1.0.2
+Sling JUnit Performance 1.0.4
+Sling Maven Plugin 2.4.0
+Sling Maven Plugin 2.4.2
+Sling Models API 1.0.0
+Sling Models API 1.0.2
+Sling Models API 1.1.0
+Sling Models API 1.2.0
+Sling Models API 1.2.2
+Sling Models API 1.3.0
+Sling Models API 1.3.10
+Sling Models API 1.3.2
+Sling Models API 1.3.4
+Sling Models API 1.3.6
+Sling Models API 1.3.8
+Sling Models Impl 1.2.0
+Sling Models Impl 1.2.2
+Sling Models Impl 1.2.4
+Sling Models Impl 1.2.6
+Sling Models Impl 1.2.8
+Sling Models Impl 1.3.0
+Sling Models Impl 1.3.2
+Sling Models Impl 1.3.4
+Sling Models Impl 1.3.6
+Sling Models Impl 1.3.8
+Sling Models Impl 1.4.0
+Sling Models Impl 1.4.10
+Sling Models Impl 1.4.12
+Sling Models Impl 1.4.2
+Sling Models Impl 1.4.4
+Sling Models Impl 1.4.6
+Sling Models Impl 1.4.8
+Sling Models Implementation 1.0.0
+Sling Models Implementation 1.0.2
+Sling Models Implementation 1.0.4
+Sling Models Implementation 1.0.6
+Sling Models Implementation 1.1.0
+Sling Models Jackson Exporter 1.0.0
+Sling Models Jackson Exporter 1.0.10
+Sling Models Jackson Exporter 1.0.2
+Sling Models Jackson Exporter 1.0.4
+Sling Models Jackson Exporter 1.0.6
+Sling Models Jackson Exporter 1.0.8
+Sling Models Validation Impl 1.0.0
+Sling Models bnd Plugin 1.0.0
+Sling Pax Exam Utilities 1.0.2
+Sling Pax Exam Utilities 1.0.4
+Sling Pax Exam Utilities 1.0.6
+Sling Provisioning Model 1.0.0
+Sling Provisioning Model 1.1.0
+Sling Provisioning Model 1.2.0
+Sling Provisioning Model 1.3.0
+Sling Provisioning Model 1.4.0
+Sling Provisioning Model 1.4.2
+Sling Provisioning Model 1.4.4
+Sling Provisioning Model 1.5.0
+Sling Provisioning Model 1.6.0
+Sling Provisioning Model 1.7.0
+Sling Provisioning Model 1.8.0
+Sling Provisioning Model 1.8.2
+Sling Provisioning Model 1.8.4
+Sling Provisioning Model 1.8.6
+Sling Query 2.0.0
+Sling Query 3.0.0
+Sling Query 4.0.0
+Sling Query 4.0.2
+Sling Query 4.0.4
+Sling Servlet Annotations 1.0.0
+Sling Servlet Annotations 1.1.0
+Sling Servlet Annotations 1.2.4
+Slingshot 0.8.0
+Slingshot 0.9.0
+Slingshot 0.9.2
+Slingstart Archetype 1.0.0
+Slingstart Archetype 1.0.2
+Slingstart Archetype 1.0.6
+Slingstart Archetype 1.0.8
+Slingstart Maven Plugin 1.0.0
+Slingstart Maven Plugin 1.0.2
+Slingstart Maven Plugin 1.0.4
+Slingstart Maven Plugin 1.1.0
+Slingstart Maven Plugin 1.2.0
+Slingstart Maven Plugin 1.3.0
+Slingstart Maven Plugin 1.3.2
+Slingstart Maven Plugin 1.3.4
+Slingstart Maven Plugin 1.3.6
+Slingstart Maven Plugin 1.4.0
+Slingstart Maven Plugin 1.4.2
+Slingstart Maven Plugin 1.4.4
+Slingstart Maven Plugin 1.5.0
+Slingstart Maven Plugin 1.6.0
+Slingstart Maven Plugin 1.7.0
+Slingstart Maven Plugin 1.7.10
+Slingstart Maven Plugin 1.7.14
+Slingstart Maven Plugin 1.7.16
+Slingstart Maven Plugin 1.7.2
+Slingstart Maven Plugin 1.7.4
+Slingstart Maven Plugin 1.7.6
+Slingstart Maven Plugin 1.7.8
+Slingstart Maven Plugin 1.8.2
+Slingstart Maven Plugin 1.8.4
+Starter 10
+Starter 11
+Starter 12
+Starter Content 1.0.0
+Starter Content 1.0.2
+Starter Content 1.0.4
+Starter Startup 1.0.2
+Starter Startup 1.0.4
+Starter Startup 1.0.6
+Starter Startup 1.0.8
+Superimposing Resource Provider 0.2.0
+Superimposing Resource Provider 0.4.0
+Taglib Archetype 1.0.0
+Tenant 1.0.0
+Tenant 1.0.2
+Tenant 1.1.0
+Tenant 1.1.2
+Tenant 1.1.4
+Tenant 1.1.6
+Testing Clients 1.1.6
+Testing Email 1.0.0
+Testing Email 1.0.2
+Testing Hamcrest 1.0.0
+Testing Hamcrest 1.0.2
+Testing Hamcrest 1.0.4
+Testing JCR Mock 1.0.0
+Testing JCR Mock 1.1.0
+Testing JCR Mock 1.1.10
+Testing JCR Mock 1.1.12
+Testing JCR Mock 1.1.14
+Testing JCR Mock 1.1.16
+Testing JCR Mock 1.1.2
+Testing JCR Mock 1.1.4
+Testing JCR Mock 1.1.6
+Testing JCR Mock 1.1.8
+Testing JCR Mock 1.2.0
+Testing JCR Mock 1.3.0
+Testing JCR Mock 1.3.2
+Testing JCR Mock 1.3.4
+Testing JCR Mock 1.3.6
+Testing JCR Mock 1.4.0
+Testing JCR Mock 1.4.2
+Testing JCR Mock 1.4.4
+Testing JCR Mock 1.4.6
+Testing Logging Mock 1.0.0
+Testing Logging Mock 2.0.0
+Testing Logging Mock 2.0.2
+Testing OSGi Mock 1.0.0
+Testing OSGi Mock 1.1.0
+Testing OSGi Mock 1.2.0
+Testing OSGi Mock 1.3.0
+Testing OSGi Mock 1.4.0
+Testing OSGi Mock 1.5.0
+Testing OSGi Mock 1.6.0
+Testing OSGi Mock 1.7.0
+Testing OSGi Mock 1.7.2
+Testing OSGi Mock 1.8.0
+Testing OSGi Mock 1.9.0
+Testing OSGi Mock 1.9.2
+Testing OSGi Mock 1.9.4
+Testing OSGi Mock 1.9.6
+Testing OSGi Mock 1.9.8
+Testing OSGi Mock 2.0.0
+Testing OSGi Mock 2.0.2
+Testing OSGi Mock 2.0.4
+Testing OSGi Mock 2.1.0
+Testing OSGi Mock 2.2.0
+Testing OSGi Mock 2.2.2
+Testing OSGi Mock 2.2.4
+Testing OSGi Mock 2.3.0
+Testing OSGi Mock 2.3.10
+Testing OSGi Mock 2.3.2
+Testing OSGi Mock 2.3.4
+Testing OSGi Mock 2.3.6
+Testing OSGi Mock 2.3.8
+Testing OSGi Mock 2.4.0
+Testing OSGi Mock 2.4.10
+Testing OSGi Mock 2.4.2
+Testing OSGi Mock 2.4.4
+Testing OSGi Mock 2.4.6
+Testing OSGi Mock 2.4.8
+Testing PaxExam 0.0.2
+Testing PaxExam 0.0.4
+Testing PaxExam 1.0.0
+Testing PaxExam 2.0.0
+Testing PaxExam 3.0.0
+Testing ResourceResolver Mock 0.1.0
+Testing ResourceResolver Mock 0.2.0
+Testing ResourceResolver Mock 0.3.0
+Testing ResourceResolver Mock 1.0.0
+Testing ResourceResolver Mock 1.1.0
+Testing ResourceResolver Mock 1.1.10
+Testing ResourceResolver Mock 1.1.12
+Testing ResourceResolver Mock 1.1.14
+Testing ResourceResolver Mock 1.1.16
+Testing ResourceResolver Mock 1.1.18
+Testing ResourceResolver Mock 1.1.2
+Testing ResourceResolver Mock 1.1.20
+Testing ResourceResolver Mock 1.1.22
+Testing ResourceResolver Mock 1.1.24
+Testing ResourceResolver Mock 1.1.26
+Testing ResourceResolver Mock 1.1.4
+Testing ResourceResolver Mock 1.1.6
+Testing ResourceResolver Mock 1.1.8
+Testing Rules 1.0.0
+Testing Sling Mock 1.0.0
+Testing Sling Mock 1.1.0
+Testing Sling Mock 1.1.2
+Testing Sling Mock 1.2.0
+Testing Sling Mock 1.3.0
+Testing Sling Mock 1.4.0
+Testing Sling Mock 1.5.0
+Testing Sling Mock 1.6.0
+Testing Sling Mock 1.6.2
+Testing Sling Mock 1.7.0
+Testing Sling Mock 1.8.0
+Testing Sling Mock 1.9.0
+Testing Sling Mock 1.9.10
+Testing Sling Mock 1.9.12
+Testing Sling Mock 1.9.2
+Testing Sling Mock 1.9.4
+Testing Sling Mock 1.9.6
+Testing Sling Mock 1.9.8
+Testing Sling Mock 2.0.0
+Testing Sling Mock 2.1.0
+Testing Sling Mock 2.1.2
+Testing Sling Mock 2.2.0
+Testing Sling Mock 2.2.10
+Testing Sling Mock 2.2.12
+Testing Sling Mock 2.2.14
+Testing Sling Mock 2.2.16
+Testing Sling Mock 2.2.18
+Testing Sling Mock 2.2.2
+Testing Sling Mock 2.2.20
+Testing Sling Mock 2.2.4
+Testing Sling Mock 2.2.6
+Testing Sling Mock 2.2.8
+Testing Sling Mock 2.3.0
+Testing Sling Mock 2.3.2
+Testing Sling Mock 2.3.4
+Testing Sling Mock 2.3.6
+Testing Sling Mock Jackrabbit 0.1.0
+Testing Sling Mock Jackrabbit 0.1.2
+Testing Sling Mock Jackrabbit 1.0.0
+Testing Sling Mock Oak 1.0.0
+Testing Sling Mock Oak 1.0.2
+Testing Sling Mock Oak 2.0.0
+Testing Sling Mock Oak 2.0.2
+Testing Sling Mock Oak 2.1.0
+Testing Sling Mock Oak 2.1.2
+Testing Sling Mock Oak 2.1.4
+Tooling Support Install 1.0.0
+Tooling Support Install 1.0.2
+Tooling Support Install 1.0.4
+Tooling Support Install 1.0.6
+Tooling Support Source 1.0.0
+Tooling Support Source 1.0.2
+Tooling Support Source 1.0.4
+Tooling Support Source 1.0.6
+URL Rewriter 0.0.2
+URL Rewriter 0.0.4
+Validation 1.0.0
+Validation API 1.0.2
+Validation Core 1.0.4
+Validation Core 1.0.6
+Version App CMS 0.11.4
+Web Console Security Provider 1.0.0
+Web Console Security Provider 1.1.0
+Web Console Security Provider 1.1.2
+Web Console Security Provider 1.1.4
+Web Console Security Provider 1.1.6
+Web Console Security Provider 1.2.0
+Web Console Security Provider 1.2.2
+XSS Protection API 1.0.0
+XSS Protection API 1.0.12
+XSS Protection API 1.0.14
+XSS Protection API 1.0.16
+XSS Protection API 1.0.18
+XSS Protection API 1.0.2
+XSS Protection API 1.0.4
+XSS Protection API 1.0.6
+XSS Protection API 1.0.8
+XSS Protection API 2.0.0
+XSS Protection API 2.0.10
+XSS Protection API 2.0.12
+XSS Protection API 2.0.14
+XSS Protection API 2.0.4
+XSS Protection API 2.0.6
+XSS Protection API 2.0.8
+XSS Protection API 2.1.0
+XSS Protection API 2.1.4
+XSS Protection API 2.2.0
+XSS Protection API Compat 1.1.0
+bnd Plugins 0.0.2
+commons metrics 1.2.4
+i18n 2.2.10
+i18n 2.2.2
+i18n 2.2.4
+i18n 2.2.6
+i18n 2.2.8
+i18n 2.3.2
+i18n 2.4.10
+i18n 2.4.2
+i18n 2.4.4
+i18n 2.4.6
+i18n 2.4.8
+i18n 2.5.0
+i18n 2.5.10
+i18n 2.5.12
+i18n 2.5.14
+i18n 2.5.2
+i18n 2.5.4
+i18n 2.5.6
+i18n 2.5.8
+javax.activation 0.1.0
+javax.activation 0.2.0
+org.apache.sling.testing.tools 1.0.10
+org.apache.sling.testing.tools 1.0.12
+org.apache.sling.testing.tools 1.0.14
+org.apache.sling.testing.tools 1.0.16
+org.apache.sling.testing.tools 1.0.4
+org.apache.sling.testing.tools 1.0.6
+org.apache.sling.testing.tools 1.0.8
+slingfeature-maven-plugin 0.8.0
+slingfeature-maven-plugin 1.0.0


[sling-org-apache-sling-committer-cli] 02/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit d37ac21fe621edbdd86d6e637cca45d712af2616
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Mar 8 14:06:42 2019 +0200

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Document assumptions.
---
 README.md | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index eaa6d43..af04f3f 100644
--- a/README.md
+++ b/README.md
@@ -20,4 +20,13 @@ This invocation produces a list of available subcommands.
 
 Currently the only implemented command is generating the release vote email, for instance
 
-    docker run --env-file=./docker-env apache/sling-cli release prepare-email $STAGING_REPOSITORY_ID
\ No newline at end of file
+    docker run --env-file=./docker-env apache/sling-cli release prepare-email $STAGING_REPOSITORY_ID
+    
+## Assumptions
+
+This tool assumes that the name of the staging repository matches the one of the version in Jira. For instance, the
+staging repositories are usually named _Apache Sling Foo 1.2.0_. It is then expected that the Jira version is
+named _Foo 1.2.0_. Otherwise the link between the staging repository and the Jira release can not be found.
+
+It is allowed for staging repository names to have an _RC_ suffix, which may include a number, so that _RC_, _RC1_, _RC25_ are
+all valid suffixes.  
\ No newline at end of file


[sling-org-apache-sling-committer-cli] 14/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 7a4c927f8b9396ece2ca91b09b5454f0c3af430d
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Wed Mar 27 15:42:54 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * improved email templates to contain the full name of the current user
---
 .../org/apache/sling/cli/impl/people/MembersFinder.java    | 14 ++++++++++++++
 .../sling/cli/impl/release/PrepareVoteEmailCommand.java    | 13 +++++++++++--
 .../apache/sling/cli/impl/release/TallyVotesCommand.java   |  7 +------
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
index 10cba19..a27bf6c 100644
--- a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
+++ b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
@@ -107,4 +107,18 @@ public class MembersFinder {
         return null;
     }
 
+    public Member getCurrentMember() {
+        final String currentUserId;
+        if (System.getProperty("asf.username") != null) {
+            currentUserId = System.getProperty("asf.username");
+        } else {
+            currentUserId = System.getenv("ASF_USERNAME");
+        }
+        if (currentUserId == null) {
+            throw new IllegalStateException(String.format("Expected to find the current user defined either through the %s system " +
+                    "property or through the %s environment variable.", "asf.username", "ASF_USERNAME"));
+        }
+         return getMemberById(currentUserId);
+    }
+
 }
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 9819107..21b72f8 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
@@ -23,6 +23,7 @@ import org.apache.sling.cli.impl.jira.Version;
 import org.apache.sling.cli.impl.jira.VersionFinder;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
 import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
+import org.apache.sling.cli.impl.people.MembersFinder;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
@@ -34,6 +35,9 @@ import org.slf4j.LoggerFactory;
     Command.PROPERTY_NAME_SUMMARY + "=Prepares an email vote for the specified release." })
 public class PrepareVoteEmailCommand implements Command {
 
+    @Reference
+    private MembersFinder membersFinder;
+
     // TODO - replace with file template
     private static final String EMAIL_TEMPLATE ="To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
             "Subject: [VOTE] Release ##RELEASE_NAME##\n" + 
@@ -58,7 +62,11 @@ public class PrepareVoteEmailCommand implements Command {
             "  [ ]  0 Don't care\n" + 
             "  [ ] -1 Don't release, because ...\n" + 
             "\n" + 
-            "This majority vote is open for at least 72 hours.\n";
+            "This majority vote is open for at least 72 hours.\n" +
+            "\n" +
+            "Regards,\n" +
+            "##USER_NAME##\n" +
+            "\n";
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
     
@@ -80,7 +88,8 @@ public class PrepareVoteEmailCommand implements Command {
                     .replace("##RELEASE_NAME##", release.getFullName())
                     .replace("##RELEASE_ID##", String.valueOf(repoId))
                     .replace("##VERSION_ID##", String.valueOf(version.getId()))
-                    .replace("##FIXED_ISSUES_COUNT##", String.valueOf(version.getIssuesFixedCount()));
+                    .replace("##FIXED_ISSUES_COUNT##", String.valueOf(version.getIssuesFixedCount()))
+                    .replace("##USER_NAME##", membersFinder.getCurrentMember().getName());
                     
             logger.info(emailContents);
 
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 74cdd23..90244eb 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
@@ -95,15 +95,10 @@ public class TallyVotesCommand implements Command {
                     }
                 }
             }
-            String currentUserId = System.getProperty("asf.username");
-            if (currentUserId == null) {
-                currentUserId = System.getenv("ASF_USERNAME");
-            }
-            Member currentUser = membersFinder.getMemberById(currentUserId);
             String email = EMAIL_TEMPLATE
                 .replace("##RELEASE_NAME##", release.getFullName())
                 .replace("##BINDING_VOTERS##", String.join(", ", bindingVoters))
-                .replace("##USER_NAME##", currentUser == null ? "" : currentUser.getName());
+                .replace("##USER_NAME##", membersFinder.getCurrentMember().getName());
             if (nonBindingVoters.isEmpty()) {
                 email = email.replace("##NON_BINDING_VOTERS##", "none");
             } else {


[sling-org-apache-sling-committer-cli] 01/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit abbd20f172a25e5e51ab75fa06c15fc1f8f9231f
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Mar 8 13:56:17 2019 +0200

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Prototype of sling cli tool.
---
 .gitignore                                         |   1 +
 Dockerfile                                         |  30 ++++
 README.md                                          |  23 +++
 bnd.bnd                                            |   0
 docker-env.sample                                  |  15 ++
 pom.xml                                            | 173 +++++++++++++++++++++
 src/main/features/app.json                         |  67 ++++++++
 .../java/org/apache/sling/cli/impl/Command.java    |  26 ++++
 .../apache/sling/cli/impl/CommandProcessor.java    | 143 +++++++++++++++++
 .../apache/sling/cli/impl/ExecutionTrigger.java    |  37 +++++
 .../org/apache/sling/cli/impl/jira/Version.java    |  47 ++++++
 .../apache/sling/cli/impl/jira/VersionFinder.java  |  98 ++++++++++++
 .../sling/cli/impl/nexus/StagingRepositories.java  |  33 ++++
 .../sling/cli/impl/nexus/StagingRepository.java    |  65 ++++++++
 .../cli/impl/nexus/StagingRepositoryFinder.java    |  86 ++++++++++
 .../cli/impl/release/PrepareVoteEmailCommand.java  |  98 ++++++++++++
 .../sling/cli/impl/release/TallyVotesCommand.java  |  39 +++++
 src/main/resources/conf/logback-default.xml        |  23 +++
 src/main/resources/scripts/launcher.sh             |  29 ++++
 .../impl/release/PrepareVoteEmailCommandTest.java  |  31 ++++
 20 files changed, 1064 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a49f72d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+docker-env
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..1338fcb
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,30 @@
+# ----------------------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+# agreements. See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file to you 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.
+# ----------------------------------------------------------------------------------------
+
+FROM openjdk:8-jre-alpine
+MAINTAINER dev@sling.apache.org
+# escaping required to properly handle arguments with spaces
+ENTRYPOINT ["/usr/share/sling-cli/bin/launcher.sh"]
+
+# Add feature launcher
+ADD target/lib /usr/share/sling-cli/launcher
+# Add launcher script
+ADD target/classes/scripts /usr/share/sling-cli/bin
+# workaround for MRESOURCES-236
+RUN chmod a+x /usr/share/sling-cli/bin/*
+# Add config files
+ADD target/classes/conf /usr/share/sling-cli/conf
+# Add all bundles
+ADD target/artifacts /usr/share/sling-cli/artifacts
+# Add the service itself
+ARG FEATURE_FILE
+ADD ${FEATURE_FILE} /usr/share/sling-cli/sling-cli.feature
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..eaa6d43
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# Apache Sling Engine CLI tool
+
+This module is part of the [Apache Sling](https://sling.apache.org) project.
+
+This module provides a command-line tool which automates various Sling development tasks. The tool is packaged
+as a docker image.
+
+## Configuration
+
+To make various credentials and configurations available to the docker image it is recommended to use a docker env file.
+A sample file is stored at `docker-env.sample`. Copy this file to `docker-env` and fill in your own information.
+
+## Launching
+
+The image is built using `mvn package`. Afterwards it may be run with
+
+    docker run --env-file=./docker-env apache/sling-cli
+    
+This invocation produces a list of available subcommands.
+
+Currently the only implemented command is generating the release vote email, for instance
+
+    docker run --env-file=./docker-env apache/sling-cli release prepare-email $STAGING_REPOSITORY_ID
\ No newline at end of file
diff --git a/bnd.bnd b/bnd.bnd
new file mode 100644
index 0000000..e69de29
diff --git a/docker-env.sample b/docker-env.sample
new file mode 100644
index 0000000..15454cf
--- /dev/null
+++ b/docker-env.sample
@@ -0,0 +1,15 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+# agreements. See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file to you 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.
+# ----------------------------------------------------------------------------------------
+ASF_USERNAME=changeme
+ASF_PASSWORD=changeme
+RELEASE_ID=42
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..047121d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+    license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to 
+    you 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. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>34</version>
+        <relativePath />
+    </parent>
+
+    <artifactId>sling-cli</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <description>Sling CLI tool for development usage</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>biz.aQute.bnd</groupId>
+                <artifactId>bnd-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <classpathPrefix>lib/</classpathPrefix>
+                            <mainClass>org.apache.sling.cli.impl.Main</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <overWriteReleases>false</overWriteReleases>
+                            <includeScope>runtime</includeScope>
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
+                            <stripVersion>true</stripVersion>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>slingfeature-maven-plugin</artifactId>
+                <version>0.8.0</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <id>feature-dependencies</id>
+                        <goals>
+                            <goal>repository</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>extra-dependencies</id>
+                        <goals>
+                            <goal>repository</goal>
+                        </goals>
+                        <configuration>
+                            <repositories>
+                                <repository>
+                                    <embedArtifacts>
+                                        <embedArtifact>
+                                            <groupId>org.apache.felix</groupId>
+                                            <artifactId>org.apache.felix.framework</artifactId>
+                                            <version>6.0.2</version>
+                                        </embedArtifact>
+                                        <embedArtifact>
+                                            <groupId>org.apache.sling</groupId>
+                                            <artifactId>org.apache.sling.launchpad.api</artifactId>
+                                            <version>1.2.0</version>
+                                        </embedArtifact>
+                                    </embedArtifacts>
+                                </repository>
+                            </repositories>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.spotify</groupId>
+                <artifactId>dockerfile-maven-plugin</artifactId>
+                <version>1.4.10</version>
+                <executions>
+                    <execution>
+                        <id>default</id>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <skipDockerInfo>true</skipDockerInfo> <!-- does not contain legal files -->
+                    <repository>apache/sling-cli</repository>
+                    <buildArgs>
+                        <FEATURE_FILE>target/artifacts/org/apache/sling/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}-app.slingfeature</FEATURE_FILE>
+                    </buildArgs>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.metatype.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.feature.launcher</artifactId>
+            <version>0.8.0</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient-osgi</artifactId>
+            <version>4.5.7</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.5</version>
+            <scope>provided</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/features/app.json b/src/main/features/app.json
new file mode 100644
index 0000000..f07827d
--- /dev/null
+++ b/src/main/features/app.json
@@ -0,0 +1,67 @@
+{
+	"id": "${project.groupId}:${project.artifactId}:slingfeature:app:${project.version}",
+	"variables": {
+    	"asf.username":"change-me",
+    	"asf.password": "change-me"
+    },
+	"bundles": [
+		{
+			"id": "${project.groupId}:${project.artifactId}:${project.version}",
+			"start-level": "5"
+		},
+		{
+			"id": "org.apache.felix:org.apache.felix.scr:2.1.12",
+			"start-level": "1"
+		},
+		{
+			"id": "org.apache.felix:org.apache.felix.configadmin:1.9.10",
+			"start-level": "1"
+		},
+		{
+			"id": "org.apache.felix:org.apache.felix.log:1.2.0",
+			"start-level": "1"
+		},
+		{
+			"id": "ch.qos.logback:logback-classic:1.2.3",
+			"start-level": "1"
+		},
+		{
+			"id": "ch.qos.logback:logback-core:1.2.3",
+			"start-level": "1"
+		},
+		{
+			"id": "org.slf4j:jul-to-slf4j:1.7.25",
+			"start-level": "1"
+		},
+		{
+			"id": "org.slf4j:jcl-over-slf4j:1.7.25",
+			"start-level": "1"
+		},
+		{
+			"id": "org.slf4j:slf4j-api:1.7.25",
+			"start-level": "1"
+		},
+		{
+			"id": "org.apache.felix:org.apache.felix.logback:1.0.2",
+			"start-level": "1"
+		},
+		{
+			"id": "org.apache.httpcomponents:httpcore-osgi:4.4.11",
+			"start-level": "3"
+		},
+		{
+			"id": "org.apache.httpcomponents:httpclient-osgi:4.5.7",
+			"start-level": "3"
+		},
+		{
+			"id": "com.google.code.gson:gson:2.8.5",
+			"start-level": "3"
+		}
+	],
+	"configurations": {
+		"org.apache.sling.cli.impl.nexus.StagingRepositoryFinder": {
+			"username": "${asf.username}",
+			"password": "${asf.password}"
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/cli/impl/Command.java b/src/main/java/org/apache/sling/cli/impl/Command.java
new file mode 100644
index 0000000..4caeea7
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/Command.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl;
+
+public interface Command {
+    
+    String PROPERTY_NAME_COMMAND = "command";
+    String PROPERTY_NAME_SUBCOMMAND = "subcommand";
+    String PROPERTY_NAME_SUMMARY = "summary";
+
+    void execute(String target);
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java b/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
new file mode 100644
index 0000000..57e5430
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl;
+
+import static org.osgi.service.component.annotations.ReferenceCardinality.MULTIPLE;
+import static org.osgi.service.component.annotations.ReferencePolicy.DYNAMIC;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.launch.Framework;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = CommandProcessor.class)
+public class CommandProcessor {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+    private BundleContext ctx;
+
+    private Map<CommandKey, CommandWithProps> commands = new ConcurrentHashMap<>();
+
+    protected void activate(BundleContext ctx) {
+        this.ctx = ctx;
+    }
+
+    @Reference(service = Command.class, cardinality = MULTIPLE, policy = DYNAMIC)
+    protected void bindCommand(Command cmd, Map<String, ?> props) {
+        commands.put(CommandKey.of(props), CommandWithProps.of(cmd, props));
+    }
+
+    protected void unbindCommand(Map<String, ?> props) {
+        commands.remove(CommandKey.of(props));
+    }
+
+    public void runCommand() {
+        // TODO - remove duplication from CLI parsing code
+        CommandKey key = CommandKey.of(ctx.getProperty("exec.args"));
+        String target = parseTarget(ctx.getProperty("exec.args"));
+        commands.getOrDefault(key, new CommandWithProps(ignored -> {
+            logger.info("Usage: sling command sub-command [target]");
+            logger.info("");
+            logger.info("Available commands:");
+            commands.forEach((k, c) -> logger.info("{} {}: {}", k.command, k.subCommand, c.summary));
+        }, "")).cmd.execute(target);
+        try {
+            ctx.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(Framework.class).stop();
+        } catch (BundleException e) {
+            logger.warn("Failed running command", e);
+        }
+    }
+
+    private String parseTarget(String cliSpec) {
+        if (cliSpec == null || cliSpec.isEmpty())
+            return null;
+
+        String[] args = cliSpec.split(" ");
+        if (args.length < 3)
+            return null;
+        
+        return args[2];
+    }
+    
+
+    static class CommandKey {
+
+        private static final CommandKey EMPTY = new CommandKey("", "");
+
+        private final String command;
+        private final String subCommand;
+
+        static CommandKey of(String cliSpec) {
+            if (cliSpec == null || cliSpec.isEmpty())
+                return EMPTY;
+
+            String[] args = cliSpec.split(" ");
+            if (args.length < 2)
+                return EMPTY;
+
+            return new CommandKey(args[0], args[1]);
+        }
+
+        static CommandKey of(Map<String, ?> serviceProps) {
+            return new CommandKey((String) serviceProps.get(Command.PROPERTY_NAME_COMMAND), (String) serviceProps.get(Command.PROPERTY_NAME_SUBCOMMAND));
+        }
+
+        CommandKey(String command, String subCommand) {
+            this.command = command;
+            this.subCommand = subCommand;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(command, subCommand);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            CommandKey other = (CommandKey) obj;
+            return Objects.equals(command, other.command) && Objects.equals(subCommand, other.subCommand);
+        }
+    }
+    
+    static class CommandWithProps {
+        private final Command cmd;
+        private final String summary;
+
+        static CommandWithProps of(Command cmd, Map<String, ?> props) {
+            return new CommandWithProps(cmd, (String) props.get(Command.PROPERTY_NAME_SUMMARY));
+        }
+        
+        CommandWithProps(Command cmd, String summary) {
+            this.cmd = cmd;
+            this.summary = summary;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/ExecutionTrigger.java b/src/main/java/org/apache/sling/cli/impl/ExecutionTrigger.java
new file mode 100644
index 0000000..23fa1b8
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/ExecutionTrigger.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+@Component
+public class ExecutionTrigger {
+
+    @Reference
+    private CommandProcessor processor;
+
+    protected void activate(BundleContext ctx) {
+        ctx.addFrameworkListener(evt -> {
+            if (evt.getType() == FrameworkEvent.STARTED)
+                new Thread(() -> processor.runCommand(), getClass().getSimpleName() + "Thread").start();
+        });
+        // never removed but not important - it's one-shot anyway
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/jira/Version.java b/src/main/java/org/apache/sling/cli/impl/jira/Version.java
new file mode 100644
index 0000000..7cce8d5
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/jira/Version.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.jira;
+
+public class Version {
+    private int id;
+    private String name;
+    private int issuesFixedCount;
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public int getIssuesFixedCount() {
+        return issuesFixedCount;
+    }
+    
+    public void setRelatedIssuesCount(int relatedIssuesCount) {
+        this.issuesFixedCount = relatedIssuesCount;
+    }
+}
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
new file mode 100644
index 0000000..5bf0406
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/jira/VersionFinder.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.jira;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.osgi.service.component.annotations.Component;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+@Component(service = VersionFinder.class)
+public class VersionFinder {
+
+    public Version find(String versionName) throws IOException {
+        Version version;
+        
+        try (CloseableHttpClient client = HttpClients.createDefault()) {
+            version = findVersion(versionName, client);
+            populateRelatedIssuesCount(client, version);
+        }
+        
+        return version;
+    }
+
+    private Version findVersion(String versionName, CloseableHttpClient client) throws IOException {
+        Version version;
+        HttpGet get = new HttpGet("https://issues.apache.org/jira/rest/api/2/project/SLING/versions");
+        get.addHeader("Accept", "application/json");
+        try (CloseableHttpResponse response = client.execute(get)) {
+            try (InputStream content = response.getEntity().getContent();
+                    InputStreamReader reader = new InputStreamReader(content)) {
+                if (response.getStatusLine().getStatusCode() != 200)
+                    throw new IOException("Status line : " + response.getStatusLine());
+                Gson gson = new Gson();
+                Type collectionType = TypeToken.getParameterized(List.class, Version.class).getType();
+                List<Version> versions = gson.fromJson(reader, collectionType);
+                version = versions.stream()
+                    .filter(v -> v.getName().equals(versionName))
+                    .findFirst()
+                    .orElseThrow( () -> new IllegalArgumentException("No version found with name " + versionName));
+            }
+        }
+        return version;
+    }
+
+    private void populateRelatedIssuesCount(CloseableHttpClient client, Version version) throws IOException {
+
+        HttpGet get = new HttpGet("https://issues.apache.org/jira/rest/api/2/version/" + version.getId() +"/relatedIssueCounts");
+        get.addHeader("Accept", "application/json");
+        try (CloseableHttpResponse response = client.execute(get)) {
+            try (InputStream content = response.getEntity().getContent();
+                    InputStreamReader reader = new InputStreamReader(content)) {
+                if (response.getStatusLine().getStatusCode() != 200)
+                    throw new IOException("Status line : " + response.getStatusLine());
+                Gson gson = new Gson();
+                VersionRelatedIssuesCount issuesCount = gson.fromJson(reader, VersionRelatedIssuesCount.class);
+                
+                version.setRelatedIssuesCount(issuesCount.getIssuesFixedCount());
+            }
+        }
+    }
+
+    static class VersionRelatedIssuesCount {
+
+        private int issuesFixedCount;
+
+        public int getIssuesFixedCount() {
+            return issuesFixedCount;
+        }
+
+        public void setIssuesFixedCount(int issuesFixedCount) {
+            this.issuesFixedCount = issuesFixedCount;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositories.java b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositories.java
new file mode 100644
index 0000000..84e1a77
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositories.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.nexus;
+
+import java.util.List;
+
+public class StagingRepositories {
+
+    private List<StagingRepository> data;
+
+    public List<StagingRepository> getData() {
+        return data;
+    }
+
+    public void setData(List<StagingRepository> data) {
+        this.data = data;
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java
new file mode 100644
index 0000000..167cebb
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepository.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.nexus;
+
+/**
+ * DTO for GSON usage
+ *
+ */
+public class StagingRepository {
+    
+    enum Status {
+        open, closed;
+    }
+    
+    private String description;
+    private String repositoryId;
+    private String repositoryURI;
+    private Status type;
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getRepositoryId() {
+        return repositoryId;
+    }
+
+    public void setRepositoryId(String repositoryId) {
+        this.repositoryId = repositoryId;
+    }
+
+    public String getRepositoryURI() {
+        return repositoryURI;
+    }
+
+    public void setRepositoryURI(String repositoryURI) {
+        this.repositoryURI = repositoryURI;
+    }
+    
+    public Status getType() {
+        return type;
+    }
+    
+    public void setType(Status type) {
+        this.type = type;
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
new file mode 100644
index 0000000..3ef7992
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.nexus;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.sling.cli.impl.nexus.StagingRepository.Status;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+import com.google.gson.Gson;
+
+@Component(
+    configurationPolicy = ConfigurationPolicy.REQUIRE,
+    service = StagingRepositoryFinder.class
+)
+@Designate(ocd = StagingRepositoryFinder.Config.class)
+public class StagingRepositoryFinder {
+
+    @ObjectClassDefinition
+    static @interface Config {
+        @AttributeDefinition(name="Username")
+        String username();
+        
+        @AttributeDefinition(name="Password")
+        String password();
+    }
+
+    private BasicCredentialsProvider credentialsProvider;
+    
+    @Activate
+    protected void activate(Config cfg) {
+        credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(new AuthScope("repository.apache.org", 443), 
+                new UsernamePasswordCredentials(cfg.username(), cfg.password()));
+    }
+
+    public StagingRepository find(int stagingRepositoryId) throws IOException {
+        try ( CloseableHttpClient client = HttpClients.custom()
+                .setDefaultCredentialsProvider(credentialsProvider)
+                .build() ) {
+            HttpGet get = new HttpGet("https://repository.apache.org/service/local/staging/profile_repositories");
+            get.addHeader("Accept", "application/json");
+            try ( CloseableHttpResponse response = client.execute(get)) {
+                try ( InputStream content = response.getEntity().getContent();
+                        InputStreamReader reader = new InputStreamReader(content)) {
+                    if ( response.getStatusLine().getStatusCode() != 200 )
+                        throw new IOException("Status line : " + response.getStatusLine());
+                    Gson gson = new Gson();
+                    return gson.fromJson(reader, StagingRepositories.class).getData().stream()
+                        .filter( r -> r.getType() == Status.closed)
+                        .filter( r -> r.getRepositoryId().endsWith("-" + stagingRepositoryId))
+                        .findFirst()
+                        .orElseThrow(() -> new IllegalArgumentException("No repository found with id " + stagingRepositoryId));
+                }
+            }
+        }
+    }
+}
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
new file mode 100644
index 0000000..eff3a3f
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommand.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.jira.Version;
+import org.apache.sling.cli.impl.jira.VersionFinder;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = Command.class, property = {
+    Command.PROPERTY_NAME_COMMAND + "=release",
+    Command.PROPERTY_NAME_SUBCOMMAND + "=prepare-email",
+    Command.PROPERTY_NAME_SUMMARY + "=Prepares an email vote for the specified release." })
+public class PrepareVoteEmailCommand implements Command {
+
+    // TODO - replace with file template
+    private static final String EMAIL_TEMPLATE ="To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
+            "Subject: [VOTE] Release Apache Sling ##RELEASE_NAME##\n" + 
+            "\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" + 
+            "\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";
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+    
+    @Reference
+    private StagingRepositoryFinder repoFinder;
+    
+    @Reference
+    private VersionFinder versionFinder;
+
+    @Override
+    public void execute(String target) {
+        try {
+            int repoId = Integer.parseInt(target);
+            StagingRepository repo = repoFinder.find(repoId);
+            String cleanVersion = getCleanVersion(repo.getDescription());
+            Version version = versionFinder.find(cleanVersion);
+            
+            String emailContents = EMAIL_TEMPLATE
+                    .replace("##RELEASE_NAME##", cleanVersion)
+                    .replace("##RELEASE_ID##", String.valueOf(repoId))
+                    .replace("##VERSION_ID##", String.valueOf(version.getId()))
+                    .replace("##FIXED_ISSUES_COUNT##", String.valueOf(version.getIssuesFixedCount()));
+                    
+            logger.info(emailContents);
+
+        } catch (IOException e) {
+            logger.warn("Failed executing command", e);
+        }
+    }
+
+    static String getCleanVersion(String repoDescription) {
+        return repoDescription
+                .replace("Apache Sling ", "") // Apache Sling prefix
+                .replaceAll(" RC[0-9]*$", ""); // 'release candidate' suffix 
+    }
+
+}
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
new file mode 100644
index 0000000..690a4d2
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
+
+import org.apache.sling.cli.impl.Command;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = Command.class, property = {
+    Command.PROPERTY_NAME_COMMAND+"=release",
+    Command.PROPERTY_NAME_SUBCOMMAND+"=tally-votes",
+    Command.PROPERTY_NAME_SUMMARY+"=Counts votes cast for a release and generates the result email"
+})
+public class TallyVotesCommand implements Command {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public void execute(String target) {
+        logger.info("Tallying votes for release {}", target);
+
+    }
+
+}
diff --git a/src/main/resources/conf/logback-default.xml b/src/main/resources/conf/logback-default.xml
new file mode 100644
index 0000000..8f2963f
--- /dev/null
+++ b/src/main/resources/conf/logback-default.xml
@@ -0,0 +1,23 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+    license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to 
+    you 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. -->
+<configuration>
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="org.apache.sling.cli" level="INFO" />
+
+    <root level="WARN">
+        <appender-ref ref="STDOUT" />
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/src/main/resources/scripts/launcher.sh b/src/main/resources/scripts/launcher.sh
new file mode 100755
index 0000000..6f0bcfb
--- /dev/null
+++ b/src/main/resources/scripts/launcher.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+# agreements. See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file to you 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.
+# ----------------------------------------------------------------------------------------
+
+# TODO - contribute '-q' flag to launcher OR allow passthrough of org.slf4j.simpleLogger system properties
+
+
+# funky syntax needed to properly preserve arguments with whitespace
+ARGS_PROP="exec.args=$@"
+
+# Use exec to become pid 1, see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
+exec /usr/bin/java \
+	 -Dorg.slf4j.simpleLogger.logFile=/dev/null \
+	 -Dlogback.configurationFile=file:/usr/share/sling-cli/conf/logback-default.xml \
+	 -jar /usr/share/sling-cli/launcher/org.apache.sling.feature.launcher.jar \
+	 -f /usr/share/sling-cli/sling-cli.feature \
+	 -c /usr/share/sling-cli/artifacts \
+	 -D "$ARGS_PROP" \
+	 -V "asf.username=${ASF_USERNAME}" \
+	 -V "asf.password=${ASF_PASSWORD}"
\ No newline at end of file
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
new file mode 100644
index 0000000..8dd81aa
--- /dev/null
+++ b/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class PrepareVoteEmailCommandTest {
+
+    @Test
+    public void cleanVersion() {
+        
+        assertEquals("Resource Merger 1.3.10", 
+                PrepareVoteEmailCommand.getCleanVersion("Apache Sling Resource Merger 1.3.10 RC1"));
+    }
+}


[sling-org-apache-sling-committer-cli] 21/21: SLING-8339 - CLI hangs when an unhandled exception occurs

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit e11e596afaf7ee8a02af73b04ff3ca3ac097078e
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Mon Apr 1 18:49:51 2019 +0200

    SLING-8339 - CLI hangs when an unhandled exception occurs
    
    Allow commands to throw exceptions and stop the framework whenever
    such an error is thrown.
---
 .../java/org/apache/sling/cli/impl/Command.java    |  2 +-
 .../apache/sling/cli/impl/CommandProcessor.java    | 22 ++++++++++++++--------
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/apache/sling/cli/impl/Command.java b/src/main/java/org/apache/sling/cli/impl/Command.java
index 4caeea7..4b015c4 100644
--- a/src/main/java/org/apache/sling/cli/impl/Command.java
+++ b/src/main/java/org/apache/sling/cli/impl/Command.java
@@ -22,5 +22,5 @@ public interface Command {
     String PROPERTY_NAME_SUBCOMMAND = "subcommand";
     String PROPERTY_NAME_SUMMARY = "summary";
 
-    void execute(String target);
+    void execute(String target) throws Exception;
 }
diff --git a/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java b/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
index 57e5430..6ca6bca 100644
--- a/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
+++ b/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
@@ -57,16 +57,22 @@ public class CommandProcessor {
         // TODO - remove duplication from CLI parsing code
         CommandKey key = CommandKey.of(ctx.getProperty("exec.args"));
         String target = parseTarget(ctx.getProperty("exec.args"));
-        commands.getOrDefault(key, new CommandWithProps(ignored -> {
-            logger.info("Usage: sling command sub-command [target]");
-            logger.info("");
-            logger.info("Available commands:");
-            commands.forEach((k, c) -> logger.info("{} {}: {}", k.command, k.subCommand, c.summary));
-        }, "")).cmd.execute(target);
         try {
-            ctx.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(Framework.class).stop();
-        } catch (BundleException e) {
+            commands.getOrDefault(key, new CommandWithProps(ignored -> {
+                logger.info("Usage: sling command sub-command [target]");
+                logger.info("");
+                logger.info("Available commands:");
+                commands.forEach((k, c) -> logger.info("{} {}: {}", k.command, k.subCommand, c.summary));
+            }, "")).cmd.execute(target);
+        } catch (Exception e) {
             logger.warn("Failed running command", e);
+        } finally {
+            try {
+                ctx.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(Framework.class).stop();
+            } catch (BundleException e) {
+                logger.error("Failed shutting down framework, forcing exit", e);
+                System.exit(1);
+            }
         }
     }
 


[sling-org-apache-sling-committer-cli] 18/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 05ae0d8f253fee2cfead5e2bc0ae837594f10334
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Mar 28 18:51:14 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * added a basic service for sending emails (needs to be tested)
---
 src/main/features/app.json                         |  3 +
 .../org/apache/sling/cli/impl/mail/Mailer.java     | 79 ++++++++++++++++++++++
 .../org/apache/sling/cli/impl/people/Member.java   | 12 +++-
 3 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/src/main/features/app.json b/src/main/features/app.json
index 9b47884..5daa106 100644
--- a/src/main/features/app.json
+++ b/src/main/features/app.json
@@ -64,6 +64,9 @@
         {
             "id"         : "org.apache.servicemix.bundles:org.apache.servicemix.bundles.jsch:0.1.55_1",
             "start-level": "3"
+        },
+        {
+            "id":"javax.mail:mail:1.5.0-b01"
         }
     ]
 }
diff --git a/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java b/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java
new file mode 100644
index 0000000..e4bd604
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java
@@ -0,0 +1,79 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you 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.apache.sling.cli.impl.mail;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Properties;
+
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.people.MembersFinder;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+@Component(
+        service = Mailer.class
+)
+public class Mailer {
+
+    private static final Properties SMTP_PROPERTIES = new Properties() {{
+        put("mail.smtp.host", "mail-relay.apache.org");
+        put("mail.smtp.auth", "true");
+        put("mail.smtp.socketFactory.port", 465);
+        put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+        put("mail.smtp.socketFactory.fallback", "false");
+    }};
+
+    @Reference
+    private CredentialsService credentialsService;
+
+    @Reference
+    private MembersFinder membersFinder;
+
+    public void send(String to, String subject, String body) {
+        Properties properties = new Properties(SMTP_PROPERTIES);
+        Session session = Session.getDefaultInstance(properties, new Authenticator() {
+            @Override
+            protected PasswordAuthentication getPasswordAuthentication() {
+                return new PasswordAuthentication(credentialsService.getCredentials().getUsername(),
+                        credentialsService.getCredentials().getPassword());
+            }
+        });
+        try {
+            MimeMessage message = new MimeMessage(session);
+            message.setFrom(membersFinder.getCurrentMember().getEmail());
+            message.setSubject(subject);
+            message.setText(body, StandardCharsets.UTF_8.name());
+            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
+            Transport.send(message);
+        } catch (MessagingException e) {
+
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/people/Member.java b/src/main/java/org/apache/sling/cli/impl/people/Member.java
index 7b3cb16..5602c66 100644
--- a/src/main/java/org/apache/sling/cli/impl/people/Member.java
+++ b/src/main/java/org/apache/sling/cli/impl/people/Member.java
@@ -20,14 +20,16 @@ package org.apache.sling.cli.impl.people;
 
 public class Member {
 
-    private String id;
-    private String name;
-    private boolean isPMCMember;
+    private final String id;
+    private final String name;
+    private final boolean isPMCMember;
+    private final String email;
 
     Member(String id, String name, boolean isPMCMember) {
         this.id = id;
         this.name = name;
         this.isPMCMember = isPMCMember;
+        email = id + "@apache.org";
     }
 
     public String getId() {
@@ -42,6 +44,10 @@ public class Member {
         return isPMCMember;
     }
 
+    public String getEmail() {
+        return email;
+    }
+
     @Override
     public int hashCode() {
         return id.hashCode();


[sling-org-apache-sling-committer-cli] 08/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 292bc15a2062ba333023f0de34bba9843dae7035
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 19 16:25:53 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Remove trailing empty lines from TallyVotesCommand output.
---
 src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

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 f15f60b..86742bb 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
@@ -39,8 +39,7 @@ import org.slf4j.LoggerFactory;
 public class TallyVotesCommand implements Command {
     
     // TODO - move to file
-    private static final String EMAIL_TEMPLATE ="\n" + 
-            "\n" + 
+    private static final String EMAIL_TEMPLATE =
             "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
             "Subject: [RESULT] [VOTE] Release ##RELEASE_NAME##\n" + 
             "\n" + 


[sling-org-apache-sling-committer-cli] 09/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit c2beebd3b7902a4f6c8e1cdbff13fc488fd4e268
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Wed Mar 20 10:14:33 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Enable class data sharing. This yields a small (~120ms) startup time improvement
    in local testing.
---
 Dockerfile                             | 6 +++++-
 src/main/resources/scripts/launcher.sh | 3 ++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 1338fcb..c29cd1e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,6 +12,10 @@
 
 FROM openjdk:8-jre-alpine
 MAINTAINER dev@sling.apache.org
+
+# Generate class data sharing
+RUN java -Xshare:dump
+
 # escaping required to properly handle arguments with spaces
 ENTRYPOINT ["/usr/share/sling-cli/bin/launcher.sh"]
 
@@ -27,4 +31,4 @@ ADD target/classes/conf /usr/share/sling-cli/conf
 ADD target/artifacts /usr/share/sling-cli/artifacts
 # Add the service itself
 ARG FEATURE_FILE
-ADD ${FEATURE_FILE} /usr/share/sling-cli/sling-cli.feature
\ No newline at end of file
+ADD ${FEATURE_FILE} /usr/share/sling-cli/sling-cli.feature
diff --git a/src/main/resources/scripts/launcher.sh b/src/main/resources/scripts/launcher.sh
index 6f0bcfb..7b306ba 100755
--- a/src/main/resources/scripts/launcher.sh
+++ b/src/main/resources/scripts/launcher.sh
@@ -19,6 +19,7 @@ ARGS_PROP="exec.args=$@"
 
 # Use exec to become pid 1, see https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
 exec /usr/bin/java \
+     -Xshare:on \
 	 -Dorg.slf4j.simpleLogger.logFile=/dev/null \
 	 -Dlogback.configurationFile=file:/usr/share/sling-cli/conf/logback-default.xml \
 	 -jar /usr/share/sling-cli/launcher/org.apache.sling.feature.launcher.jar \
@@ -26,4 +27,4 @@ exec /usr/bin/java \
 	 -c /usr/share/sling-cli/artifacts \
 	 -D "$ARGS_PROP" \
 	 -V "asf.username=${ASF_USERNAME}" \
-	 -V "asf.password=${ASF_PASSWORD}"
\ No newline at end of file
+	 -V "asf.password=${ASF_PASSWORD}"


[sling-org-apache-sling-committer-cli] 17/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 1945c87a47c665e8eaec5da3ccab7e17e8431ee5
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Mar 28 18:06:41 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * changed tabs to spaces; tabs are evil...
---
 src/main/features/app.json | 134 ++++++++++++++++++++++-----------------------
 1 file changed, 67 insertions(+), 67 deletions(-)

diff --git a/src/main/features/app.json b/src/main/features/app.json
index 5fb7cd2..9b47884 100644
--- a/src/main/features/app.json
+++ b/src/main/features/app.json
@@ -1,69 +1,69 @@
 {
-	"id": "${project.groupId}:${project.artifactId}:slingfeature:app:${project.version}",
-	"bundles": [
-		{
-			"id": "${project.groupId}:${project.artifactId}:${project.version}",
-			"start-level": "5"
-		},
-		{
-			"id": "org.apache.felix:org.apache.felix.scr:2.1.12",
-			"start-level": "1"
-		},
-		{
-			"id": "org.apache.felix:org.apache.felix.configadmin:1.9.10",
-			"start-level": "1"
-		},
-		{
-			"id": "org.apache.felix:org.apache.felix.log:1.2.0",
-			"start-level": "1"
-		},
-		{
-			"id": "ch.qos.logback:logback-classic:1.2.3",
-			"start-level": "1"
-		},
-		{
-			"id": "ch.qos.logback:logback-core:1.2.3",
-			"start-level": "1"
-		},
-		{
-			"id": "org.slf4j:jul-to-slf4j:1.7.25",
-			"start-level": "1"
-		},
-		{
-			"id": "org.slf4j:jcl-over-slf4j:1.7.25",
-			"start-level": "1"
-		},
-		{
-			"id": "org.slf4j:slf4j-api:1.7.25",
-			"start-level": "1"
-		},
-		{
-			"id": "org.apache.felix:org.apache.felix.logback:1.0.2",
-			"start-level": "1"
-		},
-		{
-			"id": "org.apache.httpcomponents:httpcore-osgi:4.4.11",
-			"start-level": "3"
-		},
-		{
-			"id": "org.apache.httpcomponents:httpclient-osgi:4.5.7",
-			"start-level": "3"
-		},
-		{
-			"id": "com.google.code.gson:gson:2.8.5",
-			"start-level": "3"
-		},
-		{
-			"id": "org.eclipse.jgit:org.eclipse.jgit:5.2.1.201812262042-r",
-			"start-level": "3"
-		},
-		{
-			"id": "com.googlecode.javaewah:JavaEWAH:1.1.6",
-			"start-level": "3"
-		},
-		{
-			"id": "org.apache.servicemix.bundles:org.apache.servicemix.bundles.jsch:0.1.55_1",
-			"start-level": "3"
-		}
-	]
+    "id"     : "${project.groupId}:${project.artifactId}:slingfeature:app:${project.version}",
+    "bundles": [
+        {
+            "id"         : "${project.groupId}:${project.artifactId}:${project.version}",
+            "start-level": "5"
+        },
+        {
+            "id"         : "org.apache.felix:org.apache.felix.scr:2.1.12",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.apache.felix:org.apache.felix.configadmin:1.9.10",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.apache.felix:org.apache.felix.log:1.2.0",
+            "start-level": "1"
+        },
+        {
+            "id"         : "ch.qos.logback:logback-classic:1.2.3",
+            "start-level": "1"
+        },
+        {
+            "id"         : "ch.qos.logback:logback-core:1.2.3",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.slf4j:jul-to-slf4j:1.7.25",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.slf4j:jcl-over-slf4j:1.7.25",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.slf4j:slf4j-api:1.7.25",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.apache.felix:org.apache.felix.logback:1.0.2",
+            "start-level": "1"
+        },
+        {
+            "id"         : "org.apache.httpcomponents:httpcore-osgi:4.4.11",
+            "start-level": "3"
+        },
+        {
+            "id"         : "org.apache.httpcomponents:httpclient-osgi:4.5.7",
+            "start-level": "3"
+        },
+        {
+            "id"         : "com.google.code.gson:gson:2.8.5",
+            "start-level": "3"
+        },
+        {
+            "id"         : "org.eclipse.jgit:org.eclipse.jgit:5.2.1.201812262042-r",
+            "start-level": "3"
+        },
+        {
+            "id"         : "com.googlecode.javaewah:JavaEWAH:1.1.6",
+            "start-level": "3"
+        },
+        {
+            "id"         : "org.apache.servicemix.bundles:org.apache.servicemix.bundles.jsch:0.1.55_1",
+            "start-level": "3"
+        }
+    ]
 }


[sling-org-apache-sling-committer-cli] 07/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 57f09426ae89abf713272307be1d7be0dcd771f3
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 19 16:22:32 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Update README for update-local-site
---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index 45336b1..9dbad6e 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,10 @@ Generating a release vote email
 Generating a release vote result email
 
     docker run --env-file=./docker-env apache/sling-cli release tally-votes $STAGING_REPOSITORY_ID
+    
+Generating the website update (only diff for now)
+
+	docker run --env-file=docker-env apache/sling-cli release update-local-site $STAGING_REPOSITORY_ID
 
 ## Assumptions
 


[sling-org-apache-sling-committer-cli] 05/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit ad74b228a8633bfb2b58f24056cd825146e8be33
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 19 16:13:04 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Add command for generating local changes to the website
---
 pom.xml                                            |   13 +-
 src/main/features/app.json                         |   12 +
 .../sling/cli/impl/jbake/JBakeContentUpdater.java  |  140 ++
 .../cli/impl/release/UpdateLocalSiteCommand.java   |    4 -
 .../cli/impl/jbake/JBakeContentUpdaterTest.java    |  197 +++
 src/test/resources/downloads.tpl                   |  474 +++++
 src/test/resources/releases.md                     | 1812 ++++++++++++++++++++
 7 files changed, 2647 insertions(+), 5 deletions(-)

diff --git a/pom.xml b/pom.xml
index 047121d..1f717d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -164,10 +164,21 @@
             <version>2.8.5</version>
             <scope>provided</scope>
         </dependency>
-        
+        <dependency>
+          <groupId>org.eclipse.jgit</groupId>
+          <artifactId>org.eclipse.jgit</artifactId>
+          <version>5.2.1.201812262042-r</version>
+          <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/features/app.json b/src/main/features/app.json
index f07827d..4d310c4 100644
--- a/src/main/features/app.json
+++ b/src/main/features/app.json
@@ -56,6 +56,18 @@
 		{
 			"id": "com.google.code.gson:gson:2.8.5",
 			"start-level": "3"
+		},
+		{
+			"id": "org.eclipse.jgit:org.eclipse.jgit:5.2.1.201812262042-r",
+			"start-level": "3"
+		},
+		{
+			"id": "com.googlecode.javaewah:JavaEWAH:1.1.6",
+			"start-level": "3"
+		},
+		{
+			"id": "org.apache.servicemix.bundles:org.apache.servicemix.bundles.jsch:0.1.55_1",
+			"start-level": "3"
 		}
 	],
 	"configurations": {
diff --git a/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java b/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java
new file mode 100644
index 0000000..52bd1a4
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdater.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.jbake;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+public class JBakeContentUpdater {
+    
+    private static final Pattern DOWNLOAD_LINE_PATTERN = Pattern.compile("^.*\"([a-zA-Z\\s\\-]+)\\|([a-zA-Z\\.\\-]+)\\|([0-9\\.\\-]+).*$");
+
+    public int updateDownloads(Path downloadsTemplatePath, String newReleaseName, String newReleaseVersion) throws IOException {
+        
+        int[] changeCount = new int[1];
+        
+        List<String> updatedLines = Files.readAllLines(downloadsTemplatePath, StandardCharsets.UTF_8).stream()
+                .map(line -> {
+                    Matcher matcher = DOWNLOAD_LINE_PATTERN.matcher(line);
+                    if ( !matcher.find() )
+                        return line;
+                    
+                    if ( ! matcher.group(1).equals(newReleaseName) )
+                        return line;
+                    
+                    changeCount[0]++;
+                    
+                    StringBuilder buffer = new StringBuilder();
+                    buffer.append(line.substring(0, matcher.start(3)));
+                    buffer.append(newReleaseVersion);
+                    buffer.append(line.substring(matcher.end(3)));
+                    
+                    return buffer.toString();
+                }).collect(Collectors.toList());
+
+        Files.write(downloadsTemplatePath, updatedLines);
+        
+        return changeCount[0];
+    }
+
+    public void updateReleases(Path releasesPath, String releaseName, String releaseVersion, LocalDateTime releaseTime) throws IOException {
+        
+        List<String> releasesLines = Files.readAllLines(releasesPath, StandardCharsets.UTF_8);
+        String dateHeader = "## " + releaseTime.format(DateTimeFormatter.ofPattern("MMMM uuuu", Locale.ENGLISH));
+        
+        int releaseLineIdx = -1;
+        int dateLineIdx = -1;
+        for ( int i = 0 ; i < releasesLines.size(); i++ ) {
+            String releasesLine = releasesLines.get(i);
+            if ( releasesLine.startsWith("This is a list of all our releases") ) {
+                releaseLineIdx = i;
+            }
+            if ( releasesLine.equals(dateHeader) ) {
+                dateLineIdx = i;
+            }
+        }
+        
+        if ( dateLineIdx == -1 ) {
+            // need to add month marker
+            releasesLines.add(releaseLineIdx + 1, "");
+            releasesLines.add(releaseLineIdx + 2, dateHeader);
+            releasesLines.add(releaseLineIdx + 3, "");
+            dateLineIdx = releaseLineIdx + 2;
+        }
+        
+        String date = formattedDay(releaseTime);
+        
+        // inspect all lines in the current month ( until empty line found )
+        // to see if the release date already exists
+        boolean changed = false;
+        for ( int i = dateLineIdx +2 ; i < releasesLines.size(); i++ ) {
+            String potentialLine = releasesLines.get(i);
+            if ( potentialLine.trim().isEmpty() )
+                break;
+            
+            if ( potentialLine.endsWith("(" +date+")") ) {
+                if ( potentialLine.contains(releaseName + " " + releaseVersion ) ) {
+                    changed = true;
+                    break;
+                }
+                
+                int insertionIdx = potentialLine.indexOf('(') - 1;
+                StringBuilder buffer = new StringBuilder();
+                buffer
+                    .append(potentialLine.substring(0, insertionIdx))
+                    .append(", ")
+                    .append(releaseName)
+                    .append(' ')
+                    .append(releaseVersion)
+                    .append(' ')
+                    .append(potentialLine.substring(insertionIdx + 1));
+                
+                releasesLines.set(i, buffer.toString());
+                changed = true;
+                break;
+            }
+        }
+        
+        if ( !changed )
+            releasesLines.add(dateLineIdx + 2, "* " + releaseName + " " + releaseVersion +" (" + date + ")");
+
+        Files.write(releasesPath, releasesLines);
+    }
+    
+    private String formattedDay(LocalDateTime releaseTime) {
+        String date = releaseTime.format(DateTimeFormatter.ofPattern("d", Locale.ENGLISH));
+        switch (date) {
+        case "1":
+            return "1st";
+        case "2":
+            return "2nd";
+        case "3":
+            return "3rd";
+        default:
+            return date + "th";
+        }
+    }
+}
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 483613e..10e836a 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
@@ -44,10 +44,6 @@ import org.slf4j.LoggerFactory;
 })
 public class UpdateLocalSiteCommand implements Command {
     
-    public static void main(String[] args) {
-        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMMM uuuu", Locale.ENGLISH)));
-    }
-
     private static final String GIT_CHECKOUT = "/tmp/sling-site";
 
     @Reference
diff --git a/src/test/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdaterTest.java b/src/test/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdaterTest.java
new file mode 100644
index 0000000..5bbbc53
--- /dev/null
+++ b/src/test/java/org/apache/sling/cli/impl/jbake/JBakeContentUpdaterTest.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.jbake;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.contains;
+import static org.junit.Assert.assertThat;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
+import org.eclipse.jgit.diff.DiffEntry.Side;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class JBakeContentUpdaterTest {
+
+    @Rule
+    public TemporaryFolder tmp = new TemporaryFolder();
+    
+    private JBakeContentUpdater updater;
+    
+    @Before
+    public void setUp() throws IOException {
+        
+        updater = new JBakeContentUpdater();
+        // copy the file away so we don't modify what is in source control
+        Files.copy(getClass().getResourceAsStream("/downloads.tpl"), Paths.get(new File(tmp.getRoot(), "downloads.tpl").toURI()));
+        Files.copy(getClass().getResourceAsStream("/releases.md"), Paths.get(new File(tmp.getRoot(), "releases.md").toURI()));
+    }
+    
+    @Test
+    public void updateDownloadsTemplate_newReleaseOfExistingModule() throws IOException {
+        
+        updateDownloadsTemplate0("API", "2.20.2");
+    }
+
+    private void updateDownloadsTemplate0(String newReleaseName, String newReleaseVersion) throws IOException {
+        Path templatePath = Paths.get(new File(tmp.getRoot(), "downloads.tpl").toURI());
+        
+        int changeCount = updater.updateDownloads(templatePath, newReleaseName, newReleaseVersion);
+        assertThat("Unexpected count of changes", changeCount, equalTo(1));
+
+        String apiLine = Files.readAllLines(templatePath, StandardCharsets.UTF_8).stream()
+            .filter( l -> l.trim().startsWith("\"" + newReleaseName + "|"))
+            .findFirst()
+            .get();
+        
+        assertThat("Did not find modified version in the release line", apiLine, containsString(newReleaseVersion));
+    }
+
+    @Test
+    public void updateDownloadsTemplate_newReleaseOfExistingMavenPlugin() throws IOException {
+        
+        updateDownloadsTemplate0("Slingstart Maven Plugin", "1.9.0");
+    }
+
+    @Test
+    public void updateDownloadsTemplate_newReleaseOfIDETooling() throws IOException {
+
+        updateDownloadsTemplate0("Sling IDE Tooling for Eclipse", "1.4.0");
+    }
+    
+    @Test
+    public void updateReleases_releaseInExistingMonth() throws IOException, GitAPIException {
+        updateReleases0(LocalDateTime.of(2019, 2, 27, 22, 00), 
+            Arrays.asList( 
+                " " ,  
+                " ## February 2019", 
+                " " ,
+                "+* API 2.20.2 (27th)",
+                " * DataSource Provider 1.0.4, Resource Collection API 1.0.2, JCR ResourceResolver 3.0.18 (26th)",  
+                " * Scripting JSP Tag Library 2.4.0, Scripting JSP Tag Library (Compat) 1.0.0 (18th)",
+                " * Pipes 3.1.0 (15th)"
+            )
+        );
+        
+    }
+
+    private void updateReleases0(LocalDateTime releaseDate, List<String> expectedLines, String... releaseNameAndInfo) throws IOException, GitAPIException {
+        
+        if ( releaseNameAndInfo.length > 2 )
+            throw new IllegalArgumentException("Unexpected releaseNameAndInfo: " + Arrays.toString(releaseNameAndInfo));
+        
+        String releaseName = releaseNameAndInfo.length > 0 ? releaseNameAndInfo[0] : "API";
+        String releaseVersion = releaseNameAndInfo.length > 1 ? releaseNameAndInfo[1] : "2.20.2";
+        
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        
+        try ( Git git = Git.init().setDirectory(tmp.getRoot()).call() ) {
+            git.add()
+                .addFilepattern("downloads.tpl")
+                .addFilepattern("releases.md")
+                .call();
+            
+            git.commit()
+                .setMessage("Initial commit")
+                .call();
+            
+            Path releasesPath = Paths.get(new File(tmp.getRoot(), "releases.md").toURI());
+            updater.updateReleases(releasesPath, releaseName, releaseVersion, releaseDate);
+            
+            List<DiffEntry> changes = git.diff().setOutputStream(out).call();
+            
+            // ensure that the diff we're getting only refers to the releases file
+            // alternatively, when no changes are expected validate that
+            
+            if ( expectedLines.isEmpty() ) {
+                assertThat("changes.size", changes.size(), equalTo(0));
+                return;
+            }
+
+            assertThat("changes.size", changes.size(), equalTo(1));
+            assertThat("changes[0].type", changes.get(0).getChangeType(), equalTo(ChangeType.MODIFY));
+            assertThat("changes[0].path", changes.get(0).getPath(Side.NEW), equalTo("releases.md"));
+            
+            // now hack away on it safely
+            List<String> ignoredPrefixes = Arrays.asList("diff", "index", "---", "+++", "@@");
+            List<String> diffLines = Arrays.stream(new String(out.toByteArray(), StandardCharsets.UTF_8)
+                .split("\\n"))
+                .filter( l -> !ignoredPrefixes.stream().filter( p -> l.startsWith(p)).findAny().isPresent() )
+                .collect(Collectors.toList());
+            
+            assertThat(diffLines, contains(expectedLines.toArray(new String[0])));
+        }
+    }
+
+    @Test
+    public void updateReleases_releaseAlreadyExists() throws IOException, GitAPIException {
+        updateReleases0(LocalDateTime.of(2019, 2, 18, 22, 00), Collections.emptyList(), "Scripting JSP Tag Library", "2.4.0");
+    }
+    
+    @Test
+    public void updateReleases_releaseInNewMonth() throws IOException, GitAPIException {
+        updateReleases0(LocalDateTime.of(2019, 3, 15, 22, 00), 
+            Arrays.asList( 
+               " ~~~~~~",
+               " This is a list of all our releases, available from our [downloads](/downloads.cgi) page.",
+               " ",
+               "+## March 2019",
+               "+",
+               "+* API 2.20.2 (15th)",
+               "+",
+               " ## February 2019",
+               " ",
+               " * DataSource Provider 1.0.4, Resource Collection API 1.0.2, JCR ResourceResolver 3.0.18 (26th)"
+            )
+        );
+    }
+
+    @Test
+    public void updateReleases_releaseExistingMonthAndDay() throws IOException, GitAPIException {
+        updateReleases0(LocalDateTime.of(2019, 2, 26, 22, 00),
+            Arrays.asList(
+                " ", 
+                " ## February 2019", 
+                " ", 
+                "-* DataSource Provider 1.0.4, Resource Collection API 1.0.2, JCR ResourceResolver 3.0.18 (26th)",
+                "+* DataSource Provider 1.0.4, Resource Collection API 1.0.2, JCR ResourceResolver 3.0.18, API 2.20.2 (26th)", 
+                " * Scripting JSP Tag Library 2.4.0, Scripting JSP Tag Library (Compat) 1.0.0 (18th)", 
+                " * Pipes 3.1.0 (15th)", 
+                " * Testing OSGi Mock 2.4.6 (14th)"
+            )
+        );
+    }
+}
diff --git a/src/test/resources/downloads.tpl b/src/test/resources/downloads.tpl
new file mode 100644
index 0000000..5a0d578
--- /dev/null
+++ b/src/test/resources/downloads.tpl
@@ -0,0 +1,474 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// ------------------------------------------------------------------------------------------------
+// Sling downloads page
+// http://www.apache.org/dev/release-download-pages.html explains how the apache.org mirrored
+// downloads page work. Basically, we provide a downloads.html page with a few placeholders
+// and a form to select the download mirrog, and a downloads.cgi page which wraps the apache.org
+// download logic CGI.
+// ------------------------------------------------------------------------------------------------
+
+// ------------------------------------------------------------------------------------------------
+// Downloads template data
+// The page template itself is found below.
+// To convert from the old svn downloads.list ust
+//    while read l; do echo "  \"$l\","; done < content/downloads.list
+// ------------------------------------------------------------------------------------------------
+def launchpadVersion="11"
+
+def slingIDETooling=[
+  "Sling IDE Tooling for Eclipse|eclipse|1.2.2|A p2 update site which can be installed in Eclipse.|sling-ide-tooling"
+]
+
+def slingApplication=[
+  "Sling Starter Standalone|A self-runnable Sling jar|org.apache.sling.starter|.jar|${launchpadVersion}|Y",
+  "Sling Starter WAR|A ready-to run Sling webapp as a war file|org.apache.sling.starter|-webapp.war|${launchpadVersion}|Y",
+  "Sling Source Release|The released Sling source code|org.apache.sling.starter|-source-release.zip|${launchpadVersion}|Y",
+  "Sling CMS App|A reference CMS App built on Apache Sling|org.apache.sling.cms.builder|.jar|0.11.2|org.apache.sling.app.cms",
+]
+
+def mavenPlugins=[
+  "JSPC Maven Plugin|jspc-maven-plugin|2.1.0|Y",
+  "Maven Launchpad Plugin|maven-launchpad-plugin|2.3.4|Y",
+  "Sling Maven Plugin|sling-maven-plugin|2.4.0|Y",
+  "Slingstart Maven Plugin|slingstart-maven-plugin|1.8.2|Y",
+  "HTL Maven Plugin|htl-maven-plugin|1.2.2-1.4.0|Y",
+]
+
+def bundles=[
+  "Adapter|org.apache.sling.adapter|2.1.10|Y|jar",
+  "Adapter Annotations|adapter-annotations|1.0.0|Y|jar",
+  "API|org.apache.sling.api|2.20.0|Y|jar",
+  "Auth Core|org.apache.sling.auth.core|1.4.2|Y|jar",
+  "Auth Form|org.apache.sling.auth.form|1.0.12|Y|jar",
+  "Authentication XING API|org.apache.sling.auth.xing.api|0.0.2|Y|jar",
+  "Authentication XING Login|org.apache.sling.auth.xing.login|0.0.2|Y|jar",
+  "Authentication XING OAuth|org.apache.sling.auth.xing.oauth|0.0.2|Y|jar",
+  "Bundle Resource Provider|org.apache.sling.bundleresource.impl|2.3.2|Y|jar",
+  "Capabilities|org.apache.sling.capabilities|0.1.2|Y|jar",
+  "Capabilities JCR|org.apache.sling.capabilities.jcr|0.1.2|Y|jar",
+  "Clam|org.apache.sling.clam|1.0.2|Y|jar",   
+  "Classloader Leak Detector|org.apache.sling.extensions.classloader-leak-detector|1.0.0|Y|jar",
+  "CMS App API|org.apache.sling.cms.api|0.11.2|org.apache.sling.app.cms|jar",
+  "CMS App Core|org.apache.sling.cms.core|0.11.2|org.apache.sling.app.cms|jar",
+  "CMS App Reference|org.apache.sling.cms.reference|0.11.2|org.apache.sling.app.cms|jar",
+  "CMS App UI|org.apache.sling.cms.ui|0.11.2|org.apache.sling.app.cms|jar",
+  "Commons Classloader|org.apache.sling.commons.classloader|1.4.4|Y|jar",
+  "Commons Clam|org.apache.sling.commons.clam|1.0.2|Y|jar",
+  "Commons Compiler|org.apache.sling.commons.compiler|2.3.6|Y|jar",
+  "Commons FileSystem ClassLoader|org.apache.sling.commons.fsclassloader|1.0.8|Y|jar",
+  "Commons HTML|org.apache.sling.commons.html|1.1.0|Y|jar",
+  "Commons Johnzon|org.apache.sling.commons.johnzon|1.1.0|Y|jar",
+  "Commons Log|org.apache.sling.commons.log|5.1.10|Y|jar",
+  "Commons Log WebConsole Plugin|org.apache.sling.commons.log.webconsole|1.0.0|Y|jar",
+  "Commons Log Service|org.apache.sling.commons.logservice|1.0.6|Y|jar",
+  "Commons Metrics|org.apache.sling.commons.metrics|1.2.6|Y|jar",
+  "Commons RRD4J metrics reporter|org.apache.sling.commons.metrics-rrd4j|1.0.2|Y|jar",
+  "Commons Mime Type Service|org.apache.sling.commons.mime|2.2.0|Y|jar",
+  "Commons OSGi|org.apache.sling.commons.osgi|2.4.0|Y|jar",
+  "Commons Scheduler|org.apache.sling.commons.scheduler|2.7.2|Y|jar",
+  "Commons Testing|org.apache.sling.commons.testing|2.1.2|Y|jar",
+  "Commons Threads|org.apache.sling.commons.threads|3.2.18|Y|jar",
+  "Content Detection Support|org.apache.sling.commons.contentdetection|1.0.2|Y|jar",
+  "Context-Aware Configuration API|org.apache.sling.caconfig.api|1.1.2|Y|jar",
+  "Context-Aware Configuration bnd Plugin|org.apache.sling.caconfig.bnd-plugin|1.0.2|Y|jar",
+  "Context-Aware Configuration Impl|org.apache.sling.caconfig.impl|1.4.14|Y|jar",
+  "Context-Aware Configuration Mock Plugin|org.apache.sling.testing.caconfig-mock-plugin|1.3.2|Y|jar",
+  "Context-Aware Configuration SPI|org.apache.sling.caconfig.spi|1.3.4|Y|jar",
+  "Crankstart API|org.apache.sling.crankstart.api|1.0.0|N|jar",
+  "Crankstart API Fragment|org.apache.sling.crankstart.api.fragment|1.0.2|N|jar",
+  "Crankstart Core|org.apache.sling.crankstart.core|1.0.0|N|jar",
+  "Crankstart Launcher|org.apache.sling.crankstart.launcher|1.0.0|Y|jar",
+  "Crankstart Launcher Sling Extensions|org.apache.sling.crankstart.sling.extensions|1.0.0|Y|jar",
+  "Crankstart Launcher Test Services|org.apache.sling.crankstart.test.services|1.0.0|Y|jar",
+  "DataSource Provider|org.apache.sling.datasource|1.0.4|Y|jar",
+  "Discovery API|org.apache.sling.discovery.api|1.0.4|Y|jar",
+  "Discovery Impl|org.apache.sling.discovery.impl|1.2.12|Y|jar",
+  "Discovery Commons|org.apache.sling.discovery.commons|1.0.20|Y|jar",
+  "Discovery Base|org.apache.sling.discovery.base|2.0.8|Y|jar",
+  "Discovery Oak|org.apache.sling.discovery.oak|1.2.28|Y|jar",
+  "Discovery Standalone|org.apache.sling.discovery.standalone|1.0.2|Y|jar",
+  "Discovery Support|org.apache.sling.discovery.support|1.0.4|Y|jar",
+  "Distributed Event Admin|org.apache.sling.event.dea|1.1.4|Y|jar",
+  "Distribution API|org.apache.sling.distribution.api|0.3.0|Y|jar",
+  "Distribution Core|org.apache.sling.distribution.core|0.4.0|Y|jar",
+  "Distribution Integration Tests|org.apache.sling.distribution.it|0.1.2|Y|jar",
+  "Distribution Sample|org.apache.sling.distribution.sample|0.1.6|Y|jar",
+  "Dynamic Include|org.apache.sling.dynamic-include|3.1.2|Y|jar",
+  "Engine|org.apache.sling.engine|2.6.18|Y|jar",
+  "Event|org.apache.sling.event|4.2.12|Y|jar",
+  "Event API|org.apache.sling.event.api|1.0.0|Y|jar",
+  "Feature Model|org.apache.sling.feature|1.0.0|Y|jar",
+  "Feature Model Analyser|org.apache.sling.feature.analyser|0.8.0|Y|jar",
+  "Feature Model IO|org.apache.sling.feature.io|1.0.0|Y|jar",
+  "Feature Model Converter|org.apache.sling.feature.modelconverter|0.8.0|Y|jar",
+  "Feature Flags|org.apache.sling.featureflags|1.2.2|Y|jar",
+  "File Optimization|org.apache.sling.fileoptim|0.9.2|org.apache.sling.file.optimization|jar",
+  "File System Resource Provider|org.apache.sling.fsresource|2.1.14|Y|jar",
+  "I18n|org.apache.sling.i18n|2.5.12|Y|jar",
+  "HApi|org.apache.sling.hapi|1.1.0|Y|jar",
+  "Health Check Annotations|org.apache.sling.hc.annotations|1.0.6|Y|jar",
+  "Health Check Core|org.apache.sling.hc.core|1.2.10|Y|jar",
+  "Health Check API|org.apache.sling.hc.api|1.0.2|Y|jar",
+  "Health Check Integration Tests|org.apache.sling.hc.it|1.0.4|Y|jar",
+  "Health Check JUnit Bridge|org.apache.sling.hc.junit.bridge|1.0.2|Y|jar",
+  "Health Check Samples|org.apache.sling.hc.samples|1.0.6|Y|jar",
+  "Health Check Support|org.apache.sling.hc.support|1.0.4|Y|jar",
+  "Health Check Webconsole|org.apache.sling.hc.webconsole|1.1.2|Y|jar",
+  "Installer Core|org.apache.sling.installer.core|3.9.0|Y|jar",
+  "Installer Console|org.apache.sling.installer.console|1.0.2|Y|jar",
+  "Installer Configuration Support|org.apache.sling.installer.factory.configuration|1.2.0|Y|jar",
+  "Installer Health Checks|org.apache.sling.installer.hc|2.0.0|Y|jar",
+  "Installer Subystems Support|org.apache.sling.installer.factory.subsystems|1.0.0|Y|jar",
+  "Installer File Provider|org.apache.sling.installer.provider.file|1.1.0|Y|jar",
+  "Installer JCR Provider|org.apache.sling.installer.provider.jcr|3.1.26|Y|jar",
+  "Installer Vault Package Install Hook|org.apache.sling.installer.provider.installhook|1.0.4|Y|jar",
+  "javax activation|org.apache.sling.javax.activation|0.1.0|Y|jar",
+  "JCR API|org.apache.sling.jcr.api|2.4.0|Y|jar",
+  "JCR API Wrapper|org.apache.sling.jcr.jcr-wrapper|2.0.0|Y|jar",
+  "JCR Base|org.apache.sling.jcr.base|3.0.6|Y|jar",
+  "JCR ClassLoader|org.apache.sling.jcr.classloader|3.2.4|Y|jar",
+  "JCR Content Loader|org.apache.sling.jcr.contentloader|2.3.0|Y|jar",
+  "JCR Content Parser|org.apache.sling.jcr.contentparser|1.2.6|Y|jar",
+  "JCR DavEx|org.apache.sling.jcr.davex|1.3.10|Y|jar",
+  "JCR Jackrabbit AccessManager|org.apache.sling.jcr.jackrabbit.accessmanager|3.0.4|Y|jar",
+  "JCR Jackrabbit UserManager|org.apache.sling.jcr.jackrabbit.usermanager|2.2.8|Y|jar",
+  "JCR Oak Server|org.apache.sling.jcr.oak.server|1.2.2|Y|jar",
+  "JCR Registration|org.apache.sling.jcr.registration|1.0.6|Y|jar",
+  "JCR Repoinit|org.apache.sling.jcr.repoinit|1.1.8|Y|jar",
+  "JCR Resource|org.apache.sling.jcr.resource|3.0.18|Y|jar",
+  "JCR Resource Security|org.apache.sling.jcr.resourcesecurity|1.0.2|Y|jar",
+  "JCR Web Console Plugin|org.apache.sling.jcr.webconsole|1.0.2|Y|jar",
+  "JMX Resource Provider|org.apache.sling.jmx.provider|1.0.2|Y|jar",
+  "JCR WebDAV|org.apache.sling.jcr.webdav|2.3.8|Y|jar",
+  "JUnit Core|org.apache.sling.junit.core|1.0.26|Y|jar",
+  "JUnit Remote Tests Runners|org.apache.sling.junit.remote|1.0.12|Y|jar",
+  "JUnit Scriptable Tests Provider|org.apache.sling.junit.scriptable|1.0.12|Y|jar",
+  "JUnit Tests Teleporter|org.apache.sling.junit.teleporter|1.0.18|Y|jar",
+  "JUnit Health Checks|org.apache.sling.junit.healthcheck|1.0.6|Y|jar",
+  "Launchpad API|org.apache.sling.launchpad.api|1.2.0|Y|jar",
+  "Launchpad Base|org.apache.sling.launchpad.base|5.6.10-2.6.26|Y|jar",
+  "Launchpad Base - Application Launcher|org.apache.sling.launchpad.base|5.6.10-2.6.26|Y|war",
+  "Launchpad Base - Web Launcher|org.apache.sling.launchpad.base|5.6.10-2.6.26|Y|war",
+  "Launchpad Installer|org.apache.sling.launchpad.installer|1.2.2|Y|jar",
+  "Launchpad Integration Tests|org.apache.sling.launchpad.integration-tests|1.0.8|Y|jar",
+  "Launchpad Test Fragment Bundle|org.apache.sling.launchpad.test-fragment|2.0.16|Y|jar",
+  "Launchpad Test Bundles|org.apache.sling.launchpad.test-bundles|0.0.6|Y|jar",
+  "Launchpad Testing|org.apache.sling.launchpad.testing|11|Y|jar",
+  "Launchpad Testing WAR|org.apache.sling.launchpad.testing-war|11|Y|jar",
+  "Launchpad Testing Services|org.apache.sling.launchpad.test-services|2.0.16|Y|jar",
+  "Launchpad Testing Services WAR|org.apache.sling.launchpad.test-services-war|2.0.16|Y|war",
+  "Log Tracer|org.apache.sling.tracer|1.0.6|Y|jar",
+  "Models API|org.apache.sling.models.api|1.3.8|Y|jar",
+  "Models bnd Plugin|org.apache.sling.bnd.models|1.0.0|Y|jar",
+  "Models Implementation|org.apache.sling.models.impl|1.4.10|Y|jar",
+  "Models Jackson Exporter|org.apache.sling.models.jacksonexporter|1.0.8|Y|jar",
+  "NoSQL Generic Resource Provider|org.apache.sling.nosql.generic|1.1.0|Y|jar",
+  "NoSQL Couchbase Client|org.apache.sling.nosql.couchbase-client|1.0.2|Y|jar",
+  "NoSQL Couchbase Resource Provider|org.apache.sling.nosql.couchbase-resourceprovider|1.1.0|Y|jar",
+  "NoSQL MongoDB Resource Provider|org.apache.sling.nosql.mongodb-resourceprovider|1.1.0|Y|jar",
+  "Oak Restrictions|org.apache.sling.oak.restrictions|1.0.2|Y|jar",
+  "Pax Exam Utilities|org.apache.sling.paxexam.util|1.0.4|Y|jar",
+  "Performance Test Utilities|org.apache.sling.performance.base|1.0.2|org.apache.sling.performance|jar",
+  "Pipes|org.apache.sling.pipes|3.1.0|Y|jar",
+  "Provisioning Model|org.apache.sling.provisioning.model|1.8.4|Y|jar",
+  "Repoinit Parser|org.apache.sling.repoinit.parser|1.2.2|Y|jar",
+  "Resource Access Security|org.apache.sling.resourceaccesssecurity|1.0.0|Y|jar",
+  "Resource Builder|org.apache.sling.resourcebuilder|1.0.4|Y|jar",
+  "Resource Collection|org.apache.sling.resourcecollection|1.0.2|Y|jar",
+  "Resource Filter|org.apache.sling.resource.filter|1.0.0|Y|jar",
+  "Resource Inventory|org.apache.sling.resource.inventory|1.0.8|Y|jar",
+  "Resource Merger|org.apache.sling.resourcemerger|1.3.8|Y|jar",
+  "Resource Presence|org.apache.sling.resource.presence|0.0.2|Y|jar",
+  "Resource Resolver|org.apache.sling.resourceresolver|1.6.6|Y|jar",
+  "Rewriter|org.apache.sling.rewriter|1.2.2|Y|jar",
+  "Failing Server-Side Tests|org.apache.sling.testing.samples.failingtests|1.0.6|N|jar",
+  "Sample Integration Tests|org.apache.sling.testing.samples.integrationtests|1.0.6|N|jar",
+  "Sample Server-Side Tests|org.apache.sling.testing.samples.sampletests|1.0.6|N|jar",
+  "Scripting API|org.apache.sling.scripting.api|2.2.0|Y|jar",
+  "Scripting Console|org.apache.sling.scripting.console|1.0.0|Y|jar",
+  "Scripting Core|org.apache.sling.scripting.core|2.0.56|Y|jar",
+  "Scripting EL API Wrapper|org.apache.sling.scripting.el-api|1.0.0|Y|jar",
+  "Scripting Java|org.apache.sling.scripting.java|2.1.2|Y|jar",
+  "Scripting JavaScript|org.apache.sling.scripting.javascript|3.0.4|Y|jar",
+  "Scripting JSP|org.apache.sling.scripting.jsp|2.3.4|Y|jar",
+  "Scripting JSP API Wrapper|org.apache.sling.scripting.jsp-api|1.0.0|Y|jar",
+  "Scripting JSP Taglib|org.apache.sling.scripting.jsp.taglib|2.4.0|Y|jar",
+  "Scripting Groovy|org.apache.sling.scripting.freemarker|1.0.0|Y|jar",
+  "Scripting Groovy|org.apache.sling.scripting.groovy|1.0.4|Y|jar",
+  "Scripting HTL Runtime|org.apache.sling.scripting.sightly.runtime|1.1.0-1.4.0|Y|jar",
+  "Scripting HTL Compiler|org.apache.sling.scripting.sightly.compiler|1.1.2-1.4.0|Y|jar",
+  "Scripting HTL Java Compiler|org.apache.sling.scripting.sightly.compiler.java|1.1.2-1.4.0|Y|jar",
+  "Scripting HTL Engine|org.apache.sling.scripting.sightly|1.1.2-1.4.0|Y|jar",
+  "Scripting HTL JavaScript Use Provider|org.apache.sling.scripting.sightly.js.provider|1.0.28|Y|jar",
+  "Scripting HTL Sling Models Use Provider|org.apache.sling.scripting.sightly.models.provider|1.0.8|Y|jar",
+  "Scripting HTL REPL|org.apache.sling.scripting.sightly.repl|1.0.6|Y|jar",
+  "Scripting Thymeleaf|org.apache.sling.scripting.thymeleaf|2.0.0|Y|jar",
+  "Security|org.apache.sling.security|1.1.16|Y|jar",
+  "Service User Mapper|org.apache.sling.serviceusermapper|1.4.2|Y|jar",
+  "Service User WebConsole|org.apache.sling.serviceuser.webconsole|1.0.0|Y|jar",
+  "Servlet Annotations|org.apache.sling.servlets.annotations|1.2.4|Y|jar",
+  "Servlet Helpers|org.apache.sling.servlet-helpers|1.1.8|Y|jar",
+  "Servlets Get|org.apache.sling.servlets.get|2.1.40|Y|jar",
+  "Servlets Post|org.apache.sling.servlets.post|2.3.28|Y|jar",
+  "Servlets Resolver|org.apache.sling.servlets.resolver|2.5.2|Y|jar",
+  "Settings|org.apache.sling.settings|1.3.10|Y|jar",
+  "Slf4j MDC Filter|org.apache.sling.extensions.slf4j.mdc|1.0.0|Y|jar",
+  "Sling Query|org.apache.sling.query|4.0.2|Y|jar",
+  "Starter Content|org.apache.sling.starter.content|1.0.2|Y|jar",
+  "Starter Startup|org.apache.sling.starter.startup|1.0.6|Y|jar",
+  "Superimposing Resource Provider|org.apache.sling.superimposing|0.2.0|Y|jar",
+  "System Bundle Extension: Activation API|org.apache.sling.fragment.activation|1.0.2|Y|jar",
+  "System Bundle Extension: WS APIs|org.apache.sling.fragment.ws|1.0.2|Y|jar",
+  "System Bundle Extension: XML APIs|org.apache.sling.fragment.xml|1.0.2|Y|jar",
+  "Tenant|org.apache.sling.tenant|1.1.4|Y|jar",
+  "Testing Clients|org.apache.sling.testing.clients|1.2.0|Y|jar",
+  "Testing Email|org.apache.sling.testing.email|1.0.0|Y|jar",
+  "Testing Hamcrest|org.apache.sling.testing.hamcrest|1.0.2|Y|jar",
+  "Testing JCR Mock|org.apache.sling.testing.jcr-mock|1.4.2|Y|jar",
+  "Testing Logging Mock|org.apache.sling.testing.logging-mock|2.0.0|Y|jar",
+  "Testing OSGi Mock Core|org.apache.sling.testing.osgi-mock.core|2.4.6|org.apache.sling.testing.osgi-mock|jar",
+  "Testing OSGi Mock JUnit 4|org.apache.sling.testing.osgi-mock.junit4|2.4.6|org.apache.sling.testing.osgi-mock|jar",
+  "Testing OSGi Mock JUnit 5|org.apache.sling.testing.osgi-mock.junit5|2.4.6|org.apache.sling.testing.osgi-mock|jar",
+  "Testing PaxExam|org.apache.sling.testing.paxexam|2.0.0|Y|jar",
+  "Testing Rules|org.apache.sling.testing.rules|1.0.8|Y|jar",
+  "Testing Resource Resolver Mock|org.apache.sling.testing.resourceresolver-mock|1.1.22|Y|jar",
+  "Testing Server Setup Tools|org.apache.sling.testing.serversetup|1.0.1|Y|jar",
+  "Testing Sling Mock Core|org.apache.sling.testing.sling-mock.core|2.3.4|org.apache.sling.testing.sling-mock|jar",
+  "Testing Sling Mock JUnit 4|org.apache.sling.testing.sling-mock.junit4|2.3.4|org.apache.sling.testing.sling-mock|jar",
+  "Testing Sling Mock JUnit 5|org.apache.sling.testing.sling-mock.junit5|2.3.4|org.apache.sling.testing.sling-mock|jar",
+  "Testing Sling Mock Oak|org.apache.sling.testing.sling-mock-oak|2.1.2|Y|jar",
+  "Tooling Support Install|org.apache.sling.tooling.support.install|1.0.4|Y|jar",
+  "Tooling Support Source|org.apache.sling.tooling.support.source|1.0.4|Y|jar",
+  "URL Rewriter|org.apache.sling.urlrewriter|0.0.2|Y|jar",
+  "Validation API|org.apache.sling.validation.api|1.0.0|Y|jar",
+  "Validation Core|org.apache.sling.validation.core|1.0.4|Y|jar",
+  "Web Console Branding|org.apache.sling.extensions.webconsolebranding|1.0.2|Y|jar",
+  "Web Console Security Provider|org.apache.sling.extensions.webconsolesecurityprovider|1.2.0|Y|jar",
+  "XSS Protection|org.apache.sling.xss|2.1.0|Y|jar",
+  "XSS Protection Compat|org.apache.sling.xss.compat|1.1.0|N|jar"
+]
+                                                                      
+def deprecated=[
+  "Auth OpenID|Not Maintained|org.apache.sling.auth.openid|1.0.4",
+  "Auth Selector|Not Maintained|org.apache.sling.auth.selector|1.0.6",
+  "Background Servlets Engine|Not Maintained|org.apache.sling.bgservlets|1.0.8",
+  "Background Servlets Integration Test|Not Maintained|org.apache.sling.bgservlets.testing|1.0.0",
+  "Commons JSON|Replaced with Commons Johnzon|org.apache.sling.commons.json|2.0.20",
+  "Explorer|Replaced with Composum|org.apache.sling.extensions.explorer|1.0.4",
+  "GWT Integration|Not Maintained|org.apache.sling.extensions.gwt.servlet|3.0.0",
+  "JCR Compiler|Replaced with FS ClassLoader|org.apache.sling.jcr.compiler|2.1.0",
+  "JCR Jackrabbit Server|Replaced with Apache Jackrabbit Oak|org.apache.sling.jcr.jackrabbit.server|2.3.0",
+  "JCR Prefs|Replaced with CA Configs|org.apache.sling.jcr.prefs|1.0.0",
+  "Karaf repoinit|Removed|org.apache.sling.karaf-repoinit|0.2.0",
+  "Launchpad Content|Replaced with Starter Content|org.apache.sling.launchpad.content|2.0.12",
+  "Path-based RTP sample|Not Maintained|org.apache.sling.samples.path-based.rtp|2.0.4",
+  "Scripting JSP Taglib Compat|Superseded by the XSS API bundle|org.apache.sling.scripting.jsp.taglib.compat|1.0.0",
+  "Scripting JST|Not Maintained|org.apache.sling.scripting.jst|2.0.6",
+  "Servlets Compat|Not Maintained|org.apache.sling.servlets.compat|1.0.2",
+  "Testing Sling Mock Jackrabbit|Not Maintained|org.apache.sling.testing.sling-mock-jackrabbit|1.0.0",
+  "Testing Tools|SLING-5703|org.apache.sling.testing.tools|1.0.16",
+  "Thread Dumper|Replaced with Apache Felix Thread Dumper|org.apache.sling.extensions.threaddump|0.2.2"
+]
+
+// ------------------------------------------------------------------------------------------------
+// Utilities
+// ------------------------------------------------------------------------------------------------
+def downloadLink(label, artifact, version, suffix) {
+	def sep = version ? "-" : ""
+	def path = "sling/${artifact}${sep}${version}${suffix}"
+	def digestsBase = "https://www.apache.org/dist/${path}"
+
+	a(href:"[preferred]${path}", label)
+	yield " ("
+	a(href:"${digestsBase}.asc", "asc")
+	yield ", "
+	a(href:"${digestsBase}.sha1", "sha1")
+	yield ")"
+	newLine()
+}
+
+def githubLink(artifact,ghflag) {
+	if(ghflag == 'Y') {
+		artifact = artifact.replaceAll('\\.','-')
+    def url = "https://github.com/apache/sling-${artifact}"
+    // remove duplicate sling- prefix
+    url = url.replaceAll('sling-sling-','sling-')
+		a(href:url, "GitHub")
+		newLine()
+	} else if (ghflag != 'N') {
+		artifact = ghflag.replaceAll('\\.','-')
+    // remove duplicate sling- prefix
+    def url = "https://github.com/apache/sling-${artifact}"
+    url = url.replaceAll('sling-sling-','sling-')
+		a(href:url, "GitHub")
+		newLine()
+	} else {
+		yield "N/A"
+	}
+}
+
+def tableHead(String [] headers) {
+	thead() {
+		tr() {
+			headers.each { header ->
+				th(header)
+			}
+		}
+	}
+
+}
+
+ // ------------------------------------------------------------------------------------------------
+// Downloads page layout
+// ------------------------------------------------------------------------------------------------
+layout 'layout/main.tpl', true,
+        projects: projects,
+        tags : contents {
+            include template: 'tags-brick.tpl'
+        },
+        lastModified: contents {
+            include template : 'lastmodified-brick.tpl'
+        },
+        bodyContents: contents {
+
+            div(class:"row"){
+                div(class:"small-12 columns"){
+                    section(class:"wrap"){
+                        yieldUnescaped content.body
+
+						h2("Sling Application")
+						table(class:"table") {
+							tableHead("Artifact", "Version", "GitHub", "Provides", "Package")
+							tbody() {
+								slingApplication.each { line ->
+									tr() {
+										def data = line.split("\\|")
+										td(data[0])
+										td(data[4])
+										td(){
+											githubLink(data[2], data[5])
+										}
+										td(data[1])
+										def artifact = "${data[2]}-${data[4]}${data[3]}"
+										td(){
+											downloadLink(artifact, artifact, "", "")
+										}
+									}
+								}
+							}
+						}
+
+						h2("Sling IDE Tooling")
+						table(class:"table") {
+							tableHead("Artifact", "Version", "Provides", "Update Site")
+							tbody() {
+								slingIDETooling.each { line ->
+									tr() {
+										def data = line.split("\\|")
+										td(data[0])
+										td(data[2])
+										td(data[3])
+										def artifact = "${data[1]}/${data[2]}"
+										td(){
+											downloadLink("Update site", artifact, "", "")
+										}
+									}
+								}
+							}
+						}
+
+						h2("Sling Components")
+						table(class:"table") {
+							tableHead("Artifact", "Version", "GitHub", "Binary", "Source")
+							tbody() {
+								bundles.each { line ->
+									tr() {
+										def data = line.split("\\|")
+										td(data[0])
+										td(data[2])
+										def artifact = data[1]
+										def version = data[2]
+										def ghflag = data[3]
+										def extension = data[4]
+										td(){
+											githubLink(artifact,ghflag)
+										}
+										td(){
+											downloadLink("Bundle", artifact, version, "." + extension)
+										}
+										td(){
+											downloadLink("Source ZIP", artifact, version, "-source-release.zip")
+										}
+									}
+								}
+							}
+						}
+
+						h2("Maven Plugins")
+						table(class:"table") {
+							tableHead("Artifact", "Version", "GitHub", "Binary", "Source")
+							tbody() {
+								mavenPlugins.each { line ->
+									tr() {
+										def data = line.split("\\|")
+										td(data[0])
+										td(data[2])
+										def artifact = data[1]
+										def version = data[2]
+										def ghflag = data[3]
+										td(){
+											githubLink(artifact, ghflag)
+										}
+										td(){
+											downloadLink("Maven Plugin", artifact, version, ".jar")
+										}
+										td(){
+											downloadLink("Source ZIP", artifact, version, "-source-release.zip")
+										}
+									}
+								}
+							}
+						}
+    
+						h2("Deprecated")
+						table(class:"table") {
+							tableHead("Artifact", "Replacement", "Version", "Binary", "Source")
+							tbody() {
+								deprecated.each { line ->
+									tr() {
+										def data = line.split("\\|")
+										td(data[0])
+										td(data[1])
+										td(data[3])
+										def artifact = data[2]
+										def version = data[3]
+										td(){
+											downloadLink("Bundle", artifact, version, ".jar")
+										}
+										td(){
+											downloadLink("Source ZIP", artifact, version, "-source-release.zip")
+										}
+									}
+								}
+							}
+						}
+                    }
+                }
+            }
+        }
diff --git a/src/test/resources/releases.md b/src/test/resources/releases.md
new file mode 100644
index 0000000..aec47ec
--- /dev/null
+++ b/src/test/resources/releases.md
@@ -0,0 +1,1812 @@
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+    license agreements. See the NOTICE file distributed with this work for additional 
+    information regarding copyright ownership. The ASF licenses this file to 
+    you 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. -->
+
+title=Releases
+type=page
+status=published
+tags=news
+tableOfContents=false
+~~~~~~
+This is a list of all our releases, available from our [downloads](/downloads.cgi) page.
+
+## February 2019
+
+* DataSource Provider 1.0.4, Resource Collection API 1.0.2, JCR ResourceResolver 3.0.18 (26th)
+* Scripting JSP Tag Library 2.4.0, Scripting JSP Tag Library (Compat) 1.0.0 (18th)
+* Pipes 3.1.0 (15th)
+* Testing OSGi Mock 2.4.6 (14th)
+* Feature Model 1.0.0 and Feature Model IO 1.0.0 (1st)
+
+## January 2019
+
+* XSS Protection API 2.1.0 (29th)
+* Scripting HTL Runtime 1.1.0-1.4.0, Scripting HTL Compiler 1.1.2-1.4.0, Scripting HTL Java Compiler 1.1.2-1.4.0, Scripting HTL Engine 1.1.2-1.4.0, HTL Maven Plugin 1.2.4-1.4.0 (28th)
+* XSS Protection API 2.0.14 (24th)
+* Commons HTML 1.1.0 (22nd)
+* Tenant 1.1.4 (16th)
+* Servlets Post 2.3.28, Sling Maven Plugin 2.4.0 (14th)
+* Engine 2.6.18 (11th)
+
+## December 2018
+
+* JCR Jackrabbit Access Manager 3.0.4, JCR ContentLoader 2.3.0 (20th)
+* API 2.20.0, Servlets Resolver 2.5.2, Servlets Annotations 1.2.4 (18th)
+* Capabilities 0.1.2, Capabilities JCR 0.1.2 (17th)
+* JCR Base 3.0.6 (16th)
+* JCR Oak Server 1.2.2 (16th)
+* Servlet GET 2.1.40 (11th)
+* Testing Sling Mock Oak 2.1.2 (11th)
+* Distribution Core 0.4.0 (10th)
+* Commons ClassLoader 1.4.4, JCR ClassLoader 3.2.4 (8th)
+* Scripting Core 2.0.56 (4th)
+
+## November 2018
+
+* App CMS 0.11.2 (28th)
+* Testing JCR Mock 1.4.2, OSGi Mock 2.4.4 (19th)
+* Servlets Get 2.1.38 and Servlets Resolver 2.4.24 (13th)
+* Installer Vault Package Install Hook 1.0.4 (12th)
+* Distributed Event Admin 1.1.4, App CMS 0.11.0 (9th)
+* Models API 1.3.8 (8th)
+* Capabilities 0.1.0, Capabilities JCR 0.1.0, Scripting HTL Runtime 1.0.0-1.4.0, Scripting HTL Compiler 1.1.0-1.4.0, Scripting HTL Java Compiler 1.1.0-1.4.0, Scripting HTL Engine 1.1.0-1.4.0, HTL JS Use Provider 1.0.28, HTL Models Use Provider 1.0.8, Scripting HTL Testing Content 1.0.14-1.4.0, Scripting HTL Testing 1.0.14-1.4.0, HTL Maven Plugin 1.2.2-1.4.0 (5th)
+
+## October 2018
+
+* Sling 11, Slingstart Archetype 1.0.8, JUnit Tests Teleporter 1.0.18 (23rd)
+* Sling Oak Restrictions 1.0.2 (21nd)
+* Form Based Authentication Handler 1.0.12, Starter Content 1.0.2 (19th)
+* Installer Vault Package Install Hook 1.0.2 (15th)
+* Scripting HTL Engine 1.0.56-1.4.0, Scripting HTL Testing Content 1.0.12-1.4.0, Scripting HTL Testing 1.0.12-1.4.0, HTL Maven Plugin 1.2.0-1.4.0
+* Clam 1.0.0, Commons Clam 1.0.0 (1st)
+
+## September 2018
+
+* Security 1.1.16 (25th)
+* Distribution Core 0.3.4 (21st)
+* Jackrabbit UserManager Support 2.2.8, Jackrabbit JSR-283 Access Control Manager Support 3.0.2 (17th)
+* Pipes 3.0.2 (17th)
+* File Optimization 0.9.2, Clam 1.0.0, Commons Clam 1.0.0, Commons Metrics 1.2.6, Commons Mime 2.2.0, Scripting FreeMarker 1.0.0, Scripting Groovy 1.0.4, Scripting Thymeleaf 2.0.0, Service User Mapper 1.4.2, Settings 1.3.10 (12th)
+* Servlets Annotations 1.1.0 (11th)
+* Commons Log 5.1.10 (10th)
+* Resource Filter 1.0.0 (8th)
+* Context-Aware Configuration API 1.1.2 (5th)
+* Context-Aware Configuration SPI 1.3.4 (5th)
+* Context-Aware Configuration Impl 1.4.14 (5th)
+* Sling Tenant 1.1.2 (5th)
+* Testing Sling Mock 2.3.4 (3rd)
+* Testing OSGi Mock 2.4.2 (3rd)
+
+## August 2018
+
+* Servlets Get 2.1.34, Discovery Oak 1.2.28 (31st)
+* Testing JCR Mock 1.4.0, API 2.18.4, ResourceResolver 1.6.6 (27th)
+* Testing Sling Mock 2.3.2 (27th)
+* Installer Core 3.9.0 (27th)
+* Installer Factory Configuration 1.2.0 (27th)
+* Bundle Resource 2.3.2 (24th)
+* Resource Builder 1.0.4 (21th)
+* Testing JCR Mock 1.3.6 (21th)
+* ResourceResolver Mock 1.1.22 (21th)
+* OSGi Mock 2.4.0 (21th)
+* Sling Mock 2.3.0 (21th)
+* Sling Mock Oak 2.1.0 (21th)
+* Context-Aware Configuration Mock Plugin 1.3.2 (21th)
+* Maven Sling Plugin 2.3.8 (17th)
+* JCR Repository Registration 1.0.6 (14th)
+* Apache Sling JCR Resource Resolver 3.0.16 (14th)
+* Dynamic Include 3.1.2 (14th)
+* Engine 2.16.14 (13th)
+* Parent POM 34 (9th)
+* Scripting HTL Java Compiler 1.0.26-1.4.0 (7th)
+* HTL Maven Plugin 1.1.8-1.4.0 (7th)
+* XSS Protection API 2.0.12 (7th)
+* Servlet Helpers 1.1.8 (6th)
+* Testing JCR Mock 1.3.4 (6th)
+* Testing OSGi Mock 2.3.10 (6th)
+* Testing Sling Mock 2.2.20 (6th)
+* Resource Resolver 1.6.4 (3rd)
+* JCR Resource 3.0.14 (3rd)
+* File Optimization 0.9.0 (1st)
+* App CMS 0.9.0 (1st)
+
+## July 2018
+
+* API 2.18.2 (30th)
+* Sling Content Loader 2.2.6 (6th)
+* XSS Protection API 2.0.8 (3rd)
+
+## June 2018
+
+* Scripting HTL Compiler 1.0.22-1.4.0 (22nd)
+* Scripting HTL Java Compiler 1.0.24-1.4.0 (22nd) 
+* Scripting HTL Engine 1.0.54-1.4.0 (22nd)
+* Scripting HTL Testing Content 1.0.10-1.4.0 (22nd)
+* Scripting HTL Testing 1.0.10-1.4.0 (22nd) 
+* HTL Maven Plugin 1.1.6-1.4.0 (22nd)
+* Scripting HTL REPL 1.0.6 (22nd)
+* Servlet Annotations 1.0.0 (19th)
+* Commons Threads 3.2.18 (19th)
+* SlingStart Maven Plugin 1.8.2 (16th)
+* Feature Model 0.1.2 (2nd)
+
+## May 2018
+
+* Commons Log 5.1.8 (24th) 
+* JSP Taglib 2.3.0 (22nd) 
+* Servlets Post 2.3.26 (22nd)
+* Form Based Authentication 1.0.10 (22nd)
+* Starter Content 1.0.0 (22nd)
+* Starter Startup 1.0.6 (22nd)
+* Servlets Get 2.1.32 (21st)
+* Servlet Helpers 1.1.6 (12th)
+* Commons HTML 1.0.2 (12th)
+* IDE tooling for Eclipse 1.2.2 (9th)
+* Context-Aware Configuration Impl 1.4.12 (7th)
+* Maven Sling Plugin 2.3.6 (7th)
+* Sling Query 4.0.2 (5th)
+* JCR Content Parser 1.2.6 (5th)
+* Feature Model 0.1.0 (1st)
+
+## April 2018
+
+* Commons Log 5.1.6 (24th)
+* File System Resource Provider 2.1.14 (23rd)
+* Installer Heath Checks 2.0.0 (11th)
+
+## March 2018
+
+* Commons Log 5.1.4 (26th)
+* Testing OSGi Mock 2.3.8 (23th)
+* Resource Resolver 1.6.0 (22nd)
+* JCR Resource 3.0.10 (22nd)
+* API 2.18.0 (19th)
+* Security 1.1.12 (19th)
+* XSS Protection API 2.0.6
+* Scripting HTL Engine 1.0.52-1.3.1 (16th)
+* Scripting HTL Testing 1.0.8-1.3.1 (16th)
+* Testing PaxExam 2.0.0 (7th)
+* JCR Oak Server 1.2.0 (7th)
+* Models Impl 1.4.8 (5th)
+* Testing Sling Mock 2.2.18 (1st)
+* Servlet Helpers 1.1.4 (1st)
+
+## February 2018
+
+* Installer Core 3.8.12 (19th)
+* Sling Pipes 2.0.2 (7th)
+* Discovery Base 2.0.8 (6th)
+* Discovery Support 1.0.4 (6th)
+* File System Resource Provider 2.1.12 (5th)
+* Starter 10 (3rd)
+* Launchpad Testing 10 (3rd)
+* Launchpad Testing WAR 10 (3rd)
+* Launchpad Integration Tests 1.0.6 (3rd)
+* Launchpad Test Bundles 0.0.4 (3rd)
+* Launchpad Testing Fragment Bundle 2.0.14 (3rd)
+* Launchpad Testing Services 2.0.14 (3rd)
+* Launchpad Testing Services WAR 2.0.14 (3rd)
+* Archetype Parent 5 (3rd)
+* Bundle Archetype 1.0.6 (3rd)
+* JCRInstall Bundle Archetype 1.0.6 (3rd)
+* Initial Content Archetype 1.0.6 (3rd)
+* Slingstart Archetype 1.0.6 (3rd)
+* Testing PaxExam 1.0.0 (2nd)
+* Scripting HTL Compiler 1.0.20-1.3.1 (1st)
+* Scripting HTL Java Compiler 1.0.22-1.3.1 (1st)
+* Scripting HTL Engine 1.0.48-1.3.1 (1st)
+* Scripting HTL Testing Content 1.0.8-1.3.1 (1st)
+* Scripting HTL Testing 1.0.6-1.3.1 (1st)
+* HTL Maven Plugin 1.1.4-1.3.1 (1st)
+
+## January 2018
+
+* Thread Support 3.2.16 (31st)
+* I18N Support 2.5.12 (29th)
+* Testing Sling Mock 1.9.12 (29th)
+* Testing Sling Mock 2.2.16 (29th)
+* Resource Merger 1.3.8 (20th)
+* Parent 33 (20th)
+* Context-Aware Configuration Impl 1.4.10 (19th)
+* Commons Compiler 2.3.6 (19th)
+* ServiceUser Mapper 1.4.0 (18th)
+* ServiceUser WebConsole 1.0.0 (18th)
+* SlingStart Maven Plugin 1.7.16 (15th)
+* File System Resource Provider 2.1.10 (15th)
+* Resource Merger 1.3.6 (15th)
+* XSS Protection API 2.0.4 (8th)
+
+## December 2017
+
+* Validation Core 1.0.4 (21st)
+* Test Services 1.0.4 (21st)
+* Slingstart Maven Plugin 1.7.14 (21st)
+* Scripting Core 2.0.54 (19th)
+* Scripting JavaScript 3.0.4 (19th)
+* Scripting HTL JS Use Provider 1.0.26 (19th)
+* Scripting HTL Compiler 1.0.16 (19th)
+* Scripting HTL Engine 1.0.46 (19th)
+* Auth Core 1.4.0 (18th)
+* Servlets Resolver 2.4.22 (13th)
+* Scripting HTL Java Compiler 1.0.18 (8th)
+* HTL Maven Plugin 1.1.2 (8th)
+* Commons Metrics 1.2.4 (5th)
+* Scripting JSP 2.3.4 (4th)
+* Commons Log 5.1.0 (1st)
+* Metrics RRD4J 1.0.2 (1st)
+* Engine 2.6.10 (1st)
+* Feature Flags 1.2.2 (1st)
+* i18n 2.5.10 (1st)
+* Security 1.1.10 (1st)
+
+## November 2017
+
+* Event Support 4.2.10 (30th)
+* JCR Registration 1.0.4 (30th)
+* Scripting HTL Java Compiler 1.0.16 (27th)
+* Scripting HTL Engine 1.0.44 (27th)
+* HTL Maven Plugin 1.1.0 (27th)
+* Starter Startup 1.0.4 (27th)
+* Security 1.1.8 (20th)
+* Context-Aware Configuration Impl 1.4.8 (13th)
+* Sling API 2.16.4 (6th)
+* Sling JCR ResourceResolver 3.0.6 (6th)
+* Sling Default GET Servlets 2.1.28 (6th)
+
+## October 2017
+
+* Scripting Core 2.0.50 (23rd)
+* Maven Sling Plugin 2.3.4 (17th)
+* Servlet Helpers 1.0.2 (17th)
+* Servlet Helpers 1.1.2 (17th)
+* JCR Mock 1.3.2 (17th)
+* ResourceResolver Mock 1.1.20 (17th)
+* OSGi Mock 1.9.8 (17th)
+* OSGi Mock 2.3.4 (17th)
+* Sling Mock 1.9.10 (17th)
+* Sling Mock 2.2.14 (17th)
+* Discovery Oak 1.2.22 (17th)
+* Starter Startup 1.0.2 (10th)
+* Context-Aware Configuration Impl 1.4.6 (9th)
+* Query 4.0.0 (4th)
+* Thread Support 3.2.10 (2nd)
+
+## September 2017
+
+* Scripting Core 2.0.48 (29th)
+* Event Support 4.2.8 (29th)
+* SlingStart Maven Plugin 1.7.10 (29th)
+* JUnit Tests Teleporter 1.0.16 (29th)
+* Testing Utilities 2.1.2 (29th)
+* Pipes 1.1.0 (24th)
+* Maven Sling Plugin 2.3.2 (23th)
+* Repoinit JCR version 1.1.6 (22th)
+* Repoinit Parser version 1.2.0 (22th)
+* Context-Aware Configuration Impl 1.4.4 (22th)
+* Scripting HTL Compiler 1.0.14 (20th)
+* Scripting HTL Java Compiler 1.0.14 (20th)
+* Scripting HTL Engine 1.0.42 (20th)
+* Commons Scheduler 2.7.2 (19th)
+* Commons Compiler 2.3.4 (17th)
+* Commons Compiler 2.3.2 (9th)
+* RRD4J metrics reporter 1.0.0 (8th)
+* Scripting JavaScript 3.0.2 (4th)
+* Scripting HTL JS Use Provider 1.0.24 (4th)
+* Scripting HTL Engine 1.0.40 (4th)
+* Parent POM 32 (4th)
+* Java Version Maven Plugin 1.0.0 (4th)
+* Scripting HTL Compiler 1.0.12 (1st)
+* Scripting HTL Java Compiler 1.0.12 (1st)
+* Scripting HTL Engine 1.0.38 (1st)
+
+## August 2017
+
+* Launchpad Base 5.6.8-2.6.24 (31st)
+* Provisioning Model 1.8.4 (28th)
+* Slingstart Maven Plugin 1.7.8 (28th)
+* Servlets Resolver 2.4.14 (28th)
+* Commons Scheduler 2.7.0 (25th)
+* Scripting JSP 2.3.2 (24th)
+* Rewriter 1.2.2 (17th)
+* Launchpad Base 5.6.6-2.6.22 (17th)
+* Event 4.2.6 (16th)
+* Default POST Servlets 2.3.22 (14th)
+* Parent 31 (8th)
+* Security 1.1.6 (7th)
+* Scripting HTL Engine 1.0.38 (7th)
+* Scripting HTL Compiler 1.0.10 (7th)
+* HTL Maven Plugin 1.0.8 (7th)
+* Launchpad Base 5.6.6-2.6.20 (3rd)
+
+## July 2017 
+
+* Resource Resolver 1.5.30 (27th)
+* Service User Mapper 1.3.4 (21th)
+* Resource Resolver 1.5.28 (21th)
+* JCR Base 3.0.4 (21th)
+* JCR Resource 3.0.4 (21th)
+* File System Resource Provider 2.1.8 (18th)
+* File System Resource Provider 1.4.8 (18th)
+* Commons Johnzon 1.1.0 (17th)
+* Discovery Base 2.0.4 (10th)
+* Discovery Oak 1.2.20 (10th)
+* Resource Resolver 1.5.26 (10th)
+
+## June 2017 
+
+* Auth Core 1.4.0 (29th)
+* Event 4.2.4 (26th)
+* JCR Content Parser 1.2.4 (26th)
+* File System Resource Provider 2.1.6 (26th)
+* File System Resource Provider 1.4.6 (26th)
+* Security 1.1.4 (21st)
+* Testing Clients 1.1.4 (20th)
+* Testing Email 1.0.0 (20th)
+* Resource Merger 1.3.4 (20th)
+* Slingstart Archetype (15th)
+* JSPC Maven Plugin 2.1.0 (15th)
+* Slingstart Archetype 1.0.2 (15th)
+* Sling 9
+* Launchpad Testing 9
+* Launchpad Testing WAR version 9 (12th)
+* Launchpad Testing Fragment Bundle 2.0.12 (12th)
+* Launchpad Testing Services 2.0.12 (12th)
+* Launchpad Test Bundles 0.0.2 (12th)
+* Launchpad Testing Services WAR 2.0.12 (12th)
+* Integration Tests 1.0.4 (12th)
+* JUnit Core 1.0.26 (6th)
+* Testing Clients 1.1.0 (6th)
+* JUnit Remote Test Runners 1.0.12 (6th)
+* Tooling Support Install 1.0.4 (6th)
+* Tooling Support Source 1.0.4 (6th)
+* Resource Inventory 1.0.8 (6th)
+* Content Distribution Core 0.2.8 (6th)
+* Testing Sling Mock 2.2.12 (6th)
+* Log Tracer 1.0.4 (6th)
+* Commons Metrics 1.2.2 (6th)
+* JCR Content Parser 1.2.2 (2nd)
+* JCR ContentLoader 2.2.4 (2nd)
+* File System Resource Provider 2.1.4 (2nd)
+* File System Resource Provider 1.4.4 (2nd)
+* Maven Sling Plugin 2.3.0 (2nd)
+* SLF4J Implementation (Logback) 5.0.2 (1st)
+
+## May 2017
+
+* JCR Resource 3.0.2 (31st)
+* JCR Content Parser 1.2.0 (29th)
+* File System Resource Provider 2.1.2 (29th)
+* File System Resource Provider 1.4.2 (29th)
+* Maven Sling Plugin 2.2.2 (29th)
+* Context-Aware Configuration SPI 1.3.2 (29th)
+* Context-Aware Configuration Impl 1.4.2 (29th)
+* Context-Aware Configuration Mock Plugin 1.3.0 (29th)
+* Launchpad Content 2.0.12 (29th)
+* Servlet Post 2.3.20 (28th)
+* JCR Contentloader 2.2.2 (28th)
+* Launchpad Base 5.6.4-2.6.18 (28th)
+* Service User Mapper 1.3.2 (22nd)
+* JCR Base Bundle 3.0.2 (22nd)
+* Web Console Branding 1.0.2 (22nd)
+* Engine Implementation 2.6.8 (22nd)
+* Servlets Get 2.1.26 (19th)
+* Servlets Post 2.3.18 (19th)
+* Commons Scheduler 2.6.2 (18th)
+* Installer Core 3.8.10 (18th)
+* Models Impl 1.4.2 (15th)
+* Testing OSGi Mock 2.3.2 (15th)
+* OSGi Mock 1.9.6 (15th)
+* Sling Mock 2.2.10 (15th)
+* Sling Mock 1.9.8 (15th)
+* Auth Core 1.3.24 (15th)
+* JUnit Scriptable Tests Provider 1.0.12 (12th)
+* XSS Protection Compat Bundle 1.1.0 (11th)
+* Scripting JavaScript 3.0.0 (11th)
+* Junit Core 1.0.24 (11th)
+* Junit Teleporter 1.0.14 (11th)
+* Testing Tools 1.0.16 (11th)
+* Adapter 2.1.10 (11th)
+* Servlets Get 2.1.24 (11th)
+* Servlets Post 2.3.16 (11th)
+* JCR Jackrabbit Access Manager 3.0.0 (11th)
+* Healthcheck API 1.0.0 (11th)
+* Healthcheck Core 1.2.8 (11th)
+* Discovery Commons 1.0.20 (11th)
+* Discovery Base 2.0.0 (11th)
+* Discovery Impl 1.2.12 (11th)
+* Discovery Oak 1.2.18 (11th)
+* Scripting HTL Java Compiler 1.0.10 (9th)
+* Scripting HTL Engine 1.0.34 (9th)
+* Scripting HTL JS Use Provider 1.0.22 (9th)
+* Servlets Resolver 2.4.12 (9th)
+* Installer Core 3.8.8 (8th)
+* JCR ContentLoader 2.2.0 (8th)
+* Pax Exam Utilities 1.0.4 (8th)
+* File System Resource Provider 2.1.0 (8th)
+* File System Resource Provider 1.4.0 (8th)
+* JCR Content Parser 1.1.0 (8th)
+* XSS Protection Bundle 2.0.0 (5th)
+* XSS Protection Compat Bundle 1.0.0 (5th)
+* Sling Resource Resolver 1.5.24 (5th)
+* Context-Aware Configuration Impl 1.4.0 (5th)
+* Context-Aware Configuration Mock Plugin 1.2.0 (5th)
+* Testing JCR Mock 1.3.0 (5th)
+* OSGi Mock 2.3.0 (5th)
+* Sling Mock 2.2.8 (5th)
+* Models API 1.3.4 (1st)
+* Models Implementation 1.4.0 (1st)
+* JCR Installer Provider 3.1.26 (1st)
+* JCR Resource 3.0.0 (1st)
+* Sling Slingstart Maven Plugin 1.7.4 (1st)
+* Service User Mapper 1.3.0 (1st)
+* Scripting API 2.2.0
+* Tooling Support Source 1.0.2 (1th)
+
+## April 2017
+
+* Commons Johnzon 1.0.0 (29th)
+* Event API 1.0.0 (19th)
+* Validation API (12th)
+* Validation Core 1.0.0 (12th)
+* Testing ResourceResolver Mock 1.1.18 (4th)
+* JCR Jackrabbit User Manager 2.2.6 (3rd)
+
+## March 2017
+
+* Resource Resolver 1.5.22 (30th)
+* Service User Mapper 1.2.6 (30th)
+* Testing Sling Mock 2.2.6 (30th)
+* Sling Mock 1.9.6 (30th)
+* Sling Mock Oak 1.0.2 (30th)
+* Context-Aware Configuration Implementation 1.3.2 (30th)
+* File System Resource Provider 2.0.0 (30th)
+* File System Resource Provider 1.3.0 (30th)
+* CAConfig SPI 1.3.0 (24th)
+* CAConfig Impl 1.3.0 (24th)
+* CAConfig Mock Plugin 1.1.0 (24th)
+* Maven Sling Plugin 2.2.0 (24th)
+* JCR Content Parser 1.0.0 (23th)
+* Testing OSGi Mock 2.2.4 (23th)
+* Testing OSGi Mock 1.9.4 (23th)
+* Commons JSON 2.0.20 (20th)
+* Karaf repoinit 0.2.0 (20th)
+* Scripting JSP API Wrapper 1.0.0 (20th)
+* Scripting JSP EL Wrapper 1.0.0 (20th)
+* Scripting JSP 2.3.0 (20th)
+* Testing PaxExam 0.0.4 (20th)
+* JCR Oak Server 1.1.4 (20th)
+* Scripting Thymeleaf 1.1.0 (20th)
+* Resource Presence 0.0.2 (20th)
+* Resource Resolver 1.5.20 (13th)
+* JCR Repoinit 1.1.4 (13th)
+* i18n 2.5.8 (8th)
+* JCR Installer 3.1.24 (8th)
+* XSS 1.0.18 (8th)
+* HTL JavaScript Use Provider 1.0.20 (8th)
+* Scripting Core 2.0.46 (8th)
+* Health Check Core 1.2.6 (8th)
+* Event 4.2.2 (8th)
+* Distributed Event Admin 1.1.2 (8th)
+* Content Distribution Core 0.2.6 (2nd)
+* Installer Health Checks 1.0.0 (2nd)
+* Parent 30 (Mar 6th) (2nd)
+* Scripting HTL Compiler 1.0.8 (2nd)
+* Scripting HTL Engine 1.0.32 (2nd)
+* Commons Classloader 1.4.0 (1st)
+* Commons File System Classloader 1.0.6 (1st)
+
+## February 2017
+
+* Resource Resolver 1.5.14 (28th)
+* JUnit Tests Teleporter 1.0.12 (28th)
+* Slingstart Maven Plugin 1.7.2 (28th)
+* Installer Core 3.8.6 (20th)
+* Content Distribution Core 0.2.4 (20th)
+* Content Distribution Core 0.2.0 (14th)
+* Servlets GET 2.1.22 (12th)
+* Resource Merger 1.3.2 (8th)
+* DavEx Access to repositories 1.3.8 (8th)
+* Simple WebDAV Access to repositories 2.3.8 (8th)
+* Launchpad Base 2.6.16 (5th)
+* Servlets GET 2.1.20 (3rd)
+* Commons ClassLoader 1.3.8 (3rd)
+
+## January 2017 
+
+* Resource Inventory 1.0.6 (31st)
+* Installer Core 3.8.2 (31st)
+* JSP 2.2.6 (30th)
+* Auth Core 1.3.24 (30th)
+* File System Resource Provider 1.2.2 (23th)
+* Maven Sling Plugin 2.1.10 (23th)
+* Resource Resolver 1.5.12 (23th)
+* Tenant 1.1.0 (17th)
+* Scripting HTL Compiler 1.0.6 (17th)
+* Scripting HTL Java Compiler 1.0.8 (17th)
+* Scripting HTL Engine 1.0.30 (17th)
+* HTL Maven Plugin 1.0.6 (17th)
+* JSP 2.2.4 (16th)
+* Resource Resolver 1.5.10 (13th)
+* JUnit Core 1.0.23 (11th)
+* JUnit Tests Teleporter 1.0.10 (11th)
+* Testing Clients 1.0.1 (11th)
+* Server Setup Tools 1.0.1 (11th)
+* Testing Rules 1.0.1 (11th)
+* Scripting HTL Compiler 1.0.4 (9th)
+* Scripting HTL Java Compiler 1.0.6 (9th)
+* Scripting HTL Engine 1.0.28 (9th)
+* Scripting HTL Models Use Provider 1.0.6 (9th)
+* Scripting HTL JS Use Provider 1.0.18 (9th)
+* HTL Maven Plugin 1.0.4 (9th)
+* Testing Hamcrest 1.0.2 (7th)
+
+## December
+
+* Testing ResourceResolver Mock 1.1.16 (27th)
+* Servlets Resolver 2.4.10 (24th)
+* File System Classloader 1.0.4 (24th)
+* Installer Console 1.0.2 (24th)
+* Resource Resolver 1.5.8 (23rd)
+* JCR Resource 2.9.2 (23rd)
+* Slingshot Sample 0.8.0 (23rd)
+* Sling Mock 2.2.4 (22th)
+* Sling Mock 1.9.4 (22th)
+* JUnit Core 1.0.22 (22th)
+* Models API 1.3.2 (22th)
+* Models Impl 1.3.8 (22th)
+* Service User Mapper 1.2.4 (22th)
+* JCR Base 3.0.0 (20th)
+* Dynamic Include 3.0.0 (20th)
+* i18n 2.5.6 (19th)
+* JCR RepoInit module 1.1.2 (19th)
+* API 2.16.2 (18th)
+* Slingstart Maven Plugin 1.7.0 (18th)
+* JCR Resource 2.9.0 (16th)
+* Scripting JSP 2.2.2 (16th)
+* Scripting Java 2.1.2 (16th)
+* Provisioning Model 1.8.0 (16th)
+* Testing JCR Mock 1.2.0 (16th)
+* OSGi Mock 2.2.2 (16th)
+* OSGi Mock 1.9.2 (16th)
+* Sling Mock 2.2.2 (16th)
+* Sling Mock 1.9.2 (16th)
+* JUnit Core 1.0.20 (16th)
+* Context-Aware Configuration API 1.1.0 (16th)
+* Context-Aware Configuration SPI 1.2.0 (16th)
+* Context-Aware Configuration Impl 1.2.0 (16th)
+* Context-Aware Configuration bnd Plugin 1.0.2 (16th)
+* Context-Aware Configuration Mock Plugin 1.0.0 (16th)
+* Scripting API 2.1.12 (15th)
+* Scripting Core 2.0.44 (15th)
+* JCR Installer 3.1.22 (13th)
+* Commons Metrics 1.2.0 (13th)
+* OSGi Mock 2.2.0 (8th)
+* OSGi Mock 1.9.0 (8th)
+* Sling Mock 2.2.0 (8th)
+* Sling Mock 1.9.0 (8th)
+* API 2.16.0 (6th)
+* Resource Resolver 1.5.6 (6th)
+* Servlets Resolver 2.4.8 (6th)
+* JCR Resource 2.8.4 (6th)
+
+## November 2016
+
+* Models bnd Plugin 1.0.0 (24th)
+* Commons ClassLoader 1.3.6 (24th)
+* JCR Resource 2.8.2 (22th)
+* Security 1.1.2 (22th)
+* Models Implementation 1.3.4 (22th)
+* Models Jackson Exporter 1.0.4 (22th)
+* Resource Resolver 1.5.4 (21st)
+* Discovery Base 1.1.6 (21st)
+* Discovery Commons 1.0.18 (21st)
+* Discovery Impl 1.2.10 (21st)
+* Discovery Oak 1.2.16 (21st)
+* Auth Core 1.3.22 (15th)
+* JCR Base 2.4.2 (14th)
+* Provisioning Model 1.7.0 (13th)
+* Slingstart Maven Plugin 1.6.0 (13th)
+* JCR Repoinit 1.1.0 (12th)
+* Repoinit Parser 1.1.0 (12th)
+* Slingstart Maven Plugin 1.5.0 (11th)
+* Installer Core 3.8.0 (10th)
+* Context-Aware Configuration SPI 1.1.0 (10th)
+* Context-Aware Configuration Impl 1.1.0 (10th)
+* Resource Resolver 1.5.2 (8th)
+* Provisioning Model 1.6.0 (8th)
+* HTL Maven Plugin 1.0.2 (8th)
+* Commons Mime 2.1.10 (7th)
+* Web Console Security Provider 1.2.0 (6th)
+* Models API 1.3.0 (3th)
+* Models Implementation 1.3.0 (3th)
+* Models Jackson Exporter 1.0.0 (3th)
+
+## October 2016
+
+* Launchpad Base 2.6.14 (31st)
+* Provisioning Model 1.5.0 (31st)
+* XSS Protection API 1.0.16 (31st)
+* Commons Scheduler 2.5.2 (27th)
+* API 2.15.0 (25st)
+* Resource Resolver 1.5.0 (25st)
+* Installer Core 3.7.0 (25st)
+* Scripting HTL Engine 1.0.26 (24th)
+* Commons Log 5.0.0 (24th)
+* Log WebConsole 1.0.0 (24th)
+* DataSource Provider 1.0.2 (24th)
+* Log Tracer 1.0.2 (24th)
+* Servlets Resolver 2.4.6 (22nd)
+* Scripting JSP 2.2.0 (20th)
+* Engine 2.6.6 (20th)
+* Scripting Java 2.1.0 (20th)
+* Scripting HTL JS Use Provider 1.0.16 (20th)
+* Context-Aware Configuration API 1.0.0
+* Context-Aware Configuration SPI 1.0.0 (18th)
+* Context-Aware Configuration Impl 1.0.0 (18th)
+* Context-Aware Configuration bnd Plugin 1.0.0 (18th)
+* Resource Builder 1.0.2 (18th)
+* Testing Hamcrest 1.0.0 (18th)
+* Scripting Core 2.0.40 (17th)
+* Scripting HTL Java Compiler 1.0.4 (17th)
+* Scripting HTL Engine 1.0.24 (17th)
+* Launchpad Base 2.6.12 (16th)
+* Event 3.4.0 (15th)
+* Distributed Eventing 1.1.0 (15th)
+* Rewriter 1.2.0 (15th)
+* Pipes 0.0.10 (14th)
+* Scripting HTL Compiler 1.0.2 (13th)
+* Scripting HTL Java Compiler 1.0.2 (13th)
+* Scripting HTL Engine 1.0.22 (13th)
+* Scripting HTL JS Use Provider 1.0.14 (13th)
+* Scripting HTL Models Use Provider 1.0.4 (13th)
+* Testing Sling Mock 2.1.2 (10th)
+* i18n 2.5.4 (8th)
+* Oak Restrictions 1.0.0 (3rd)
+
+## September 2016
+
+* Discovery Commons 1.0.16 (29th)
+* Discovery Oak 1.2.14 (29th)
+* Testing Clients 1.0.0 (16th)
+* Server Setup Tools 1.0.0 (16th)
+* Testing Rules 1.0.0 (16th)
+* Auth Core 1.3.20 (19th)
+* JUnit Core 1.0.18 (19th)
+* JUnit Tests Teleporter 1.0.8 (19th)
+* Testing Logging Mock 2.0.0 (19th)
+* JCR Mock 1.1.16 (19th)
+* OSGi Mock 1.8.0 (19th)
+* OSGi Mock 2.1.0 (19th)
+* Sling Mock 1.8.0 (19th)
+* Sling Mock 2.1.0 (19th)
+* Sling Mock Oak 2.0.2 (19th)
+* Resource Builder 1.0.0 (19th)
+* Servlet Helpers 1.1.0 (19th)
+* Scripting HTL Compiler 1.0.0 (8th)
+* Scripting HTL Java Compiler 1.0.0 (8th)
+* Scripting HTL Engine 1.0.20 (8th)
+* Scripting HTL JS Use Provider 1.0.12 (8th)
+* Scripting HTL Models Use Provider 1.0.2 (8th)
+* Scripting HTL REPL 1.0.4 (8th)
+* HTL Maven Plugin 1.0.0 (8th)
+* Discovery Oak 1.2.10 (5th)
+
+## August 2016
+
+* RepoInit Parser 1.0.4 (29th)
+* RepoInit JCR module 1.0.2 (29th)
+* XSS Protection API 1.0.14 (29th)
+* Auth Core 1.3.18 (29th)
+* Testing Tools 1.0.14 (29th)
+* Engine 2.6.2 (26th)
+* Commons Testing 2.1.0 (26th)
+* API 2.14.2 (26th)
+* Resource Resolver 1.4.18 (26th)
+* Servlets Get 2.1.18 (25th)
+* Engine 2.6.0 (22nd)
+* Feature Flags 1.2.0 (22nd)
+* Background Servlets 1.0.8 (19th)
+* XSS Protection API 1.0.12 (19th)
+* I18n 2.5.2 (18th)
+* Hypermedia API client-side tools 1.0.0 (18th)
+* Testing PaxExam 0.0.2 (17th)
+* JCR Oak Server 1.1.0 (17th)
+* Security 1.1.0 (15th)
+* i18n 2.5.0 (8th)
+* i18n 2.4.10 (8th)
+* Engine 2.5.0 (5th)
+* i18n 2.4.8 (5th)
+* Feature Flags 1.1.0 (5th)
+* Event Support 4.1.0 (1st)
+
+## July 2016
+
+* Resource Resolver 1.4.16 (25th)
+* Launchpad Testing Services 2.0.10 (25th)
+* Launchpad Testing Services WAR 2.0.10 (25th)
+* Launchpad Integration Tests 1.0.2 (25th)
+* API 2.14.0 (25th)
+* Commons Scheduler 2.5.0 (24th)
+* Resource Resolver 1.4.14 (21st)
+* Discovery Base 1.1.4 (17th)
+* Discovery Impl 1.2.8 (17th)
+* Discovery Oak 1.2.8 (17th)
+* Testing Sling Mock 1.7.0 (15th)
+* Sling Mock 2.0.0 (15th)
+* Sling Mock Oak 2.0.0 (15th)
+* Commons Testing 2.0.26 (13th)
+* Scripting Core 2.0.38 (13th)
+* Servlets Resolver 2.4.4 (13th)
+* Repoinit Parser 1.0.2 (11th)
+* Repoinit JCR 1.0.0 (11th)
+* API 2.12.0 (9th)
+* Scripting Thymeleaf 1.0.0 (4th)
+
+## June 2016
+
+* Auth Core 1.3.16 (29th)
+* Adapter Manager 2.1.8 (28th)
+* Repository API Bundle 2.4.0 (27th)
+* JCR Base Bundle 2.4.0 (27th)
+* Rewriter 1.1.4 (26th)
+* JCR Resource 2.8.0 (22nd)
+* Scripting JavaScript 2.0.30 (22nd)
+* Testing JCR Mock 1.1.14 (13th)
+* OSGi Mock 2.0.4 (13th)
+* ResourceResolver Mock 1.1.14 (13th)
+* Provisioning Model 1.4.4
+* Slingstart Maven Plugin 1.4.4 (10th)
+* Servlets Post 2.3.12 (1st)
+
+## May 2016
+
+* JSON Library 2.0.16 (27th)
+
+## April 2016
+
+* Discovery API 1.0.4 (29th)
+* Log Tracer version 1.0.0 (25th)
+* Resource Resolver 1.4.12 (25th)
+* Scripting JSP-Taglib version 2.2.6 (21st)
+* Auth Core 1.3.14 (12th)
+* Servlets Post (10th)
+* Resource Resolver (7th)
+* Event 4.0.2 (4th)
+
+## March 2016
+
+* Discovery Commons 1.0.12 (29th)
+* Scripting Sightly Engine 1.0.18 (18th)
+* Apache Maven Sling Plugin 2.1.8 (16th)
+* IDE Tooling for Eclipse 1.1.0 (14th)
+* Resource Resolver 1.4.8 (11th)
+* JCR Resource 2.7.4 (11th)
+* Installer Core 3.6.8 (11th)
+* Health Check Core 1.2.4 ( 8th)
+* Health Checks Annotations 1.0.4 ( 8th)
+* JCR Davex 1.3.2 ( 8th)
+* JCR Webdav 2.3.4 ( 8th)
+* Scripting Sightly Engine 1.0.16 (5th)
+* Tooling Support Source 1.0.0 (3rd)
+* Background Servlets Engine 1.0.6 (2nd)
+* Background Servlets Integration Test 1.0.0 (2nd)
+
+## February 2016
+
+* NoSQL Generic Resource Provider 1.1.0 (27th)
+* Couchbase Client 1.0.2 (27th)
+* Couchbase Resource Provider 1.1.0 (27th)
+* MongoDB Resource Provider 1.1.0 (27th)
+* Resource Resolver 1.4.4 (26th)
+* Scripting Sightly Engine 1.0.14 (26th)
+* JCR Base 2.3.2 (23rd)
+* Internationalization Support (I18N) 2.4.6 (22nd)
+* Resource Resolver 1.4.2 (19th)
+* JCR Resource 2.7.2 (19th)
+* Servlets Resolver 2.4.2 (19th)
+* JCR Installer 3.1.18 (15th)
+* Resource Merger 1.3.0 (14th)
+* Scripting Core 2.0.36 (12th)
+* Slingstart Maven Plugin 1.4.2 (11th)
+* API 2.11.0 (8th)
+* Resource Resolver 1.4.0 (8th)
+* JCR Resource 2.7.0 (8th)
+* Servlets Resolver 2.4.0 (8th)
+* Testing OSGi Mock 1.7.2 (8th)
+* OSGi Mock 2.0.2 (8th)
+* JCR Mock 1.1.12 (8th)
+* Sling Mock 1.6.2 (8th)
+* ResourceResolver Mock 1.1.12 (8th)
+* Servlet Helpers 1.0.0 (8th)
+* Discovery Oak 1.2.6 (8th)
+* HApi 1.0.0 (5th) (2nd)
+* XSS Protection API 1.0.8 (2nd)
+* Scripting Sightly Engine 1.0.12 (2nd)
+* Discovery Commons 1.0.10 (1st)
+* Discovery Oak 1.2.4 (1st)
+* Testing Tools 1.0.12 (1st)
+
+## January 2016
+
+* Thread Support 3.2.6 (25th)
+* Models Impl 1.2.6 (23st)
+* Testing Utilities 2.0.24 (21st)
+* Commons Metrics 1.0.0 (15th)
+* Scripting Sightly Engine 1.0.10 (12th)
+* Scripting Groovy 1.0.2 (12th)
+* Slingstart Maven Plugin 1.4.0 (8th)
+* Commons OSGi 2.4.0 (8th)
+* Engine Implementation 2.4.6 (8th)
+* Scripting JavaScript 2.0.28 (8th)
+* JUnit Tests Teleporter 1.0.6 (3rd)
+* JUnit Core 1.0.16 (3rd)
+* Settings 1.3.8 (3rd)
+* Launchpad Base 2.6.10 (3rd)
+* Scripting JSP 2.1.8 (3rd)
+* Commons Threads 3.2.4 (3rd)
+* Discovery Standalone 1.0.2 (3rd)
+* Parent POM 26 (3rd
+
+## December 2015
+
+* Provisioning Model 1.4.2 (28th)
+* Commons Scheduler 2.4.14 (21st)
+* Servlets GET 2.1.14 (21st)
+* Scripting Java 2.0.14 (20th)
+* Models Impl 1.2.4 (14th)
+* Sling Testing OSGi Mock 2.0.0 (14th)
+* Commons Scheduler 2.4.12 (14th)
+* Launchpad Base 2.6.8 (11th)
+* Event 4.0.0 (1st)
+
+## November 2015
+
+* Discovery Commons 1.0.6 (30th)
+* Discovery Base 1.1.2 (30th)
+* Discovery Oak 1.2.0 (30th)
+* iscovery Impl 1.2.6 (30th)
+* Thread Support 3.2.2 ( 29th)
+* Background Servlets Engine 1.0.2 (23rd)
+* JUnit Core 1.0.14 (23rd)
+* JUnit Tests Teleporter 1.0.4 (23rd)
+* Security 1.0.18 (20th)
+* Discovery Commons 1.0.4 (16th)
+* Discovery Base 1.1.0 (16th)
+* Discovery Oak 1.1.0 (16th)
+* Discovery Impl 1.2.2 (16th)
+* Commons Testing 2.0.22 (12th)
+* Commons JSON 2.0.16 (12th)
+* Maven Sling Plugin 2.1.6 (12th)
+* Testing OSGi Mock 1.7.0 (9th)
+* Discovery Commons 1.0.2 (5th)
+* Discovery Base 1.0.2 (5th)
+* Discovery Oak 1.0.2 (5th)
+* Discovery Impl 1.2.0 (5th)
+* IDE Tooling 1.0.10 (9th)
+* Discovery Commons 1.0.0 (2nd)
+* Discovery Base 1.0.0 (2nd)
+* Discovery Oak 1.0.0 (2nd)
+
+## October 2015
+
+* Rewriter 1.1.2 (27th)
+* Launchpad Base 2.6.6 (26th)
+* Event 3.7.6 (26th)
+* Provisioning Model 1.4.0 (26th)
+* Maven Launchpad Plugin 2.3.4 (26th)
+* Archetype Parent version 4 (19th)
+* Bundle Archetype version 1.0.4 (19th)
+* JCRInstall Bundle Archetype 1.0.4 (19th)
+* Initial Content Archetype 1.0.4 (19th)
+* Servlet Archetype 1.0.4 (19th)
+* Slingstart Archetype 1.0.0 (19th)
+* Auth Core 1.3.12 (18th)
+* Sling 8 (16th)
+* Maven Plugin for Supporting Bundle Development 2.1.2 (15th)
+* Auth Forms 1.0.8 (13)
+* Scripting Sightly Engine 1.0.6 (12th)
+* Scripting Sightly Models Use Provider 1.0.0 (12th)
+* Scripting Sightly REPL 1.0.2 (12th)
+* Scripting JavaScript 2.0.26 (12th)
+* XSS Protection API 1.0.6 (12th)
+* Oak Repository Server 1.0.0 (12th)
+* Adapter Manager Implementation 2.1.6 (12th)
+* Jackrabbit UserManager Support 2.2.4 (12th)
+* Simple WebDAV Access to repositories 2.3.2 (12th)
+* OSGi LogService Implementation 1.0.6 (12th)
+* Engine Implementation 2.4.4 (12th)
+* JSON Library 2.0.12 (12th)
+* Testing OSGi Mock 1.6.0 (9th)
+* Sling Mock 1.6.0 (9th)
+* Sling Mock Jackrabbit 1.0.0 (9th)
+* Sling Mock Oak 1.0.0 (9th)
+* Eclipse IDE 1.0.8 (8th)
+* Servlets Resolver 2.3.8 (5th)
+* Parent POM 25 (5th)
+
+## September 2015
+
+* Discovery Impl 1.1.8 (30th)
+* Distributed Event Admin 1.0.4 (30th)
+* JUnit Core 1.0.12 (28th)
+* JUnit Tests Teleporter 1.0.2 (28th)
+* NoSQL Generic Resource Provider 1.0.0 (21th)
+* NoSQL Couchbase Client 1.0.0 (21th)
+* NoSQL Couchbase Resource Provider 1.0.0 (21th)
+* NoSQL MongoDB Resource Provider 1.0.0 (21th)
+* Testing ResourceResolver Mock 1.1.10 (15th)
+* Rewriter 1.1.0 (15th)
+* Models API 1.2.2 (15th)
+* Models Impl 1.2.2 (15th)
+* Testing Sling Mock 1.5.0 (10th)
+* JCR Mock 1.1.10 (10th)
+* Scripting Sightly JS Use Provider 1.0.10 (7th)
+* Scripting Sightly Engine 1.0.4 (7th)
+* Scripting JavaScript 2.0.24 (7th)
+* Slingstart Maven Plugin 1.3.6 (7th)
+* Launchpad Base 5.2.0-2.6.4 (6th)
+* Security 1.0.16 (4th)
+
+## August 2015
+
+* JCR Resource 2.5.6 (31st)
+* Slingstart Maven Plugin 1.3.4 (31st)
+* Security 1.0.14 (31st)
+* Security 1.0.12 (25th)
+* Testing OSGi Mock 1.5.0 (24th)
+* ResourceResolver Mock 1.1.8 (24th)
+* Web Console Security Provider 1.1.6 (21st)
+* Slingstart Maven Plugin 1.3.2 (20th)
+* JCR API 2.3.0 (17th)
+* JCR Base 2.3.0 (17th)
+* JCR Jackrabbit Server 2.3.0 (17th)
+* JCR Davex 1.3.0 (17th)
+* JCR Webdav 2.3.0 (17th)
+* Commons Scheduler 2.4.10 (14th)
+* i18n 2.4.4 (13th)
+* Scripting Core 2.0.34 (13th)
+* Scripting JavaScript 2.0.22 (13th)
+* Scripting Sightly JS Use Provider 1.0.8 (13th)
+* Commons Log 4.0.6 (11th)
+* Slingstart Maven Plugin 1.3.0 (7th)
+* Provisioning Model 1.3.0 (7th)
+* XSS Protection Bundle 1.0.4 (3rd)
+
+## July 2015
+
+* Scripting Core 2.0.32 (26th)
+* Event 3.7.4 (24th)
+* Distributed Event Admin 1.0.2 (24th)
+* Scripting API 2.1.8 (21st)
+* Scripting Core 2.0.30 (21st)
+* Scripting JavaScript 2.0.20 (21st)
+* Scripting Sightly JS Use Provider 1.0.6 (21st)
+* Resource Merger 1.2.10 (21st)
+* JCR Resource 2.5.4 (17th)
+* Servlets GET 2.1.12 (17th)
+* Event 3.7.2 (13th)
+* Authentication Service 1.3.10 (13th)
+* Scripting Thymeleaf 0.0.6 (10th)
+* Content Detection Support 1.0.2 (9th)
+* Parent POM 24 (6th)
+* Authentication Service 1.3.8 (6th)
+* Scripting JavaScript Support 2.0.18 (2nd)
+* Feature Flags 1.0.2 (1st)
+
+## June 2015
+
+* Event 3.7.0 (30th)
+* Models API 1.2.0 (27th)
+* Models Impl 1.2.0 (27th)
+* Testing Sling Mock 1.4.0 (27th)
+* OSGi Mock 1.4.0 (27th)
+* JCR Mock 1.1.8 (27th)
+* JCR Resource Resolver 2.5.2 (26th)
+* Parent 23 (25th)
+* Log Tracer 1.0.2 (22th)
+* Commons FileSystem ClassLoader 1.0.2 (19th)
+* Default POST Servlets 2.3.8 (15th)
+* Provisioning Model 1.2.0
+* Installer Core 3.6.6 (13th) (13th)
+* Commons Scheduler 2.4.8 (13th)
+* Slingstart Maven Plugin 1.2.0 (13th)
+* Background Servlets Engine 1.0.0 (2nd)
+
+## May 2015
+
+* Testing Sling Mock 1.3.0 (26th)
+* OSGi Mock 1.3.0 (26th)
+* JCR Mock 1.1.6 (26th)
+* ResourceResolver Mock 1.1.6 (26th)
+* Logging Mock 1.0.0 (26th)
+* Commons OSGi 2.3.0 (26th)
+* Installer Core 3.6.4 (2nd)
+
+## April 2015
+
+* Health Check Core 1.2.2 (30th)
+* Launchpad Base 5.0.0-2.6.0 (30th)
+* Discovery Impl 1.1.2 (28th)
+* Testing Tools 1.0.10 (24th)
+* i18n 2.4.2 (23rd)
+* Slingstart Maven Plugin 1.1.0 (23rd)
+* Scripting JavaScript Support 2.0.16 (20th)
+* Engine Implementation 2.4.2 (20th)
+* File Installer 1.1.0 (20th)
+* Resource Inventory 1.0.4 (20th)
+* Scripting Sightly JS Provider 1.0.4 (16th)
+* Scripting Sightly Testing Content 1.0.4 (16th)
+* Scripting Sightly Testing 1.0.4 (16th)
+* JCR Installer 3.1.16 (13th)
+* Commons Testing 2.0.18 (13th)
+* Security 1.0.10 (April 8th)
+* Scripting Sightly 1.0.2 (7th)
+* Scripting Sightly Testing Content 1.0.2 (7th)
+* Scripting Sightly Testing 1.0.2 (7th)
+* Event 3.6.0 (7th)
+* Commons Log 4.0.2 (7th)
+* Commons Log Service 1.0.4 (7th)
+* Performance Test Utilities 1.0.2 (2nd)
+
+## March 2015
+
+* Scripting Sightly 1.0.0 (30th)
+* Scripting Sightly JavaScript Use Provider 1.0.0 (30th)
+* Scripting Sightly REPL 1.0.0 (30th)
+* Scripting Sightly Testing Content 1.0.0 (30th)
+* XSS Protection Bundle 1.0.2 (30th)
+* Resource Resolver 1.2.4 (24th)
+* XSS Protection Bundle 1.0.0 (20th)
+* JCR Installer 3.1.14 (16th)
+* Resource Resolver 1.2.2 (16th)
+* Service User Mapper 1.2.0 (16th)
+* Launchpad Base 4.6.1-2.5.8 (12th)
+* Event 3.5.4 (12th)
+* Settings 1.3.6 (12th)
+* Resource Merger 1.2.8 (12th)
+* Slingstart Maven Plugin 1.0.4 (12th)
+* Provisioning Model 1.1.0 (12th)
+* Query 3.0.0 (11th)
+* JCR Resource 2.5.0 (5th)
+* Resource Resolver 1.2.0 (5th)
+* Commons Scheduler 2.4.6 (4th)
+* IDE Tooling 1.0.6 (2nd)
+* Service User Mapper 1.1.0 (2nd)
+* Health Check Core 1.2.0 (2nd)
+* Health Check Web Console 1.1.2 (2nd)
+
+## February 2015
+
+* URL Rewriter 0.0.2 (27th)
+* Security 1.0.8 (26th)
+* Testing Sling Mock 1.2.0 (26th)
+* OSGi Mock 1.2.0 (26th)
+* JCR Mock 1.1.4 (26th)
+* ResourceResolver Mock 1.1.4 (26th)
+* API 2.9.0 (February 24th)
+* Tooling Support Install 1.0.2 (23rd)
+* Engine Implementation 2.4.0 (19th)
+* Auth Core 1.3.6 (16th)
+* Resource Resolver 1.1.14 (16th)
+* Eventing 3.5.2 (16th)
+* Resource Merger 1.2.6 (16th)
+* Installer Factory Configuration 1.1.2 (16th)
+* Resource Resolver 1.1.12 (2nd)
+
+## January 2015
+
+* Testing JCR Mock 1.1.2 (28th)
+* ResourceResolver Mock 1.1.2 (28th)
+* Sling Mock 1.1.2 (28th)
+* Sling Mock Jackrabbit 0.1.2 (28th)
+* JCR Resource 2.4.4 (26th)
+* Launchpad Base 4.6.0-2.5.6 (26th)
+* JCR Resource 2.4.2 (23rd)
+* Resource Resolver 1.1.10  (19th)
+* DataSource 1.0.0 (19th)
+* Launchpad Base 4.6.0-2.5.4 (19th)
+* Commons JSON 2.0.10 (17th)
+* Installer Core 3.6.2 (16th)
+* i18n 2.3.2 (16th)
+* JCR Resource Security 1.0.2 (13th)
+* Installer Core 3.6.0 (12th)
+* Installer Factory Configuration 1.1.0 (12th)
+* Launchpad Installer 1.2.2 (12th)
+* Eventing 3.5.0 (10th)
+* JCR Resource Security 1.0.0 (9th)
+* Installer Factory Subsystems 1.0.0 (9th)
+
+## December 2014
+
+* Release JUnit Core 1.0.10 (15th)
+* JUnit Scriptable Tests Provider 1.0.10 (15th)
+* JUnit Remote Tests Runners 1.0.10 (15th)
+* Testing Sling Mock 1.1.0 (15th)
+* OSGi Mock 1.1.0 (15th)
+* JCR Mock 1.1.0 (15th)
+* ResourceResolver Mock 1.1.0 (15th)
+* Adapter Manager 2.1.4 (15th)
+* Auth Core 1.3.4 (2nd)
+
+## November 2014
+
+* Resource Merger 1.2.0 (29th)
+* Resource Resolver 1.1.8 (27th)
+* Servlets Resolver 2.3.6 (18th)
+* Engine 2.3.10 (18th)
+* Servlets Resolver 2.3.4 (14th)
+* Eventing 3.4.4 (7th)
+* Scripting JSP 2.1.6 (6th)
+* Slingstart Maven Plugin 1.0.2 (5th)
+* Event 3.4.2 (1st)
+
+## October 2014
+
+* Engine 2.3.8 (27th)
+* Provisioning Model 1.0.0 (27th)
+* Slingstart Maven Plugin 1.0.0 (27th)
+* JCR Resource Resolver 2.3.12 (26th)
+* Eventing 3.4.0 (24th)
+* Distributed Event Admin 1.0.0 (24th)
+* JCR Resource Resolver 2.3.10 (22nd)
+* Auth Core 1.3.2 (21st)
+* Resource Resolver Mock 1.0.0 (21st)
+* JCR Mock 1.0.0 (21st)
+* OSGi Mock 1.0.0 (21st)
+* Sling Mock 1.0.0 (21st)
+* Sling Mock Jackrabbit 0.1.0 (21st)
+* IDE Tooling 1.0.4 (18th)
+* Settings 1.3.4 (10th)
+* Discovery API 1.0.2 (10th)
+* Discovery Impl 1.0.12 (10th)
+* Resource Resolver 1.1.6 (4th)
+* Superimposing Resource Provider 0.2.0 (3rd)
+* Sling 7 (3rd)
+
+## September 2014
+
+* Scripting Java 2.0.12 (30th)
+* Resource Resolver Mock 0.3.0 (29th)
+* Resource Resolver 1.1.4 (26th)
+* JSP Taglib 2.2.4 (25th)
+* DavEx Access to repositories 1.2.2 (22nd)
+* Adapter Manager Implementation 2.1.2 (22nd)
+* Scripting Core implementation 2.0.28 (22nd)
+* JCR ContentLoader 2.1.0 (21st)
+* Web Console Security Provider 1.1.4 (21st)
+* Resource Access Security 1.0.0 (20th)
+* Auth Core 1.3.0 (20th)
+* Engine 2.3.6 (19th)
+* JCR ClassLoader 3.2.2 (19th)
+* JCR Jackrabbit Access Manager 2.1.2 (19th)
+* JCR Jackrabbit Server 2.2.0 (19th)
+* JCR Jackrabbit User Manager 2.2.2 (19th)
+* JCR Registration 1.0.2 (19th)
+* JCR Web Console 1.0.2 (19th)
+* Scripting Thymeleaf 0.0.4 (17th)
+* Resource Resolver 1.1.2 (16th)
+* Maven Launchpad Plugin 2.3.2 (15th)
+* Filesystem Resource Provider 1.1.4 (12th)
+* Launchpad Content 2.0.8 (12th)
+* JSP Tag Library 2.2.2 (12th)
+* Scripting Groovy Support 1.0.0 (12th)
+* Auth Core 1.2.0 (8th)
+* Models API 1.1.0 (5th)
+* Models Impl 1.1.0 (5th)
+* Health Check Annotations 1.0.2 (5th)
+* Health Check Core 1.1.2 (5th)
+* Health Check JUnit Bridge 1.0.2 (5th)
+* Health Check Samples 1.0.6 (5th)
+* Default GET Servlets 2.1.10 (1st)
+* Explorer 1.0.4 (1st)
+
+## August 2014
+
+* API 2.8.0 (31st)
+* JCR Resource 2.3.8 (31st)
+* i18n 2.2.10 (31st)
+* Installer Core 3.5.4 (31st)
+* JCR Installer 3.1.8 (31st)
+* File Installer 1.0.4 (31st)
+* JSON Library 2.0.8 (28th)
+* Default POST Servlets 2.3.6 (28th)
+* Eventing 3.3.14 (25th)
+* Commons Mime 2.1.8 (25th)
+* Commons Scheduler 2.4.4 (25th)
+* Commons Mime 2.1.6 (19th)
+* Commons OSGi 2.2.2 (19th)
+* Tenant 1.0.2 (18th)
+* Query 2.0.0 (11th)
+* Auth Core 1.1.8 (11th)
+* Auth Selector 1.0.6 (11th)
+* Form Based Authentication 1.0.6 (11th)
+* OpenID Authentication 1.0.4 (11th)
+* Eventing 3.3.12 (8st)
+* Parent 20 (1st)
+
+## July 2014
+
+* Discovery Impl 1.0.10 (29th)
+* Engine 2.3.4 (26th)
+* Launchpad Base 4.4.1-2.5.2 (26th)
+* Testing Tools 1.0.8 (22nd)
+* Compat Servlets 1.0.2 (14th)
+* Service User Mapper 1.0.4 (14th)
+* Settings 1.3.2 (26th)
+* Scripting JSP 2.1.4 (26th)
+* Scripting Java 2.0.10 (13th)
+* Authentication XING API 0.0.2 (11th)
+* Authentication XING Login 0.0.2 (11th)
+* Authentication XING OAuth 0.0.2 (11th)
+* Scripting Thymeleaf 0.0.2 (11th)
+* Models API 1.0.2 (2nd)
+* Models Impl 1.0.6 (2nd)
+* Installer Core 3.5.2 (2nd)
+* Installer Configuration Factory 1.0.14 (2nd)
+* Eclipse IDE 1.0.0 (1st)
+
+## June 2014
+
+* Scripting JavaScript Support 2.0.14 (23rd)
+* SLF4J MDC Filter 1.0.0 (9th)
+* Classloader Leak Detector 1.0.0 (9th)
+* Bundle JCR Install Archetype 1.0.2 (4th)
+* Tooling Support Install 1.0.0 (4th)
+* Bundle Archetype 1.0.2 (4th)
+* Servlet Archetype 1.0.2 (4th)
+* Service User Mapper 1.0.2 (2nd)
+
+## May 2014
+
+* JCR ContentLoader 2.1.8 (23th)
+* Commons Compiler 2.2.0 (20th)
+* Scripting JSP 2.1.0 (20th)
+* Archetype Parent 1 (14th)
+* Models Impl 1.0.4 (7th)
+
+## April 2014
+
+* Discovery Impl 1.0.8 (30th)
+* Resource Inventory 1.0.2 (30th)
+* Eventing 3.3.10 (30th)
+* Commons ClassLoader 1.3.2 (17th)
+* Resource Resolver 1.1.0 (4th)
+* Featureflags 1.0.0 (4th)
+* Resource-Based Discovery Service (discovery.impl) 1.0.6 (4th)
+
+## March 2014
+
+* Servlets Resolver 2.3.2 (31st)
+* Servlets Get 2.1.8 (31st)
+* Installer Configuration Factory 1.0.12 (31st)
+* Parent POM 19 (31st)
+* API 2.7.0 (24th)
+* JCR Resource 2.3.6 (24th)
+* JMX Resource Provider 1.0.2 (24th)
+* Resource Merger 1.1.2 (24th)
+* Model Implementation 1.0.2 (18th)
+* JCR Resource 2.3.4 (17th)
+* Engine 2.3.2 (16th)
+* i18n 2.2.8 (8th)
+* JCR Resource 2.3.2 (8th)
+* Discovery Impl 1.0.4 (8th)
+* JCR Webdav 2.2.2 (8th)
+* Resource Collection 1.0.0 (8th)
+* Resource Inventory 1.0.0 (8th)
+* JMX Provider 1.0.0 (8th)
+* Resource Merger 1.1.0 (8th)
+* Commons Log 4.0.0 (7th)
+* Security 1.0.0 (7th)
+* JCR Registration 1.0.0 (7th)
+* Bundle Resource 2.2.20 (7th)
+* JCR Base 2.2.2 (7th)
+* Eventing 3.3.6 (7th)
+* Scripting API 2.1.6 (7th)
+* Scripting Core 2.0.26 (7th)
+* Servlets Get 2.1.6 (7th)
+* Servlets Post 2.3.4 (7th)
+* Maven Launchpad Plugin 2.3.0 (6th)
+* API 2.6.0 (3rd)
+* Engine 2.3.0 (3rd)
+
+## February 2014
+
+* Servlets Resolver 2.3.0 (24th)
+* Resource Merger 1.0.0 (24th)
+* JCR API 2.2.0 (17th)
+* JCR Base 2.2.0 (17th)
+* JCR Resource 2.3.0 (17th)
+* Service User Mapper 1.0.0 (6th)
+* Resource Resolver Mock 0.2.0 (6th)
+
+## January 2014
+
+* Health Check Core 1.1.0 (31th)
+* Health Check Webconsole 1.1.0 (31th)
+* Auth Core 1.1.6 (31th)
+* Pax Exam Utilities 1.0.2 (28th)
+* API 2.5.0 (24th)
+* Eventing 3.3.4 (24th)
+* Installer Core 3.5.0 (19th)
+* Eventing 3.3.2 (19th)
+
+## December 2013
+
+* Web Console Security Provider 1.1.2 (17th)
+* Maven JSPC Plugin 2.0.8 (14th)
+* Resource-Based Discovery Service 1.0.2 (3rd)
+
+## November 2013
+
+* Testing Utilities 2.0.16 (November 27th)
+
+## October 2013
+
+* Web Console Security Provider 1.1.0 (28th)
+* Event 3.3.0 (24th)
+* Commons Scheduler 2.4.2 (24th)
+* Commons Threads 3.2.0 (24th)
+* Health Check Core 1.0.6 (24th)
+* Health Check JMX 1.0.6 (24th)
+* JMX Resource Provider 0.6.0 (24th)
+* Engine 2.2.10 (October 12th)
+* Auth Core 1.1.4 (7th)
+* Commons Scheduler 2.4.0 (7th)
+* Resource Inventory 0.5.0 (7th)
+* JMX Resource Provider 0.5.0 (7th)
+
+## September 2013
+
+* org.apache.sling.hc.core-1.0.4 (30th)
+* org.apache.sling.hc.it-1.0.4 (30th)
+* org.apache.sling.hc.jmx-1.0.4 (30th)
+* org.apache.sling.hc.samples-1.0.4 (30th)
+* org.apache.sling.hc.support-1.0.4 (30th)
+* org.apache.sling.hc.webconsole-1.0.4 (30th)
+* org.apache.sling.junit.healthcheck-1.0.6 (30th)
+* Commons Log 3.0.2 (12th)
+
+## August 2013
+
+* Discovery Impl 1.0.0 (12th)
+* Discovery Standalone 1.0.0 (12th)
+* Discovery Support 1.0.0 (12th)
+* Settings 1.3.0 (12th)
+* Event 3.2.0 (12th)
+* JCR Jackrabbit Server 2.1.2 (8th)
+* Scripting JSP Taglib 2.2.0 (8th)
+
+## July 2013
+
+* JCR DavEx 1.2.0 (31st)
+* JCR Webdav 2.2.0 (31st)
+* Servlets Post 2.3.2 (18th)
+* I18n 2.2.6 (18th)
+* Commons FileSystem ClassLoader 1.0.0 (18th)
+* JCR ClassLoader 3.2.0 (18th)
+* Parent POM 17 (18th)
+
+## May 2013
+
+* Form Based Authentication Handler 1.0.4 (27th)
+* Scripting JSP 2.0.28 (16th)
+* Servlets Post 2.3.0 (10th)
+* JCR Resource 2.2.8 (10th)
+* API 2.4.2 (3rd)
+* Parent POM 16 (3rd)
+
+## April 2013
+
+* Tenant 1.0.0 (26th)
+* Security 1.0.4 (26th)
+* javax.activation 0.1.0 (26th)
+* API 2.4.0 (18th)
+* Bundle Resource Provider 2.1.2 (18th)
+* File System Resource Provider 1.1.2 (18th)
+* JCR Resource 2.2.6 (18th)
+* Resource Resolver 1.0.6 (18th)
+* Servlets Resolver 2.2.4 (18th)
+* Engine 2.2.8 (18th)
+* Auth Core 1.1.2 (18th)
+
+## March 2013
+
+* Launchpad Base 2.5.0 (4th)
+* Script Console 1.0.0 (4th)
+
+## February 2013
+
+* JCR Classloader 3.1.2 (18th)
+* Commons Testing 2.0.14 (18th)
+* JUnit Core 1.0.8 (18th)
+* JUnit Remote 1.0.8 (18th)
+* JUnit Scriptable 1.0.8 (18th)
+* Testing Tools 1.0.6 (18th)
+* Installer Core 3.4.6 (18th)
+* Installer Configuration Factory 1.0.10 (18th)
+* JCR Instaler 3.1.6 (18th)
+* Parent POM 15 (18th)
+* Fragment Extension XML 1.0.2 (18th)
+* Fragment Extension WS 1.0.2 (18th)
+* Fragment Extension Activation 1.0.2  (18th)
+* Resource Resolver 1.0.4 (14th )
+* JCR Resource 2.2.4 (14th)
+
+## December 2012
+
+* Installer Core 3.4.4 (20th)
+* JCR Resource 2.2.2 (20th)
+* Resource Resolver 1.0.2 (20th)
+* Security 1.0.2 (20th)
+* Parent POM 14 (20th)
+* Servlet Resolver 2.2.2 (10th)
+
+## November 2012
+
+* Settings 1.2.2 (30th)
+* Auth Core 1.1.0 (30th)
+* Commons Logservice 1.0.2 (30th)
+* Installer Core 3.4.2 (30th)
+* Scripting JSP 2.0.26 (30th)
+* Commons Compiler 2.1.0 (30th)
+* JCR Compiler 2.1.0 (30th)
+* I18n 2.2.4 (30th)
+* JCR Classloader 3.1.10 (30th)
+* JCR Webdav 2.1.2 (30th)
+* JCR Davex 1.1.0 (30th)
+* Maven Launchpad Plugin 2.2.0 (19th)
+* Commons OSGi 2.2.0 (19th)
+* Launchpad Installer 1.2.0 (19th)
+* Rewriter 1.0.4 (19th)
+* Settings 1.2.0 (19th)
+* API 2.3.0 (15th)
+* Bundle Resource Provider 2.1.0 (15th)
+* File System Resource Provider 1.1.0 (15th)
+* JCR Resource 2.2.0 (15th)
+* Resource Resolver 1.0.0 (15th)
+* Servlets Get 2.1.4 (15th)
+* Servlets Post 2.2.0 (15th)
+* Servlets Resolver 2.2.0 (15th)
+* Adapter 2.1.0 (15th)
+* Commons Testing 2.0.12 (15th)
+
+## October 2012
+
+* JSP Taglib 2.1.8 (29th)
+* Installer Core 3.4.0 (29th)
+* Installer API 1.0.0 (29th)
+* Installer Console 1.0.0 (29th)
+* JCR Wrapper 2.0.0 (29th)
+
+## August 2012
+
+* Installer Core 3.3.8 (19th)
+* Launchpad Installer 1.1.4 (19th)
+* Maven Launchpad Plugin 2.1.2 (19th)
+* Scripting JST 2.0.6 (17th)
+
+## July 2012
+
+* Adapter 2.0.16 (9th)
+* JCR ContentLoader 2.1.6 (9th)
+* Parent POM 13 (9th)
+
+## June 2012
+* Commons Compiler 2.0.6 (28th)
+* Adapter 2.0.14 (28th)
+* JCR ClassLoader 3.1.8 (28th)
+* JCR Compiler 2.0.4 (28th)
+* Scripting Core 2.0.24 (28th)
+* Scripting Java 2.0.4 (28th)
+* Scripting JSP 2.0.24 (28th)
+* POST Servlets 2.1.2 (28th)
+
+## May 2012
+
+* Installer Factory Configuration 1.0.8 (26th)
+* Engine 2.2.6 (26th)
+* i18n 2.2.2 (26th)
+* Scripting Core 2.0.22 (26th)
+* Commons ClassLoader 1.3.0 (18th)
+* Commons Compiler 2.0.4 (18th)
+* Eventing 3.1.4 (18th)
+* Installer Core 3.3.6 (18th)
+* JCR Installer 3.1.4 (18th)
+* JCR ClassLoader 3.1.6 (18th)
+* JCR Resource 2.1.0 (18th)
+* Launchpad Installer 1.1.2 (18th)
+* Scripting Java 2.0.4 (18th)
+* Scripting JSP 2.0.22 (18th)
+
+## February 2012
+
+* Commons Testing 2.0.10 (7th)
+* Commons Scheduler 2.3.4 (7th)
+* Commons Log 3.0.0 (7th)
+* Commons Log Service 1.0.0 (7th)
+* Adapter 2.0.12 (7th)
+* Installer Core 3.3.4 (7th)
+* Launchpad API 1.1.0 (7th)
+* Launchpad Installer 1.1.0 (7th)
+* Maven JSPC Plugin 2.0.6 (7th)
+
+## January 2012
+
+* API 2.2.4 (30th)
+* Adapter 2.0.10 (30th)
+* Scripting JSP Taglib 2.1.6 (30th)
+* Rewriter 1.0.2 (30th)
+* JCR ContentLoader 2.1.4 (30th)
+* JCR Base 2.1.2 (30th)
+* Servlet Resolver 2.1.2 (30th)
+* Security 1.0.0 (30th)
+* Scripting API 2.1.4 (16th)
+* Scripting Core 2.0.20 (16th)
+* i18n 2.2.0 (16th)
+* Installer Core 3.3.2 (16th)
+* Scripting Java 2.0.2 (16th)
+* Scripting JSP 2.0.20 (16th)
+* Adapter Annotations 1.0.0 (14th)
+* Maven Sling Plugin 2.1.0 (14th)
+* Settings 1.1.0 (6th)
+* Commons ClassLoader 1.2.4 (6th)
+* Commons Scheduler 2.3.2 (6th)
+* Installer Core 3.3.0 (6th)
+* Installer Configuration Factory 1.0.4 (6th)
+* Launchpad Installer 1.0.6 (6th)
+* JCR Installer 3.1.2 (6th)
+* Thread Dumper 0.2.2 (6th)
+
+## November 2011
+
+* Jackrabbit User Manager 2.2.0 (15th)
+
+## October 2011
+
+* Maven Sling Plugin 2.0.6 (21st)
+
+## September 2011
+
+* Maven Launchpad Plugin 2.1.0 (9th)
+
+## August 2011
+
+* Resource Bundle 1.0.0 (16th)
+* Parent POM 12 (16th)
+* API 2.2.2 (16th)
+* Commons Scheduler 2.3.0 (16th)
+* Commons OSGi 2.1.0 (16th)
+* Scripting Core 2.0.18 (16th)
+* Installer Core 3.2.2 (16th)
+* Installer Configuration Factory 1.0.2 (16th)
+* Launchpad Installer 1.0.4 (16th)
+* File Installer 1.0.2 (16th)
+* Scripting JSP Support 2.0.18 (15th)
+* Parent POM 11 (8th)
+
+## July 2011
+
+* Internationalization 2.1.2 (15th)
+* Event 3.1.0 (13th)
+* OSGi Installer 3.2.0 (13th)
+* JCR Installer 3.1.0 (13th)
+* Installer Configuration Factory 1.0.0 (13th)
+* Launchpad Installer 1.0.2 (13th)
+
+## June 2011
+
+* Engine 2.2.4 (22nd)
+
+## May 2011
+
+* Launchpad Standalone Archetype 1.0.0 (13th)
+* Launchpad Webapp Archetype 1.0.0 (13th)
+* Scripting JSP Support 2.0.16(3rd)
+* JSP Taglib 2.1.2 (3rd)
+
+## April 2011
+
+* Test Tools 1.0.2 (26th)
+* JUnit Core 1.0.6 (26th)
+* JUnit Remote Tests Runners 1.0.6 (26th)
+* JUnit Scriptable Tests Provider 1.0.6 (26th)
+* Sample Integration Tests 1.0.6 (26th)
+* Sample Server-Side Tests 1.0.6 (26th)
+* Failing Server-Side Tests 1.0.6 (26th)
+* I18N 2.1.0 (12th)
+
+## March 2011
+
+* Sling 6 (28th)
+* Launchpad Content 2.0.6 (28th)
+* Launchpad Integration Tests 1.0.0 (04th)
+* Launchpad Testing Services 2.0.8 (04th)
+* Launchpad Testing Services WAR 2.0.8 (04th)
+
+## February 2011
+
+* Javascript 2.0.12 (26th)
+* Explorer 1.0.2 (24th)
+* JCR Resource 2.0.10 (24th)
+* Engine 2.2.2 (24th)
+* Installer IT Testing 3.1.2 (24th)
+* Launchpad API 1.0.0 (20th)
+* Launchpad Installer 1.0.0 (20th)
+* Launchpad Base 2.3.0 (20th)
+* Maven Launchpad Plugin 2.0.10 (20th)
+* Commons Testing 2.0.8 (20th)
+* Servlets Get 2.1.2 (18th)
+* Installer Core 3.1.2 (4th)
+* JCR Installer 3.0.4 (4th)
+* Event 3.0.2 (4th)
+
+## January 2011
+
+* Scripting Core 2.0.16 (29th)
+* JCR Resource 2.0.8 (28th)
+* Engine 2.2.0 (28th)
+* Bundle Resource Provider 2.0.6 (28th)
+* File Resource Provider 1.0.2 (28th)
+* Auth Core 1.0.6 (28th)
+* Auth Selector 1.0.4 (28th)
+* Commons Compiler 2.0.2 (21st)
+* JCR Compiler 2.0.2 (21st)
+* Commons Log 2.1.2 (21st)
+* Event 3.0.0 (21st)
+* Scripting JSP 2.0.14 (21st)
+* Installer Core 3.1.0 (21st)
+* JCR Installer 3.0.2 (21st)
+
+## December 2010
+
+* Maven Launchpad Plugin 2.0.8 (20th)
+* Commons Compiler 2.0.0 (20th)
+* i18n 2.0.4 (20th)
+* Commons Json 2.0.6 (20th)
+* Commons Log 2.1.0 (20th)
+* Scripting Java 2.0.0 (20th)
+* Scripting JST 2.0.4 (20th)
+* Scripting API 2.1.2 (20th)
+* Scripting JSP 2.0.12 (20th)
+* Scripting Javascript 2.0.10 (20th)
+* JCR Compiler 2.0.0 (20th)
+* Auth Core 1.0.4 (20th)
+* Auth Selector 1.0.2 (20th)
+* Auth Form 1.0.2 (20th)
+* Auth OpenId 1.0.2 (20th)
+* JCR ContentLoader 2.1.2 (20th)
+* API 2.20 (13th)
+* Adapter 2.0.8 (13th)
+* Commons ClassLoader 1.2.2 (13th)
+* JCR ClassLoader 3.1.4 (13th)
+* Parent POM 10 (13th)
+
+## November 2010
+
+* JCR Web Console Plugin 1.0.0 (16th)
+* JCR Access Manager 2.1.0
+* JCR User Manager 2.1.0 (8th) (8th)
+* JCR WebDAV support 2.1.0 (8th)
+* JCR DavEX support 1.0.0 (8th)
+* Explorer 1.0.0 (1st)
+
+## October 2010
+
+* Scripting Core 2.0.14 (25th)
+* Commons Threads 3.1.0 (15th)
+* Event 2.4.2 (15th)
+* I18N 2.0.2 (15th)
+* Rewriter 1.0.0 (15th)
+* Settings 1.0.2 (15th)
+
+## September 2010
+
+* Installer Core 3.0.0 (24th)
+* Installer File Provider 1.0.0 (24th)
+* Installer JCR Provider 3.0.0 (24th)
+* Commons Testing 2.0.6 (20th)
+* JCR API 2.1.0 (10th)
+* JCR Base 2.1.0 (10th)
+* JCR Content Loader 2.1.0 (10th)
+* Jackrabbit Server 2.1.0 (10th)
+* Commons Threads 3.0.2 (06th)
+* Event 2.4.0 (06th)
+
+## August 2010
+
+* Commons ClassLoader 1.2.0 (30th)
+* JCR ClassLoader 3.1.2 (30th)
+* Web Console Branding 1.0.0 (25th)
+* Web Console Security Provider 1.0.0 (25th)
+* API 2.1.0 (21st)
+
+## July 2010
+
+* GWT Integration 3.0.0 (30th)
+
+## April 2010
+
+* Commons OSGi 2.0.6 (27th)
+* Launchpad Base 2.2.0 (27th)
+* Maven Launchpad Plugin 2.0.6 (27th)
+
+## March 2010
+
+* Event 2.3.0 (1st)
+* Scripting Core 2.1.0 (1st)
+* Apache Commons MIME 2.1.4 (1st)
+* FileResource Provider 1.0.0 (1st)
+
+## February 2010
+
+* Sample Path Based Resource Type Provider 2.0.4 (22nd)
+* Event 2.2.0 (19th)
+* Scripting API 2.1.0 (19th)
+* Thread Dumper 0.2.0 (19th)
+* JCR WebDav 2.0.8 (17th)
+* JCR ContentLoader 2.0.6 (17th)
+* JCR UserManager 2.0.4 (17th)
+* JCR Server 2.0.6 (17th)
+* JCR AccessManager 2.0.4 (17th)
+* JCR Base 2.0.6 (17th)
+* Commons ClassLoader 1.1.4 (8th)
+* JCR ClassLoader 3.1.0 (8th)
+
+## January 2010
+
+* JCR API 2.0.6 (29th)
+
+## December 2009
+
+* Commons ClassLoader 1.1.2 (21st)
+* Commons Scheduler 2.2.0 (21st)
+* Commons Threads 3.0.0 (21st)
+* Event 2.1.0 (21st)
+* Servlets Get 2.0.8 (21st)
+* Commons Mime 2.1.2 (15th)
+* Commons HTML 1.0.0 (2nd)
+* Commons Compiler 1.0.0 (2nd)
+* JCR Compiler 1.0.0 (2nd)
+* JCR Prefs 1.0.0 (2nd)
+* Scripting Java 1.0.0 (2nd)
+
+## November 2009
+
+* Parent POM 8 (28th)
+* Launchpad Base 2.1.0 (28th)
+* Commons ClassLoader 1.1.0 (28th)
+* JCR ClassLoader 3.0.0 (28th)
+* Scripting Core 2.0.8 (28th)
+* Scripting JSP 2.0.8 (28th)
+* Scripting JSP Taglib 2.0.6 (28th)
+* Scripting JavaScript 2.0.6 (28th)
+
+## October 2009
+
+* Engine 2.0.6 (13th)
+* Adapter 2.0.4 (13th)
+* JCR Resource 2.0.6 (13th)
+* Commons ClassLoader 1.0.0 (13th)
+* Event 2.0.6 (13th)
+* JCR ClassLoader 2.0.6 (13th)
+* Scripting Core 2.0.6 (13th)
+* Servlets Resolver 2.0.8 (13th)
+* API 2.0.8 (2nd)
+* Commons HTML 0.9.0 (2nd)
+* Commons ClassLoader 0.9.0 (2nd)
+* Commons Scheduler 2.1.0 (2nd)
+* Servlets Get 2.0.6 (2nd)
+
+## August 2009
+
+* API 2.0.6 (17th)
+* JCR API 2.0.4 (17th)
+* Commons LogService 2.0.6 (5th)
+


[sling-org-apache-sling-committer-cli] 16/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 9da1f2c23f6265b62a3fbe68051d0cedf0a4d43c
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Mar 28 17:48:08 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * no need to customise the SSLContext
---
 .../cli/impl/release/UpdateReporterCommand.java    | 23 ++--------------------
 1 file changed, 2 insertions(+), 21 deletions(-)

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 4c0c127..0a33043 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
@@ -20,17 +20,11 @@ package org.apache.sling.cli.impl.release;
 
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLSocket;
-
 import org.apache.http.NameValuePair;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
@@ -38,8 +32,6 @@ import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.ssl.DefaultHostnameVerifier;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
@@ -79,19 +71,8 @@ public class UpdateReporterCommand implements Command {
         try {
             StagingRepository repository = repoFinder.find(Integer.parseInt(target));
             Release release = Release.fromString(repository.getDescription());
-            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
-            sslContext.init(null, null, null);
-            SSLContext.setDefault(sslContext);
-            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
-                    sslContext,
-                    new String[] {"TLSv1.2"},
-                    new String[] {
-                            "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
-                    },
-                    new DefaultHostnameVerifier()
-            );
             try (CloseableHttpClient client =
-                         HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).setSSLSocketFactory(sslConnectionSocketFactory).build()) {
+                         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<>();
@@ -108,7 +89,7 @@ public class UpdateReporterCommand implements Command {
                     }
                 }
             }
-        } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
+        } catch (IOException e) {
             LOGGER.error(String.format("Unable to update reporter service; passed command: %s.", target), e);
         }
 


[sling-org-apache-sling-committer-cli] 19/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit d9ae57105690c4ddaf25301bbd07d816f6a0defa
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Fri Mar 29 15:23:50 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * finished Mailer implementation
---
 Dockerfile                                         |  2 +-
 src/main/features/app.json                         |  5 +++-
 .../org/apache/sling/cli/impl/mail/Mailer.java     | 30 ++++++++++++----------
 3 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index ca438e9..48d4d4e 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,7 +11,7 @@
 # ----------------------------------------------------------------------------------------
 FROM azul/zulu-openjdk-alpine:11 as builder
 MAINTAINER dev@sling.apache.org
-RUN jlink --add-modules java.logging,java.naming,java.xml,java.security.jgss,java.sql,jdk.crypto.ec \
+RUN jlink --add-modules java.logging,java.naming,java.xml,java.security.jgss,java.sql,jdk.crypto.ec,java.desktop \
           --output /opt/jre --strip-debug --compress=2 --no-header-files --no-man-pages
 
 FROM alpine
diff --git a/src/main/features/app.json b/src/main/features/app.json
index 5daa106..d8a2bb2 100644
--- a/src/main/features/app.json
+++ b/src/main/features/app.json
@@ -66,7 +66,10 @@
             "start-level": "3"
         },
         {
-            "id":"javax.mail:mail:1.5.0-b01"
+            "id": "javax.mail:mail:1.5.0-b01"
+        },
+        {
+            "id": "org.apache.sling:org.apache.sling.javax.activation:0.1.0"
         }
     ]
 }
diff --git a/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java b/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java
index e4bd604..0c0a4e4 100644
--- a/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java
+++ b/src/main/java/org/apache/sling/cli/impl/mail/Mailer.java
@@ -18,32 +18,38 @@
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 package org.apache.sling.cli.impl.mail;
 
+import java.io.UnsupportedEncodingException;
 import java.nio.charset.StandardCharsets;
 import java.util.Properties;
 
-import javax.mail.Authenticator;
+import javax.mail.Address;
 import javax.mail.Message;
 import javax.mail.MessagingException;
-import javax.mail.PasswordAuthentication;
 import javax.mail.Session;
 import javax.mail.Transport;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 
+import org.apache.sling.cli.impl.Credentials;
 import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.people.Member;
 import org.apache.sling.cli.impl.people.MembersFinder;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @Component(
         service = Mailer.class
 )
 public class Mailer {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(Mailer.class);
+
     private static final Properties SMTP_PROPERTIES = new Properties() {{
         put("mail.smtp.host", "mail-relay.apache.org");
+        put("mail.smtp.port", "465");
         put("mail.smtp.auth", "true");
-        put("mail.smtp.socketFactory.port", 465);
         put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
         put("mail.smtp.socketFactory.fallback", "false");
     }};
@@ -56,22 +62,18 @@ public class Mailer {
 
     public void send(String to, String subject, String body) {
         Properties properties = new Properties(SMTP_PROPERTIES);
-        Session session = Session.getDefaultInstance(properties, new Authenticator() {
-            @Override
-            protected PasswordAuthentication getPasswordAuthentication() {
-                return new PasswordAuthentication(credentialsService.getCredentials().getUsername(),
-                        credentialsService.getCredentials().getPassword());
-            }
-        });
+        Session session = Session.getInstance(properties);
         try {
             MimeMessage message = new MimeMessage(session);
-            message.setFrom(membersFinder.getCurrentMember().getEmail());
+            Member sender = membersFinder.getCurrentMember();
+            Credentials credentials = credentialsService.getCredentials();
+            message.setFrom(new InternetAddress(sender.getEmail(), sender.getEmail(), StandardCharsets.UTF_8.name()));
             message.setSubject(subject);
             message.setText(body, StandardCharsets.UTF_8.name());
             message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
-            Transport.send(message);
-        } catch (MessagingException e) {
-
+            Transport.send(message, new Address[] {new InternetAddress(to)}, credentials.getUsername(), credentials.getPassword());
+        } catch (MessagingException | UnsupportedEncodingException e) {
+            LOGGER.error(String.format("Unable to send email with Subject '%s' to '%s'.", subject, to), e);
         }
 
     }


[sling-org-apache-sling-committer-cli] 13/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 45adcd8076d9cab47101542a3fa750a30eb2e18b
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Mar 25 18:33:29 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * added support for querying Sling's project members
    * improved TallyVotesCommand to list binding and non-binding votes
---
 .../org/apache/sling/cli/impl/people/Member.java   |  58 +++++++++++
 .../sling/cli/impl/people/MembersFinder.java       | 110 +++++++++++++++++++++
 .../sling/cli/impl/release/TallyVotesCommand.java  |  57 ++++++++---
 3 files changed, 213 insertions(+), 12 deletions(-)

diff --git a/src/main/java/org/apache/sling/cli/impl/people/Member.java b/src/main/java/org/apache/sling/cli/impl/people/Member.java
new file mode 100644
index 0000000..7b3cb16
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/people/Member.java
@@ -0,0 +1,58 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you 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.apache.sling.cli.impl.people;
+
+public class Member {
+
+    private String id;
+    private String name;
+    private boolean isPMCMember;
+
+    Member(String id, String name, boolean isPMCMember) {
+        this.id = id;
+        this.name = name;
+        this.isPMCMember = isPMCMember;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean isPMCMember() {
+        return isPMCMember;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Member)) {
+            return false;
+        }
+        Member other = (Member) obj;
+        return id.equals(other.id);
+    }
+}
diff --git a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
new file mode 100644
index 0000000..10cba19
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
@@ -0,0 +1,110 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you 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.apache.sling.cli.impl.people;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+@Component(service = MembersFinder.class)
+public class MembersFinder {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(MembersFinder.class);
+    private static final String PEOPLE_ENDPOINT = "https://whimsy.apache.org/public/public_ldap_people.json";
+    private static final String PROJECTS_ENDPOINT = "https://whimsy.apache.org/public/public_ldap_projects.json";
+    private static final int STALENESS_IN_HOURS = 3;
+    private Set<Member> members = Collections.emptySet();
+    private long lastCheck = 0;
+
+    public synchronized Set<Member> findMembers() {
+        final Set<Member> _members = new HashSet<>();
+        if (lastCheck == 0 || System.currentTimeMillis() > lastCheck + STALENESS_IN_HOURS * 3600 * 1000) {
+            lastCheck = System.currentTimeMillis();
+            try (CloseableHttpClient client = HttpClients.createDefault()) {
+                JsonParser parser = new JsonParser();
+                Set<String> memberIds;
+                Set<String> pmcMemberIds;
+                try (CloseableHttpResponse response = client.execute(new HttpGet(PROJECTS_ENDPOINT))) {
+                    try (InputStream content = response.getEntity().getContent();
+                         InputStreamReader reader = new InputStreamReader(content)) {
+                        if (response.getStatusLine().getStatusCode() != 200) {
+                            throw new IOException("Status line : " + response.getStatusLine());
+                        }
+                        JsonElement jsonElement = parser.parse(reader);
+                        JsonObject json = jsonElement.getAsJsonObject();
+                        JsonObject sling = json.get("projects").getAsJsonObject().get("sling").getAsJsonObject();
+                        memberIds = new HashSet<>();
+                        pmcMemberIds = new HashSet<>();
+                        for (JsonElement member : sling.getAsJsonArray("members")) {
+                            memberIds.add(member.getAsString());
+                        }
+                        for (JsonElement pmcMember : sling.getAsJsonArray("owners")) {
+                            pmcMemberIds.add(pmcMember.getAsString());
+                        }
+                    }
+                }
+                try (CloseableHttpResponse response = client.execute(new HttpGet(PEOPLE_ENDPOINT))) {
+                    try (InputStream content = response.getEntity().getContent();
+                         InputStreamReader reader = new InputStreamReader(content)) {
+                        if (response.getStatusLine().getStatusCode() != 200) {
+                            throw new IOException("Status line : " + response.getStatusLine());
+                        }
+                        JsonElement jsonElement = parser.parse(reader);
+                        JsonObject json = jsonElement.getAsJsonObject();
+                        JsonObject people = json.get("people").getAsJsonObject();
+                        for (String id : memberIds) {
+                            String name = people.get(id).getAsJsonObject().get("name").getAsString();
+                            _members.add(new Member(id, name, pmcMemberIds.contains(id)));
+                        }
+
+                    }
+                }
+                members = Collections.unmodifiableSet(_members);
+            } catch (IOException e) {
+                LOGGER.error("Unable to retrieve Apache Sling project members.", e);
+            }
+        }
+        return members;
+    }
+
+    public Member getMemberById(String id) {
+        for (Member member : findMembers()) {
+            if (id.equals(member.getId())) {
+                return member;
+            }
+        }
+        return null;
+    }
+
+}
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 6046405..74cdd23 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
@@ -18,6 +18,8 @@ package org.apache.sling.cli.impl.release;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 import org.apache.sling.cli.impl.Command;
@@ -26,6 +28,8 @@ import org.apache.sling.cli.impl.mail.EmailThread;
 import org.apache.sling.cli.impl.mail.VoteThreadFinder;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
 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.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
@@ -37,7 +41,10 @@ import org.slf4j.LoggerFactory;
     Command.PROPERTY_NAME_SUMMARY+"=Counts votes cast for a release and generates the result email"
 })
 public class TallyVotesCommand implements Command {
-    
+
+    @Reference
+    private MembersFinder membersFinder;
+
     // TODO - move to file
     private static final String EMAIL_TEMPLATE =
             "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
@@ -45,12 +52,17 @@ public class TallyVotesCommand implements Command {
             "\n" + 
             "Hi,\n" + 
             "\n" + 
-            "The vote has passed with the following result :\n" + 
+            "The vote has passed with the following result:\n" +
             "\n" + 
             "+1 (binding): ##BINDING_VOTERS##\n" + 
-            "\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";
+            "promote the artifacts to the central Maven repository.\n" +
+            "\n" +
+            "Regards,\n" +
+            "##USER_NAME##\n" +
+            "\n";
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
     @Reference
@@ -67,16 +79,37 @@ public class TallyVotesCommand implements Command {
             Release release = Release.fromString(repository.getDescription());
             EmailThread voteThread = voteThreadFinder.findVoteThread(release.getFullName());
 
-            // TODO - validate which voters are binding and list them separately in the email
-            String bindingVoters = voteThread.getEmails().stream()
-                .filter( e -> isPositiveVote(e) )
-                .map ( e -> e.getFrom().replaceAll("<.*>", "").trim() )
-                .collect(Collectors.joining(", "));
-            
+            Set<String> bindingVoters = new HashSet<>();
+            Set<String> nonBindingVoters = new HashSet<>();
+            for (Email e : voteThread.getEmails()) {
+                if (isPositiveVote(e)) {
+                    String sender = e.getFrom().replaceAll("<.*>", "").trim();
+                    for (Member m : membersFinder.findMembers()) {
+                        if (sender.equals(m.getName())) {
+                            if (m.isPMCMember()) {
+                                bindingVoters.add(sender);
+                            } else {
+                                nonBindingVoters.add(sender);
+                            }
+                        }
+                    }
+                }
+            }
+            String currentUserId = System.getProperty("asf.username");
+            if (currentUserId == null) {
+                currentUserId = System.getenv("ASF_USERNAME");
+            }
+            Member currentUser = membersFinder.getMemberById(currentUserId);
             String email = EMAIL_TEMPLATE
                 .replace("##RELEASE_NAME##", release.getFullName())
-                .replace("##BINDING_VOTERS##", bindingVoters);
-            
+                .replace("##BINDING_VOTERS##", String.join(", ", bindingVoters))
+                .replace("##USER_NAME##", currentUser == null ? "" : currentUser.getName());
+            if (nonBindingVoters.isEmpty()) {
+                email = email.replace("##NON_BINDING_VOTERS##", "none");
+            } else {
+                email = email.replace("##NON_BINDING_VOTERS##", String.join(", ", nonBindingVoters));
+            }
+
             logger.info(email);
             
         } catch (IOException e) {


[sling-org-apache-sling-committer-cli] 10/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 3cba59df2786d945bf40e2fb2b911107bf13d1fc
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Wed Mar 20 14:58:05 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    * removed space in subject for tally votes email
---
 src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 86742bb..cbda427 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
@@ -41,7 +41,7 @@ public class TallyVotesCommand implements Command {
     // TODO - move to file
     private static final String EMAIL_TEMPLATE =
             "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
-            "Subject: [RESULT] [VOTE] Release ##RELEASE_NAME##\n" + 
+            "Subject: [RESULT][VOTE] Release ##RELEASE_NAME##\n" + 
             "\n" + 
             "Hi,\n" + 
             "\n" + 


[sling-org-apache-sling-committer-cli] 06/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit 7675184c579148b7d12a11b9f256c53f558f4204
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 19 16:21:26 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Fix local site update diff generation.
---
 .../java/org/apache/sling/cli/impl/release/ReleaseVersion.java     | 7 ++++++-
 .../org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java  | 6 ++----
 .../java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java | 1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java b/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
index b629e19..0f0ef96 100644
--- a/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
+++ b/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
@@ -27,12 +27,14 @@ public final class ReleaseVersion {
         rel.name = rel.fullName
             .replace("Apache Sling ", ""); // Apache Sling prefix
         rel.version = rel.fullName.substring(rel.fullName.lastIndexOf(' ') + 1);
+        rel.component = rel.name.substring(0, rel.name.lastIndexOf(' '));
         
         return rel;
     }
     
     private String fullName;
     private String name;
+    private String component;
     private String version;
 
     private ReleaseVersion() {
@@ -50,5 +52,8 @@ public final class ReleaseVersion {
     public String getVersion() {
         return version;
     }
-    
+
+    public String getComponent() {
+        return component;
+    }
 }
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 10e836a..613afe0 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,8 +21,6 @@ import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.Locale;
 
 import org.apache.sling.cli.impl.Command;
 import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
@@ -66,8 +64,8 @@ public class UpdateLocalSiteCommand implements Command {
         
                 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, releaseVersion.getName(), releaseVersion.getVersion());
-                updater.updateReleases(releasesPath, releaseVersion.getName(), releaseVersion.getVersion(), LocalDateTime.now());
+                updater.updateDownloads(templatePath, releaseVersion.getComponent(), releaseVersion.getVersion());
+                updater.updateReleases(releasesPath, releaseVersion.getComponent(), releaseVersion.getVersion(), LocalDateTime.now());
         
                 git.diff()
                     .setOutputStream(System.out)
diff --git a/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java b/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
index 90ed3e5..fc63a5f 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
@@ -30,5 +30,6 @@ public class ReleaseVersionTest {
         assertEquals("Resource Merger 1.3.10", rel.getName());
         assertEquals("Apache Sling Resource Merger 1.3.10", rel.getFullName());
         assertEquals("1.3.10", rel.getVersion());
+        assertEquals("Resource Merger", rel.getComponent());
     }
 }


[sling-org-apache-sling-committer-cli] 03/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit e54afe118b167cbb113c137be29d7093b0e9ebc2
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Fri Mar 8 14:55:14 2019 +0200

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Implement command for generating release result email, still WIP.
---
 README.md                                          |  8 ++-
 docker-env.sample                                  |  1 -
 .../TallyVotesCommand.java => mail/Email.java}     | 39 ++++++++-----
 .../EmailThread.java}                              | 26 +++------
 .../sling/cli/impl/mail/VoteThreadFinder.java      | 61 ++++++++++++++++++++
 .../sling/cli/impl/release/TallyVotesCommand.java  | 67 +++++++++++++++++++++-
 6 files changed, 166 insertions(+), 36 deletions(-)

diff --git a/README.md b/README.md
index af04f3f..eabf20c 100644
--- a/README.md
+++ b/README.md
@@ -18,10 +18,16 @@ The image is built using `mvn package`. Afterwards it may be run with
     
 This invocation produces a list of available subcommands.
 
-Currently the only implemented command is generating the release vote email, for instance
+## Commands
+
+Generating a release vote email
 
     docker run --env-file=./docker-env apache/sling-cli release prepare-email $STAGING_REPOSITORY_ID
     
+Generating a release vote result email
+
+    docker run --env-file=./docker-env apache/sling-cli release tally-votes $STAGING_REPOSITORY_ID
+    
 ## Assumptions
 
 This tool assumes that the name of the staging repository matches the one of the version in Jira. For instance, the
diff --git a/docker-env.sample b/docker-env.sample
index 15454cf..7a2a892 100644
--- a/docker-env.sample
+++ b/docker-env.sample
@@ -12,4 +12,3 @@
 # ----------------------------------------------------------------------------------------
 ASF_USERNAME=changeme
 ASF_PASSWORD=changeme
-RELEASE_ID=42
diff --git a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java b/src/main/java/org/apache/sling/cli/impl/mail/Email.java
similarity index 54%
copy from src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
copy to src/main/java/org/apache/sling/cli/impl/mail/Email.java
index 690a4d2..54ec66e 100644
--- a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
+++ b/src/main/java/org/apache/sling/cli/impl/mail/Email.java
@@ -14,26 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.cli.impl.release;
+package org.apache.sling.cli.impl.mail;
 
-import org.apache.sling.cli.impl.Command;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+public class Email {
+    private String from;
+    private String subject;
+    private String body;
 
-@Component(service = Command.class, property = {
-    Command.PROPERTY_NAME_COMMAND+"=release",
-    Command.PROPERTY_NAME_SUBCOMMAND+"=tally-votes",
-    Command.PROPERTY_NAME_SUMMARY+"=Counts votes cast for a release and generates the result email"
-})
-public class TallyVotesCommand implements Command {
+    public String getFrom() {
+        return from;
+    }
+
+    public void setFrom(String from) {
+        this.from = from;
+    }
 
-    private final Logger logger = LoggerFactory.getLogger(getClass());
+    public String getSubject() {
+        return subject;
+    }
 
-    @Override
-    public void execute(String target) {
-        logger.info("Tallying votes for release {}", target);
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getBody() {
+        return body;
+    }
 
+    public void setBody(String body) {
+        this.body = body;
     }
 
 }
diff --git a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java b/src/main/java/org/apache/sling/cli/impl/mail/EmailThread.java
similarity index 54%
copy from src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
copy to src/main/java/org/apache/sling/cli/impl/mail/EmailThread.java
index 690a4d2..03ac673 100644
--- a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
+++ b/src/main/java/org/apache/sling/cli/impl/mail/EmailThread.java
@@ -14,26 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sling.cli.impl.release;
+package org.apache.sling.cli.impl.mail;
 
-import org.apache.sling.cli.impl.Command;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.List;
 
-@Component(service = Command.class, property = {
-    Command.PROPERTY_NAME_COMMAND+"=release",
-    Command.PROPERTY_NAME_SUBCOMMAND+"=tally-votes",
-    Command.PROPERTY_NAME_SUMMARY+"=Counts votes cast for a release and generates the result email"
-})
-public class TallyVotesCommand implements Command {
-
-    private final Logger logger = LoggerFactory.getLogger(getClass());
-
-    @Override
-    public void execute(String target) {
-        logger.info("Tallying votes for release {}", target);
+public class EmailThread {
+    private List<Email> emails;
 
+    public List<Email> getEmails() {
+        return emails;
     }
 
+    public void setEmails(List<Email> emails) {
+        this.emails = emails;
+    }
 }
diff --git a/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java b/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java
new file mode 100644
index 0000000..0d39968
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.mail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.osgi.service.component.annotations.Component;
+
+import com.google.gson.Gson;
+
+@Component(service = VoteThreadFinder.class)
+public class VoteThreadFinder {
+    
+    public EmailThread findVoteThread(String releaseName) throws IOException {
+        try ( CloseableHttpClient client = HttpClients.createDefault() ) {
+            
+            URI uri = new URIBuilder("https://lists.apache.org/api/stats.lua")
+                .addParameter("domain", "sling.apache.org")
+                .addParameter("list", "dev")
+                .addParameter("d", "lte=1M")
+                .addParameter("q", "[VOTE] Release " + releaseName)
+                .build();
+            
+            HttpGet get = new HttpGet(uri);
+            try ( CloseableHttpResponse response = client.execute(get)) {
+                try ( InputStream content = response.getEntity().getContent();
+                        InputStreamReader reader = new InputStreamReader(content)) {
+                    if ( response.getStatusLine().getStatusCode() != 200 )
+                        throw new IOException("Status line : " + response.getStatusLine());
+                    Gson gson = new Gson();
+                    return gson.fromJson(reader, EmailThread.class);
+                }
+            }
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+}
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 690a4d2..8e34d87 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
@@ -16,8 +16,18 @@
  */
 package org.apache.sling.cli.impl.release;
 
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
 import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.mail.Email;
+import org.apache.sling.cli.impl.mail.EmailThread;
+import org.apache.sling.cli.impl.mail.VoteThreadFinder;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
 import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -27,13 +37,66 @@ import org.slf4j.LoggerFactory;
     Command.PROPERTY_NAME_SUMMARY+"=Counts votes cast for a release and generates the result email"
 })
 public class TallyVotesCommand implements Command {
-
+    
+    // TODO - move to file
+    private static final String EMAIL_TEMPLATE ="\n" + 
+            "\n" + 
+            "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
+            "Subject: [RESULT] [VOTE] Release Apache Sling ##RELEASE_NAME##\n" + 
+            "\n" + 
+            "Hi,\n" + 
+            "\n" + 
+            "The vote has passed with the following result :\n" + 
+            "\n" + 
+            "+1 (binding): ##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";
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
+    @Reference
+    private StagingRepositoryFinder repoFinder;
+    
+    @Reference
+    private VoteThreadFinder voteThreadFinder;
+    
     @Override
     public void execute(String target) {
-        logger.info("Tallying votes for release {}", target);
+        try {
+            
+            StagingRepository repository = repoFinder.find(Integer.parseInt(target));
+            // TODO - release name cleanup does not belong here
+            String releaseName = repository.getDescription().replaceFirst(" RC[0-9]+", "");
+            EmailThread voteThread = voteThreadFinder.findVoteThread(releaseName);
+
+            // TODO - validate which voters are binding and list them separately in the email
+            String bindingVoters = voteThread.getEmails().stream()
+                .filter( e -> isPositiveVote(e) )
+                .map ( e -> e.getFrom().replaceAll("<.*>", "").trim() )
+                .collect(Collectors.joining(", "));
+            
+            String email = EMAIL_TEMPLATE
+                .replace("##RELEASE_NAME##", releaseName)
+                .replace("##BINDING_VOTERS##", bindingVoters);
+            
+            logger.info(email);
+            
+        } catch (IOException e) {
+            logger.warn("Command execution failed", e);
+        }
+    }
+
+    // TODO - better detection of '+1' votes
+    private boolean isPositiveVote(Email e) {
+        return cleanup(e.getBody()).contains("+1");
+    }
 
+    private String cleanup(String subject) {
+        String[] lines = subject.split("\\n");
+        return Arrays.stream(lines)
+            .filter( l -> !l.isEmpty() )
+            .filter( l -> !l.startsWith(">"))
+            .collect(Collectors.joining("\n"));
     }
 
 }


[sling-org-apache-sling-committer-cli] 04/21: SLING-8311 - Investigate creating a Sling CLI tool for development task automation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git

commit d5e841e05e0b1f3e8f1e1c224ab634f2ef254168
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Tue Mar 19 15:16:23 2019 +0100

    SLING-8311 - Investigate creating a Sling CLI tool for development task automation
    
    Implement command for listing active releases.
---
 README.md                                          |   8 +-
 .../cli/impl/nexus/StagingRepositoryFinder.java    |  37 ++++++--
 .../apache/sling/cli/impl/release/ListCommand.java |  49 ++++++++++
 .../cli/impl/release/PrepareVoteEmailCommand.java  |  15 +--
 .../sling/cli/impl/release/ReleaseVersion.java}    |  41 +++++++--
 .../sling/cli/impl/release/TallyVotesCommand.java  |   9 +-
 .../cli/impl/release/UpdateLocalSiteCommand.java   | 102 +++++++++++++++++++++
 ...ailCommandTest.java => ReleaseVersionTest.java} |  11 ++-
 8 files changed, 234 insertions(+), 38 deletions(-)

diff --git a/README.md b/README.md
index eabf20c..45336b1 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@ This invocation produces a list of available subcommands.
 
 ## Commands
 
+Listing active releases
+
+    docker run --env-file=./docker-env apache/sling-cli release list
+
 Generating a release vote email
 
     docker run --env-file=./docker-env apache/sling-cli release prepare-email $STAGING_REPOSITORY_ID
@@ -27,7 +31,7 @@ Generating a release vote email
 Generating a release vote result email
 
     docker run --env-file=./docker-env apache/sling-cli release tally-votes $STAGING_REPOSITORY_ID
-    
+
 ## Assumptions
 
 This tool assumes that the name of the staging repository matches the one of the version in Jira. For instance, the
@@ -35,4 +39,4 @@ staging repositories are usually named _Apache Sling Foo 1.2.0_. It is then expe
 named _Foo 1.2.0_. Otherwise the link between the staging repository and the Jira release can not be found.
 
 It is allowed for staging repository names to have an _RC_ suffix, which may include a number, so that _RC_, _RC1_, _RC25_ are
-all valid suffixes.  
\ No newline at end of file
+all valid suffixes.  
diff --git a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
index 3ef7992..21b30ff 100644
--- a/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
+++ b/src/main/java/org/apache/sling/cli/impl/nexus/StagingRepositoryFinder.java
@@ -19,6 +19,9 @@ package org.apache.sling.cli.impl.nexus;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
@@ -43,6 +46,8 @@ import com.google.gson.Gson;
 )
 @Designate(ocd = StagingRepositoryFinder.Config.class)
 public class StagingRepositoryFinder {
+    
+    private static final String REPOSITORY_PREFIX = "orgapachesling-";
 
     @ObjectClassDefinition
     static @interface Config {
@@ -61,8 +66,30 @@ public class StagingRepositoryFinder {
         credentialsProvider.setCredentials(new AuthScope("repository.apache.org", 443), 
                 new UsernamePasswordCredentials(cfg.username(), cfg.password()));
     }
+    
+    public List<StagingRepository> list() throws IOException {
+        return this. <List<StagingRepository>> withStagingRepositories( reader -> {
+            Gson gson = new Gson();
+            return gson.fromJson(reader, StagingRepositories.class).getData().stream()
+                    .filter( r -> r.getType() == Status.closed)
+                    .filter( r -> r.getRepositoryId().startsWith(REPOSITORY_PREFIX) )
+                    .collect(Collectors.toList());            
+        });
+    }
 
     public StagingRepository find(int stagingRepositoryId) throws IOException {
+        return this.<StagingRepository> withStagingRepositories( reader -> {
+            Gson gson = new Gson();
+            return gson.fromJson(reader, StagingRepositories.class).getData().stream()
+                    .filter( r -> r.getType() == Status.closed)
+                    .filter( r -> r.getRepositoryId().startsWith(REPOSITORY_PREFIX) )
+                    .filter( r -> r.getRepositoryId().endsWith("-" + stagingRepositoryId))
+                    .findFirst()
+                    .orElseThrow(() -> new IllegalArgumentException("No repository found with id " + stagingRepositoryId));            
+        });
+    }
+    
+    private <T> T withStagingRepositories(Function<InputStreamReader, T> function) throws IOException {
         try ( CloseableHttpClient client = HttpClients.custom()
                 .setDefaultCredentialsProvider(credentialsProvider)
                 .build() ) {
@@ -73,14 +100,10 @@ public class StagingRepositoryFinder {
                         InputStreamReader reader = new InputStreamReader(content)) {
                     if ( response.getStatusLine().getStatusCode() != 200 )
                         throw new IOException("Status line : " + response.getStatusLine());
-                    Gson gson = new Gson();
-                    return gson.fromJson(reader, StagingRepositories.class).getData().stream()
-                        .filter( r -> r.getType() == Status.closed)
-                        .filter( r -> r.getRepositoryId().endsWith("-" + stagingRepositoryId))
-                        .findFirst()
-                        .orElseThrow(() -> new IllegalArgumentException("No repository found with id " + stagingRepositoryId));
+                    
+                    return function.apply(reader);
                 }
             }
-        }
+        }       
     }
 }
diff --git a/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java b/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java
new file mode 100644
index 0000000..1d35e29
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = Command.class, property = {
+        Command.PROPERTY_NAME_COMMAND + "=release",
+        Command.PROPERTY_NAME_SUBCOMMAND + "=list",
+        Command.PROPERTY_NAME_SUMMARY + "=Lists all open releases" })
+public class ListCommand implements Command {
+
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    @Reference
+    private StagingRepositoryFinder repoFinder;
+
+    @Override
+    public void execute(String target) {
+        try {
+            repoFinder.list().stream()
+                .forEach( r -> logger.info("{}\t{}", r.getRepositoryId(), r.getDescription()));
+        } catch (IOException e) {
+            logger.warn("Failed executing command", e);
+        }
+    }
+
+}
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 eff3a3f..5b8df75 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
@@ -36,7 +36,7 @@ public class PrepareVoteEmailCommand implements Command {
 
     // TODO - replace with file template
     private static final String EMAIL_TEMPLATE ="To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
-            "Subject: [VOTE] Release Apache Sling ##RELEASE_NAME##\n" + 
+            "Subject: [VOTE] Release ##RELEASE_NAME##\n" + 
             "\n" + 
             "Hi,\n" + 
             "\n" + 
@@ -73,11 +73,11 @@ public class PrepareVoteEmailCommand implements Command {
         try {
             int repoId = Integer.parseInt(target);
             StagingRepository repo = repoFinder.find(repoId);
-            String cleanVersion = getCleanVersion(repo.getDescription());
-            Version version = versionFinder.find(cleanVersion);
+            ReleaseVersion releaseVersion = ReleaseVersion.fromRepositoryDescription(repo.getDescription());
+            Version version = versionFinder.find(releaseVersion.getName());
             
             String emailContents = EMAIL_TEMPLATE
-                    .replace("##RELEASE_NAME##", cleanVersion)
+                    .replace("##RELEASE_NAME##", releaseVersion.getFullName())
                     .replace("##RELEASE_ID##", String.valueOf(repoId))
                     .replace("##VERSION_ID##", String.valueOf(version.getId()))
                     .replace("##FIXED_ISSUES_COUNT##", String.valueOf(version.getIssuesFixedCount()));
@@ -88,11 +88,4 @@ public class PrepareVoteEmailCommand implements Command {
             logger.warn("Failed executing command", e);
         }
     }
-
-    static String getCleanVersion(String repoDescription) {
-        return repoDescription
-                .replace("Apache Sling ", "") // Apache Sling prefix
-                .replaceAll(" RC[0-9]*$", ""); // 'release candidate' suffix 
-    }
-
 }
diff --git a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java b/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
similarity index 50%
copy from src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
copy to src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
index 8dd81aa..b629e19 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
+++ b/src/main/java/org/apache/sling/cli/impl/release/ReleaseVersion.java
@@ -16,16 +16,39 @@
  */
 package org.apache.sling.cli.impl.release;
 
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class PrepareVoteEmailCommandTest {
+public final class ReleaseVersion {
+    
+    public static ReleaseVersion fromRepositoryDescription(String repositoryDescription) {
+        
+        ReleaseVersion rel = new ReleaseVersion();
+        
+        rel.fullName = repositoryDescription
+            .replaceAll(" RC[0-9]*$", ""); // 'release candidate' suffix
+        rel.name = rel.fullName
+            .replace("Apache Sling ", ""); // Apache Sling prefix
+        rel.version = rel.fullName.substring(rel.fullName.lastIndexOf(' ') + 1);
+        
+        return rel;
+    }
+    
+    private String fullName;
+    private String name;
+    private String version;
 
-    @Test
-    public void cleanVersion() {
+    private ReleaseVersion() {
         
-        assertEquals("Resource Merger 1.3.10", 
-                PrepareVoteEmailCommand.getCleanVersion("Apache Sling Resource Merger 1.3.10 RC1"));
     }
+    
+    public String getFullName() {
+        return fullName;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public String getVersion() {
+        return version;
+    }
+    
 }
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 8e34d87..f15f60b 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
@@ -42,7 +42,7 @@ public class TallyVotesCommand implements Command {
     private static final String EMAIL_TEMPLATE ="\n" + 
             "\n" + 
             "To: \"Sling Developers List\" <de...@sling.apache.org>\n" + 
-            "Subject: [RESULT] [VOTE] Release Apache Sling ##RELEASE_NAME##\n" + 
+            "Subject: [RESULT] [VOTE] Release ##RELEASE_NAME##\n" + 
             "\n" + 
             "Hi,\n" + 
             "\n" + 
@@ -65,9 +65,8 @@ public class TallyVotesCommand implements Command {
         try {
             
             StagingRepository repository = repoFinder.find(Integer.parseInt(target));
-            // TODO - release name cleanup does not belong here
-            String releaseName = repository.getDescription().replaceFirst(" RC[0-9]+", "");
-            EmailThread voteThread = voteThreadFinder.findVoteThread(releaseName);
+            ReleaseVersion releaseVersion = ReleaseVersion.fromRepositoryDescription(repository.getDescription()); 
+            EmailThread voteThread = voteThreadFinder.findVoteThread(releaseVersion.getFullName());
 
             // TODO - validate which voters are binding and list them separately in the email
             String bindingVoters = voteThread.getEmails().stream()
@@ -76,7 +75,7 @@ public class TallyVotesCommand implements Command {
                 .collect(Collectors.joining(", "));
             
             String email = EMAIL_TEMPLATE
-                .replace("##RELEASE_NAME##", releaseName)
+                .replace("##RELEASE_NAME##", releaseVersion.getFullName())
                 .replace("##BINDING_VOTERS##", bindingVoters);
             
             logger.info(email);
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
new file mode 100644
index 0000000..483613e
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.sling.cli.impl.release;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
+
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.ResetCommand.ResetType;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(service = Command.class, property = {
+    Command.PROPERTY_NAME_COMMAND+"=release",
+    Command.PROPERTY_NAME_SUBCOMMAND+"=update-local-site",
+    Command.PROPERTY_NAME_SUMMARY+"=Updates the Sling website with the new release information, based on a local checkout"
+})
+public class UpdateLocalSiteCommand implements Command {
+    
+    public static void main(String[] args) {
+        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMMM uuuu", Locale.ENGLISH)));
+    }
+
+    private static final String GIT_CHECKOUT = "/tmp/sling-site";
+
+    @Reference
+    private StagingRepositoryFinder repoFinder;
+    
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+    
+    @Override
+    public void execute(String target) {
+        
+        
+        try {
+            ensureRepo();
+            try ( Git git = Git.open(new File(GIT_CHECKOUT)) ) {
+                
+                StagingRepository repository = repoFinder.find(Integer.parseInt(target));
+                ReleaseVersion releaseVersion = ReleaseVersion.fromRepositoryDescription(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, releaseVersion.getName(), releaseVersion.getVersion());
+                updater.updateReleases(releasesPath, releaseVersion.getName(), releaseVersion.getVersion(), LocalDateTime.now());
+        
+                git.diff()
+                    .setOutputStream(System.out)
+                    .call();
+            }
+        } catch (GitAPIException | IOException e) {
+            logger.warn("Failed executing command", e);
+        }
+            
+    }
+
+    private void ensureRepo() throws GitAPIException, IOException {
+        
+        if ( !Paths.get(GIT_CHECKOUT).toFile().exists() ) {
+            Git.cloneRepository()
+            .setURI("https://github.com/apache/sling-site.git")
+            .setProgressMonitor(new TextProgressMonitor())
+            .setDirectory(new File(GIT_CHECKOUT))
+            .call();
+        } else {
+            try ( Git git = Git.open(new File(GIT_CHECKOUT)) )  {
+                git.reset()
+                    .setMode(ResetType.HARD)
+                    .call();
+            }
+        }
+    }
+}
diff --git a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
similarity index 70%
rename from src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
rename to src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
index 8dd81aa..90ed3e5 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/release/ReleaseVersionTest.java
@@ -20,12 +20,15 @@ import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
 
-public class PrepareVoteEmailCommandTest {
+public class ReleaseVersionTest {
 
     @Test
-    public void cleanVersion() {
+    public void fromRepositoryDescription() {
         
-        assertEquals("Resource Merger 1.3.10", 
-                PrepareVoteEmailCommand.getCleanVersion("Apache Sling Resource Merger 1.3.10 RC1"));
+        ReleaseVersion rel = ReleaseVersion.fromRepositoryDescription("Apache Sling Resource Merger 1.3.10 RC1");
+        
+        assertEquals("Resource Merger 1.3.10", rel.getName());
+        assertEquals("Apache Sling Resource Merger 1.3.10", rel.getFullName());
+        assertEquals("1.3.10", rel.getVersion());
     }
 }