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

[sling-org-apache-sling-committer-cli] 01/01: SLING-8391 - Add support for execution modes

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

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

commit 74d74152ec6bf2b7f92d256deb1d1ffbbe3efee0
Author: Radu Cotescu <co...@adobe.com>
AuthorDate: Fri May 3 15:17:05 2019 +0200

    SLING-8391 - Add support for execution modes
    
    * implemented support for an execution context that commands can use
    to define the way they operate
    * none of the commands actively use the execution mode yet
---
 .../java/org/apache/sling/cli/impl/Command.java    |  2 +-
 .../apache/sling/cli/impl/CommandProcessor.java    | 52 +++++++------
 .../apache/sling/cli/impl/ExecutionContext.java    | 86 ++++++++++++++++++++++
 .../apache/sling/cli/impl/release/ListCommand.java |  3 +-
 .../cli/impl/release/PrepareVoteEmailCommand.java  |  5 +-
 .../sling/cli/impl/release/TallyVotesCommand.java  |  5 +-
 .../cli/impl/release/UpdateLocalSiteCommand.java   |  7 +-
 .../cli/impl/release/UpdateReporterCommand.java    |  7 +-
 .../impl/release/PrepareVoteEmailCommandTest.java  |  3 +-
 .../cli/impl/release/TallyVotesCommandTest.java    |  3 +-
 10 files changed, 135 insertions(+), 38 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 4b015c4..102b5e6 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) throws Exception;
+    void execute(ExecutionContext context) 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 6ca6bca..cb3de3a 100644
--- a/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
+++ b/src/main/java/org/apache/sling/cli/impl/CommandProcessor.java
@@ -16,9 +16,6 @@
  */
 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;
@@ -27,20 +24,26 @@ 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.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.osgi.service.component.annotations.ReferenceCardinality.MULTIPLE;
+import static org.osgi.service.component.annotations.ReferencePolicy.DYNAMIC;
+
 @Component(service = CommandProcessor.class)
 public class CommandProcessor {
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
+    private static final String EXEC_ARGS = "exec.args";
     private BundleContext ctx;
 
     private Map<CommandKey, CommandWithProps> commands = new ConcurrentHashMap<>();
 
-    protected void activate(BundleContext ctx) {
+    @Activate
+    private void activate(BundleContext ctx) {
         this.ctx = ctx;
     }
 
@@ -53,17 +56,17 @@ public class CommandProcessor {
         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"));
+    void runCommand() {
+        String[] arguments = arguments(ctx.getProperty(EXEC_ARGS));
+        CommandKey key = CommandKey.of(arguments);
+        ExecutionContext context = defineContext(arguments);
         try {
             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);
+            }, "")).cmd.execute(context);
         } catch (Exception e) {
             logger.warn("Failed running command", e);
         } finally {
@@ -76,15 +79,22 @@ public class CommandProcessor {
         }
     }
 
-    private String parseTarget(String cliSpec) {
-        if (cliSpec == null || cliSpec.isEmpty())
-            return null;
+    private String[] arguments(String cliSpec) {
+        if (cliSpec == null) {
+            return new String[0];
+        }
+        return cliSpec.split(" ");
+    }
 
-        String[] args = cliSpec.split(" ");
-        if (args.length < 3)
+    private ExecutionContext defineContext(String[] arguments) {
+        if (arguments.length < 3)
             return null;
-        
-        return args[2];
+        String target = arguments[2];
+        if (arguments.length > 3) {
+            return new ExecutionContext(target, arguments[3]);
+        } else {
+            return new ExecutionContext(target, null);
+        }
     }
     
 
@@ -95,15 +105,11 @@ public class CommandProcessor {
         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)
+        static CommandKey of(String[] arguments) {
+            if (arguments.length < 2)
                 return EMPTY;
 
-            return new CommandKey(args[0], args[1]);
+            return new CommandKey(arguments[0], arguments[1]);
         }
 
         static CommandKey of(Map<String, ?> serviceProps) {
diff --git a/src/main/java/org/apache/sling/cli/impl/ExecutionContext.java b/src/main/java/org/apache/sling/cli/impl/ExecutionContext.java
new file mode 100644
index 0000000..d2a433e
--- /dev/null
+++ b/src/main/java/org/apache/sling/cli/impl/ExecutionContext.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;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines the way a {@link Command} will be executed, together with the {@code command}'s execution target.
+ */
+public class ExecutionContext {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionContext.class);
+
+    private final String target;
+    private final Mode mode;
+
+    /**
+     * Creates an {@code ExecutionContext}.
+     *
+     * @param target the command's target
+     * @param mode   the execution mode
+     */
+    public ExecutionContext(String target, String mode) {
+        this.target = target;
+        if (mode == null) {
+            this.mode = Mode.DRY_RUN;
+        } else {
+            this.mode = Mode.fromString(mode);
+        }
+    }
+
+    /**
+     * Returns the execution target for a command.
+     *
+     * @return the execution target
+     */
+    public String getTarget() {
+        return target;
+    }
+
+    /**
+     * Returns the execution mode for a command.
+     *
+     * @return the execution mode
+     */
+    public Mode getMode() {
+        return mode;
+    }
+
+    enum Mode {
+        DRY_RUN("--dry-run"), INTERACTIVE("--interactive"), AUTO("--auto");
+
+        private final String string;
+
+        Mode(String string) {
+            this.string = string;
+        }
+
+        static Mode fromString(String value) {
+            for (Mode m : values()) {
+                if (m.string.equals(value)) {
+                    return m;
+                }
+            }
+            LOGGER.warn("Unknown command execution mode {}. Switching to default mode {}.", value, DRY_RUN.string);
+            return DRY_RUN;
+        }
+    }
+}
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
index 1d35e29..39b9b8d 100644
--- a/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java
+++ b/src/main/java/org/apache/sling/cli/impl/release/ListCommand.java
@@ -19,6 +19,7 @@ package org.apache.sling.cli.impl.release;
 import java.io.IOException;
 
 import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.ExecutionContext;
 import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -37,7 +38,7 @@ public class ListCommand implements Command {
     private StagingRepositoryFinder repoFinder;
 
     @Override
-    public void execute(String target) {
+    public void execute(ExecutionContext context) {
         try {
             repoFinder.list().stream()
                 .forEach( r -> logger.info("{}\t{}", r.getRepositoryId(), r.getDescription()));
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 9e50205..1862605 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 java.util.stream.Collectors;
 import javax.mail.internet.InternetAddress;
 
 import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.ExecutionContext;
 import org.apache.sling.cli.impl.jira.Version;
 import org.apache.sling.cli.impl.jira.VersionFinder;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
@@ -88,9 +89,9 @@ public class PrepareVoteEmailCommand implements Command {
             "https://issues.apache.org/jira/browse/SLING/fixforversion/##VERSION_ID##";
 
     @Override
-    public void execute(String target) {
+    public void execute(ExecutionContext context) {
         try {
-            int repoId = Integer.parseInt(target);
+            int repoId = Integer.parseInt(context.getTarget());
             StagingRepository repo = repoFinder.find(repoId);
             List<Release> releases = Release.fromString(repo.getDescription());
             List<Version> versions = releases.stream()
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 48a2f69..6e82cfd 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
@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
 import javax.mail.internet.InternetAddress;
 
 import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.ExecutionContext;
 import org.apache.sling.cli.impl.mail.Email;
 import org.apache.sling.cli.impl.mail.VoteThreadFinder;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
@@ -78,10 +79,10 @@ public class TallyVotesCommand implements Command {
             "\n";
 
     @Override
-    public void execute(String target) {
+    public void execute(ExecutionContext context) {
         try {
             
-            StagingRepository repository = repoFinder.find(Integer.parseInt(target));
+            StagingRepository repository = repoFinder.find(Integer.parseInt(context.getTarget()));
             List<Release> releases = Release.fromString(repository.getDescription());
             String releaseName = releases.stream().map(Release::getName).collect(Collectors.joining(", "));
             String releaseFullName = releases.stream().map(Release::getFullName).collect(Collectors.joining(", "));
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 99ab368..66aef04 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
@@ -24,6 +24,7 @@ import java.time.LocalDateTime;
 import java.util.List;
 
 import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.ExecutionContext;
 import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
 import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
@@ -51,14 +52,12 @@ public class UpdateLocalSiteCommand implements Command {
     private final Logger logger = LoggerFactory.getLogger(getClass());
     
     @Override
-    public void execute(String target) {
-        
-        
+    public void execute(ExecutionContext context) {
         try {
             ensureRepo();
             try ( Git git = Git.open(new File(GIT_CHECKOUT)) ) {
                 
-                StagingRepository repository = repoFinder.find(Integer.parseInt(target));
+                StagingRepository repository = repoFinder.find(Integer.parseInt(context.getTarget()));
                 List<Release> releases = Release.fromString(repository.getDescription());
                 
                 JBakeContentUpdater updater = new JBakeContentUpdater();
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 fdf0ef2..04d287c 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
@@ -39,6 +39,7 @@ 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.ExecutionContext;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
 import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
 import org.osgi.service.component.annotations.Activate;
@@ -67,9 +68,9 @@ public class UpdateReporterCommand implements Command {
     private CredentialsProvider credentialsProvider;
 
     @Override
-    public void execute(String target) {
+    public void execute(ExecutionContext context) {
         try {
-            StagingRepository repository = repoFinder.find(Integer.parseInt(target));
+            StagingRepository repository = repoFinder.find(Integer.parseInt(context.getTarget()));
             
             try (CloseableHttpClient client =
                          HttpClients.custom().setDefaultCredentialsProvider(credentialsProvider).build()) {
@@ -92,7 +93,7 @@ public class UpdateReporterCommand implements Command {
                 }
             }
         } catch (IOException e) {
-            LOGGER.error(String.format("Unable to update reporter service; passed command: %s.", target), e);
+            LOGGER.error(String.format("Unable to update reporter service; passed command: %s.", context.getTarget()), e);
         }
 
     }
diff --git a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
index 4e971f2..24a9660 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/release/PrepareVoteEmailCommandTest.java
@@ -19,6 +19,7 @@
 package org.apache.sling.cli.impl.release;
 
 import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.ExecutionContext;
 import org.apache.sling.cli.impl.jira.Version;
 import org.apache.sling.cli.impl.jira.VersionFinder;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
@@ -83,7 +84,7 @@ public class PrepareVoteEmailCommandTest {
         ServiceReference<?> reference =
                 osgiContext.bundleContext().getServiceReference(Command.class.getName());
         Command command = (Command) osgiContext.bundleContext().getService(reference);
-        command.execute("123");
+        command.execute(new ExecutionContext("123", null));
         verify(logger).info(
                 "From: John Doe <jo...@apache.org>\n" +
                         "To: \"Sling Developers List\" <de...@sling.apache.org>\n" +
diff --git a/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java
index 29f6012..7800a07 100644
--- a/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java
+++ b/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java
@@ -28,6 +28,7 @@ import javax.mail.internet.InternetAddress;
 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.ExecutionContext;
 import org.apache.sling.cli.impl.mail.Email;
 import org.apache.sling.cli.impl.mail.VoteThreadFinder;
 import org.apache.sling.cli.impl.nexus.StagingRepository;
@@ -110,7 +111,7 @@ public class TallyVotesCommandTest {
         ServiceReference<?> reference =
                 osgiContext.bundleContext().getServiceReference(Command.class.getName());
         Command command = (Command) osgiContext.bundleContext().getService(reference);
-        command.execute("123");
+        command.execute(new ExecutionContext("123", null));
         verify(logger).info(
                 "From: John Doe <jo...@apache.org> \n" +
                 "To: \"Sling Developers List\" <de...@sling.apache.org>\n" +