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

csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 9c1f77f  Allow docker actions with zip files.  (#2112)
9c1f77f is described below

commit 9c1f77fdb1e4a7339634434dc90c45026d6a43d2
Author: rodric rabbah <[email protected]>
AuthorDate: Sat Jun 17 11:54:29 2017 -0400

    Allow docker actions with zip files.  (#2112)
    
    * Allow docker actions with zip files.
    Add native action for binary injection.
    Add note about breaking change for --docker option.
    
    * Separate dep fetching from rest of build to avoid repeated fetches when 
none changed.
---
 docs/actions.md                                    | 23 +++++-
 tests/src/test/scala/common/Wsk.scala              |  4 +-
 .../test/scala/system/basic/WskBasicTests.scala    |  8 +-
 .../whisk/core/cli/test/WskBasicUsageTests.scala   | 39 ++++++----
 tools/cli/Dockerfile                               |  6 +-
 tools/cli/go-whisk-cli/commands/action.go          | 87 ++++++++++++++--------
 tools/cli/go-whisk-cli/commands/flags.go           | 41 +++++-----
 .../go-whisk-cli/wski18n/resources/en_US.all.json  | 20 ++---
 8 files changed, 144 insertions(+), 84 deletions(-)

diff --git a/docs/actions.md b/docs/actions.md
index ee75cb2..e566de7 100644
--- a/docs/actions.md
+++ b/docs/actions.md
@@ -827,7 +827,7 @@ For the instructions that follow, assume that the Docker 
user ID is `janesmith`
 
 
   ```
-  wsk action create --docker example janesmith/blackboxdemo
+  wsk action create example --docker janesmith/blackboxdemo
   ```
 
   Notice the use of `--docker` when creating an action. Currently all Docker 
images are assumed to be hosted on Docker Hub.
@@ -853,11 +853,30 @@ For the instructions that follow, assume that the Docker 
user ID is `janesmith`
   ./buildAndPush.sh janesmith/blackboxdemo
   ```
   ```
-  wsk action update --docker example janesmith/blackboxdemo
+  wsk action update example --docker janesmith/blackboxdemo
   ```
 
   You can find more information about creating Docker actions in the 
[References](./reference.md#docker-actions) section.
 
+  *Note:* Previous version of the CLI supported `--docker` without a parameter 
and the image name was a positional argument.
+  In order to allow Docker actions to accept initialization data via a (zip) 
file, similar to other actions kinds, we have
+  normalized the user experience for Docker actions so that a positional 
argument if present must be a file (e.g., a zip file)
+  instead. The image name must be specified following the `--docker` option. 
Furthermore, due to user feedback, we have added
+  `--native` as shorthand for `--docker openwhisk/dockerskeleton` so that 
executables that run inside the standard Docker action
+  SDK are more convenient to create and deploy.
+
+  For example, the tutorial above created a binary executable inside the 
container locate at `/action/exec`. If you copy this file
+  to your local file system and zip it into `exec.zip` then you can use the 
following commands to create a docker action which receives
+  the executable as initialization data.
+
+  ```bash
+  wsk action create example exec.zip --native
+  ```
+  which is equivalent to the following command.
+  ```bash
+  wsk action create example exec.zip --docker openwhisk/dockerskeleton
+  ```
+
 ## Watching action output
 
 OpenWhisk actions might be invoked by other users, in response to various 
events, or as part of an action sequence. In such cases it can be useful to 
monitor the invocations.
diff --git a/tests/src/test/scala/common/Wsk.scala 
b/tests/src/test/scala/common/Wsk.scala
index 6b7d5e2..51d3fbf 100644
--- a/tests/src/test/scala/common/Wsk.scala
+++ b/tests/src/test/scala/common/Wsk.scala
@@ -284,6 +284,7 @@ class WskAction()
         artifact: Option[String],
         kind: Option[String] = None, // one of docker, copy, sequence or none 
for autoselect else an explicit type
         main: Option[String] = None,
+        docker: Option[String] = None,
         parameters: Map[String, JsValue] = Map(),
         annotations: Map[String, JsValue] = Map(),
         parameterFile: Option[String] = None,
@@ -300,11 +301,12 @@ class WskAction()
             { artifact map { Seq(_) } getOrElse Seq() } ++
             {
                 kind map { k =>
-                    if (k == "docker" || k == "sequence" || k == "copy") 
Seq(s"--$k")
+                    if (k == "sequence" || k == "copy" || k == "native") 
Seq(s"--$k")
                     else Seq("--kind", k)
                 } getOrElse Seq()
             } ++
             { main.toSeq flatMap { p => Seq("--main", p) } } ++
+            { docker.toSeq flatMap { p => Seq("--docker", p) } } ++
             { parameters flatMap { p => Seq("-p", p._1, p._2.compactPrint) } } 
++
             { annotations flatMap { p => Seq("-a", p._1, p._2.compactPrint) } 
} ++
             { parameterFile map { pf => Seq("-P", pf) } getOrElse Seq() } ++
diff --git a/tests/src/test/scala/system/basic/WskBasicTests.scala 
b/tests/src/test/scala/system/basic/WskBasicTests.scala
index 2311f6a..4e379d0 100644
--- a/tests/src/test/scala/system/basic/WskBasicTests.scala
+++ b/tests/src/test/scala/system/basic/WskBasicTests.scala
@@ -273,7 +273,7 @@ class WskBasicTests
         (wp, assetHelper) =>
             assetHelper.withCleaner(wsk.action, name) {
                 // this docker image will be need to be pulled from dockerhub 
and hence has to be published there first
-                (action, _) => action.create(name, Some("openwhisk/example"), 
kind = Some("docker"))
+                (action, _) => action.create(name, None, docker = 
Some("openwhisk/example"))
             }
 
             val args = Map("payload" -> "test".toJson)
@@ -291,7 +291,7 @@ class WskBasicTests
         (wp, assetHelper) =>
             assetHelper.withCleaner(wsk.action, name) {
                 // this docker image will be need to be pulled from dockerhub 
and hence has to be published there first
-                (action, _) => action.create(name, 
Some(TestUtils.getTestActionFilename("blackbox.zip")), kind = Some("docker"))
+                (action, _) => action.create(name, 
Some(TestUtils.getTestActionFilename("blackbox.zip")), kind = Some("native"))
             }
 
             val run = wsk.action.invoke(name, Map())
@@ -348,7 +348,7 @@ class WskBasicTests
             wsk.action.get(name, fieldFilter = Some("annotations")).stdout 
should include regex (s"""$successMsg 
annotations\n\\[\\s+\\{\\s+"key":\\s+"exec",\\s+"value":\\s+"nodejs:6"\\s+\\}\\s+\\]""")
             wsk.action.get(name, fieldFilter = Some("limits")).stdout should 
include regex (s"""$successMsg 
limits\n\\{\\s+"timeout":\\s+60000,\\s+"memory":\\s+256,\\s+"logs":\\s+10\\s+\\}""")
             wsk.action.get(name, fieldFilter = Some("namespace")).stdout 
should include regex (s"""(?i)$successMsg namespace\n$ns_regex_list""")
-            wsk.action.get(name, fieldFilter = Some("invalid"), 
expectedExitCode = ERROR_EXIT).stderr should include("error: Invalid field 
filter 'invalid'.")
+            wsk.action.get(name, fieldFilter = Some("invalid"), 
expectedExitCode = MISUSE_EXIT).stderr should include("error: Invalid field 
filter 'invalid'.")
             wsk.action.get(name, fieldFilter = Some("publish")).stdout should 
include(s"""$successMsg publish\nfalse""")
     }
 
@@ -485,7 +485,7 @@ class WskBasicTests
         val name = "dockerContainer"
         (wp, assetHelper) =>
             assetHelper.withCleaner(wsk.action, name) {
-                (action, _) => action.create(name, Some("fake-container"), 
kind = Some("docker"))
+                (action, _) => action.create(name, None, docker = 
Some("fake-container"))
             }
 
             wsk.action.get(name).stdout should not include (""""code"""")
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala 
b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index 8513875..83f27d8 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -273,7 +273,15 @@ class WskBasicUsageTests
             val file = Some(TestUtils.getTestActionFilename("hello.js"))
             assetHelper.withCleaner(wsk.action, name) { (action, name) => 
action.create(name, file) }
             // Update it with a missing file
-            wsk.action.create("updateMissingFile", Some("notfound"), update = 
true, expectedExitCode = MISUSE_EXIT)
+            wsk.action.create(name, Some("notfound"), update = true, 
expectedExitCode = MISUSE_EXIT)
+    }
+
+    it should "reject action update for sequence with no components" in 
withAssetCleaner(wskprops) {
+        (wp, assetHelper) =>
+            val name = "updateMissingComponents"
+            val file = Some(TestUtils.getTestActionFilename("hello.js"))
+            assetHelper.withCleaner(wsk.action, name) { (action, name) => 
action.create(name, file) }
+            wsk.action.create(name, None, update = true, kind = 
Some("sequence"), expectedExitCode = MISUSE_EXIT)
     }
 
     it should "create, and get an action to verify parameter and annotation 
parsing" in withAssetCleaner(wskprops) {
@@ -467,13 +475,13 @@ class WskBasicUsageTests
     }
 
     it should "create, and invoke an action that utilizes an invalid docker 
container with appropriate error" in withAssetCleaner(wskprops) {
-        val name = "invalid dockerContainer"
+        val name = "invalidDockerContainer"
         val containerName = 
s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
 
         (wp, assetHelper) =>
             assetHelper.withCleaner(wsk.action, name) {
                 // docker name is a randomly generate string
-                (action, _) => action.create(name, Some(containerName), kind = 
Some("docker"))
+                (action, _) => action.create(name, None, docker = 
Some(containerName))
             }
 
             val run = wsk.action.invoke(name)
@@ -608,6 +616,9 @@ class WskBasicUsageTests
                     assert(stdout.startsWith(s"ok: got action $name, 
displaying field annotations\n"))
                     removeCLIHeader(stdout).parseJson shouldBe JsArray(
                         JsObject(
+                            "key" -> JsString("exec"),
+                            "value" -> JsString("nodejs:6")),
+                        JsObject(
                             "key" -> JsString("web-export"),
                             "value" -> JsBoolean(webEnabled || rawEnabled)),
                         JsObject(
@@ -615,10 +626,7 @@ class WskBasicUsageTests
                             "value" -> JsBoolean(rawEnabled)),
                         JsObject(
                             "key" -> JsString("final"),
-                            "value" -> JsBoolean(webEnabled || rawEnabled)),
-                        JsObject(
-                            "key" -> JsString("exec"),
-                            "value" -> JsString("nodejs:6")))
+                            "value" -> JsBoolean(webEnabled || rawEnabled)))
                 }
     }
 
@@ -628,8 +636,8 @@ class WskBasicUsageTests
             val file = Some(TestUtils.getTestActionFilename("echo.js"))
             val invalidInput = "bogus"
             val errorMsg = s"Invalid argument '$invalidInput' for --web flag. 
Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'."
-            wsk.action.create(name, file, web = Some(invalidInput), 
expectedExitCode = ERROR_EXIT).stderr should include(errorMsg)
-            wsk.action.create(name, file, web = Some(invalidInput), update = 
true, expectedExitCode = ERROR_EXIT).stderr should include(errorMsg)
+            wsk.action.create(name, file, web = Some(invalidInput), 
expectedExitCode = MISUSE_EXIT).stderr should include(errorMsg)
+            wsk.action.create(name, file, web = Some(invalidInput), update = 
true, expectedExitCode = MISUSE_EXIT).stderr should include(errorMsg)
     }
 
     it should "invoke action while not encoding &, <, > characters" in 
withAssetCleaner(wskprops) {
@@ -1168,9 +1176,9 @@ class WskBasicUsageTests
         val invalidArgsMsg = "error: Invalid argument(s)"
         val tooFewArgsMsg = invalidArgsMsg + "."
         val tooManyArgsMsg = invalidArgsMsg + ": "
-        val actionNameActionReqMsg = "An action name and action are required."
+        val actionNameActionReqMsg = "An action name and code artifact are 
required."
         val actionNameReqMsg = "An action name is required."
-        val actionOptMsg = "An action is optional."
+        val actionOptMsg = "A code artifact is optional."
         val packageNameReqMsg = "A package name is required."
         val packageNameBindingReqMsg = "A package name and binding name are 
required."
         val ruleNameReqMsg = "A rule name is required."
@@ -1273,9 +1281,12 @@ class WskBasicUsageTests
 
         invalidArgs foreach {
             case (cmd, err) =>
-                val stderr = wsk.cli(cmd ++ wskprops.overrides, 
expectedExitCode = ERROR_EXIT).stderr
-                stderr should include(err)
-                stderr should include("Run 'wsk --help' for usage.")
+                withClue(cmd) {
+                    val rr = wsk.cli(cmd ++ wskprops.overrides, 
expectedExitCode = ANY_ERROR_EXIT)
+                    rr.exitCode should (be(ERROR_EXIT) or be(MISUSE_EXIT))
+                    rr.stderr should include(err)
+                    rr.stderr should include("Run 'wsk --help' for usage.")
+                }
         }
     }
 
diff --git a/tools/cli/Dockerfile b/tools/cli/Dockerfile
index 186b4d5..8ca8605 100644
--- a/tools/cli/Dockerfile
+++ b/tools/cli/Dockerfile
@@ -13,20 +13,22 @@ RUN go get github.com/tools/godep
 RUN echo "Installing the go-bindata tool"
 RUN go get github.com/jteeuwen/go-bindata/...
 
-ADD . /src/github.com/
-
 # Load all of the dependencies from the previously generated/saved godep 
generated godeps.json file
+ADD ./go-whisk-cli/Godeps /src/github.com/go-whisk-cli/Godeps
 RUN echo "Restoring Go dependencies"
 RUN cd /src/github.com/go-whisk-cli && /bin/godep restore -v
 
 # Collect all translated strings into single .go module
 RUN echo "Generating i18n Go module"
+ADD ./go-whisk-cli/wski18n /src/github.com/go-whisk-cli/wski18n
+ADD ./go-whisk/wski18n /src/github.com/go-whisk/wski18n
 RUN cd /src/github.com/go-whisk-cli && /bin/go-bindata -pkg wski18n -o 
wski18n/i18n_resources.go wski18n/resources
 RUN cd /src/github.com/go-whisk && /bin/go-bindata -pkg wski18n -o 
wski18n/i18n_resources.go wski18n/resources
 
 # Generate a Go package dependency list
 # NOTE: Currently, the 'go list' command will not work against the current Go 
CLI non-standard file structure
 #RUN cd /src/github.com/go-whisk-cli && go list -f '{{join .Deps "\n"}}' > 
../../../wsk.deps.out
+ADD . /src/github.com
 RUN cd /src/github.com/go-whisk-cli && echo "Dependencies list requires 
restructuring the GO CLI packages" > ../../../wsk.deps.out
 
 # All of the Go CLI binaries will be placed under a build folder
diff --git a/tools/cli/go-whisk-cli/commands/action.go 
b/tools/cli/go-whisk-cli/commands/action.go
index 6e2a558..0931e06 100644
--- a/tools/cli/go-whisk-cli/commands/action.go
+++ b/tools/cli/go-whisk-cli/commands/action.go
@@ -57,10 +57,10 @@ var actionCreateCmd = &cobra.Command{
 
         if whiskErr := checkArgs(
             args,
-            2,
+            1,
             2,
             "Action create",
-            wski18n.T("An action name and action are required.")); whiskErr != 
nil {
+            wski18n.T("An action name and code artifact are required.")); 
whiskErr != nil {
                 return whiskErr
         }
 
@@ -93,11 +93,11 @@ var actionUpdateCmd = &cobra.Command{
             1,
             2,
             "Action update",
-            wski18n.T("An action name is required. An action is optional.")); 
whiskErr != nil {
+            wski18n.T("An action name is required. A code artifact is 
optional.")); whiskErr != nil {
                 return whiskErr
         }
 
-        if action, err = parseAction(cmd, args, false); err != nil {
+        if action, err = parseAction(cmd, args, true); err != nil {
             return actionParseError(cmd, args, err)
         }
 
@@ -319,7 +319,6 @@ var actionListCmd = &cobra.Command{
 
 func parseAction(cmd *cobra.Command, args []string, update bool) 
(*whisk.Action, error) {
     var err error
-    var artifact string
     var existingAction *whisk.Action
     var paramArgs []string
     var annotArgs []string
@@ -332,10 +331,6 @@ func parseAction(cmd *cobra.Command, args []string, update 
bool) (*whisk.Action,
         return nil, parseQualifiedNameError(args[0], err)
     }
 
-    if len(args) == 2 {
-        artifact = args[1]
-    }
-
     client.Namespace = qualifiedName.namespace
     action := new(whisk.Action)
     action.Name = qualifiedName.entityName
@@ -385,11 +380,20 @@ func parseAction(cmd *cobra.Command, args []string, 
update bool) (*whisk.Action,
         action.Parameters = append(action.Parameters, 
existingAction.Parameters...)
         action.Annotations = append(action.Annotations, 
existingAction.Annotations...)
     } else if flags.action.sequence {
-        action.Exec = new(whisk.Exec)
-        action.Exec.Kind = "sequence"
-        action.Exec.Components = csvToQualifiedActions(artifact)
-    } else if len(artifact) > 0 {
-        action.Exec, err = getExec(args[1], flags.action.kind, 
flags.action.docker, flags.action.main)
+        if len(args) == 2 {
+            action.Exec = new(whisk.Exec)
+            action.Exec.Kind = "sequence"
+            action.Exec.Components = csvToQualifiedActions(args[1])
+        } else {
+            return nil, noArtifactError()
+        }
+    } else if len(args) > 1 || len(flags.action.docker) > 0 {
+        action.Exec, err = getExec(args, flags.action)
+        if err != nil {
+            return nil, err
+        }
+    } else if !update {
+        return nil, noArtifactError()
     }
 
     if cmd.LocalFlags().Changed(WEB_FLAG) {
@@ -401,39 +405,48 @@ func parseAction(cmd *cobra.Command, args []string, 
update bool) (*whisk.Action,
     return action, err
 }
 
-func getExec(artifact string, kind string, isDocker bool, mainEntry string) 
(*whisk.Exec, error) {
+func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
     var err error
     var code string
     var exec *whisk.Exec
 
-    ext := filepath.Ext(artifact)
     exec = new(whisk.Exec)
+    kind := params.kind
+    isNative := params.native
+    docker := params.docker
+    mainEntry := params.main
+    ext := ""
 
-    if !isDocker || ext == ".zip" {
+    if len(args) == 2 {
+        artifact := args[1]
+        ext = filepath.Ext(artifact)
         code, err = readFile(artifact)
 
+        if err != nil {
+            whisk.Debug(whisk.DbgError, "readFile(%s) error: %s\n", artifact, 
err)
+            return nil, err
+        }
+
         if ext == ".zip" || ext == ".jar" {
             // Base64 encode the file
             code = base64.StdEncoding.EncodeToString([]byte(code))
-            exec.Code = &code
-        } else {
-            exec.Code = &code
         }
 
-        if err != nil {
-            whisk.Debug(whisk.DbgError, "readFile(%s) error: %s\n", artifact, 
err)
-            return nil, err
-        }
+        exec.Code = &code
+    } else if len(args) == 1 && len(docker) == 0 {
+        return nil, noArtifactError()
+    } else if len(args) > 1 {
+        return nil, noArtifactError()
     }
 
     if len(kind) > 0 {
         exec.Kind = kind
-    } else if isDocker {
+    } else if len(docker) > 0 || isNative {
         exec.Kind = "blackbox"
-        if ext != ".zip" {
-            exec.Image = artifact
-        } else {
+        if isNative {
             exec.Image = "openwhisk/dockerskeleton"
+        } else {
+            exec.Image = docker
         }
     } else if ext == ".swift" {
         exec.Kind = "swift:default"
@@ -572,7 +585,7 @@ func nestedError(errorMessage string, err error) (error) {
 func nonNestedError(errorMessage string) (error) {
     return whisk.MakeWskError(
         errors.New(errorMessage),
-        whisk.EXITCODE_ERR_GENERAL,
+        whisk.EXITCODE_ERR_USAGE,
         whisk.DISPLAY_MSG,
         whisk.DISPLAY_USAGE)
 }
@@ -581,9 +594,9 @@ func actionParseError(cmd *cobra.Command, args []string, 
err error) (error) {
     whisk.Debug(whisk.DbgError, "parseAction(%s, %s) error: %s\n", cmd, args, 
err)
 
     errMsg := wski18n.T(
-        "Unable to parse action command arguments: {{.err}}",
+        "Invalid argument(s). {{.required}}",
         map[string]interface{}{
-            "err": err,
+            "required": err,
         })
 
     return nestedError(errMsg, err)
@@ -724,6 +737,12 @@ func zipKindError() (error) {
     return nonNestedError(errMsg)
 }
 
+func noArtifactError() (error) {
+    errMsg := wski18n.T("An action name and code artifact are required.")
+
+    return nonNestedError(errMsg)
+}
+
 func extensionError(extension string) (error) {
     errMsg := wski18n.T(
         "'{{.name}}' is not a supported action runtime",
@@ -873,7 +892,8 @@ func isWebAction(client *whisk.Client, qname QualifiedName) 
error {
 }
 
 func init() {
-    actionCreateCmd.Flags().BoolVar(&flags.action.docker, "docker", false, 
wski18n.T("treat ACTION as docker image path on dockerhub"))
+    actionCreateCmd.Flags().BoolVar(&flags.action.native, "native", false, 
wski18n.T("treat ACTION as native action (zip file provides a compatible 
executable to run)"))
+    actionCreateCmd.Flags().StringVar(&flags.action.docker, "docker", "", 
wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
     actionCreateCmd.Flags().BoolVar(&flags.action.copy, "copy", false, 
wski18n.T("treat ACTION as the name of an existing action"))
     actionCreateCmd.Flags().BoolVar(&flags.action.sequence, "sequence", false, 
wski18n.T("treat ACTION as comma separated sequence of actions to invoke"))
     actionCreateCmd.Flags().StringVar(&flags.action.kind, "kind", "", 
wski18n.T("the `KIND` of the action runtime (example: swift:default, 
nodejs:default)"))
@@ -887,7 +907,8 @@ func init() {
     actionCreateCmd.Flags().StringVarP(&flags.common.paramFile, "param-file", 
"P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
     actionCreateCmd.Flags().StringVar(&flags.action.web, "web", "", 
wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a 
standard action; yes | true = web action, raw = raw HTTP web action, no | false 
= standard action"))
 
-    actionUpdateCmd.Flags().BoolVar(&flags.action.docker, "docker", false, 
wski18n.T("treat ACTION as docker image path on dockerhub"))
+    actionUpdateCmd.Flags().BoolVar(&flags.action.native, "native", false, 
wski18n.T("treat ACTION as native action (zip file provides a compatible 
executable to run)"))
+    actionUpdateCmd.Flags().StringVar(&flags.action.docker, "docker", "", 
wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
     actionUpdateCmd.Flags().BoolVar(&flags.action.copy, "copy", false, 
wski18n.T("treat ACTION as the name of an existing action"))
     actionUpdateCmd.Flags().BoolVar(&flags.action.sequence, "sequence", false, 
wski18n.T("treat ACTION as comma separated sequence of actions to invoke"))
     actionUpdateCmd.Flags().StringVar(&flags.action.kind, "kind", "", 
wski18n.T("the `KIND` of the action runtime (example: swift:default, 
nodejs:default)"))
diff --git a/tools/cli/go-whisk-cli/commands/flags.go 
b/tools/cli/go-whisk-cli/commands/flags.go
index 2af878d..252e0ab 100644
--- a/tools/cli/go-whisk-cli/commands/flags.go
+++ b/tools/cli/go-whisk-cli/commands/flags.go
@@ -31,7 +31,9 @@ const WEB_FLAG      = "web"
 
 var cliDebug = os.Getenv("WSK_CLI_DEBUG")  // Useful for tracing init() code
 
-var flags struct {
+var flags Flags
+
+type Flags struct {
 
     global struct {
         verbose     bool
@@ -48,10 +50,10 @@ var flags struct {
         annotFile   string
         param       []string
         paramFile   string
-        shared      string // AKA "public" or "publish"
-        skip        int  // skip first N records
-        limit       int  // return max N records
-        full        bool // return full records (docs=true for client request)
+        shared      string  // AKA "public" or "publish"
+        skip        int     // skip first N records
+        limit       int     // return max N records
+        full        bool    // return full records (docs=true for client 
request)
         summary     bool
         feed        string  // name of feed
         detail      bool
@@ -73,19 +75,7 @@ var flags struct {
         namespaceSet    string
     }
 
-    action struct {
-        docker      bool
-        copy        bool
-        pipe        bool
-        web         string
-        sequence    bool
-        timeout     int
-        memory      int
-        logsize     int
-        result      bool
-        kind        string
-        main        string
-    }
+    action ActionFlags
 
     activation struct {
         action          string // retrieve results for this action
@@ -122,6 +112,21 @@ var flags struct {
     }
 }
 
+
+type ActionFlags struct {
+    docker      string
+    native      bool
+    copy        bool
+    web         string
+    sequence    bool
+    timeout     int
+    memory      int
+    logsize     int
+    result      bool
+    kind        string
+    main        string
+}
+
 func IsVerbose() bool {
     return flags.global.verbose || IsDebug()
 }
diff --git a/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json 
b/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json
index e173b42..7a9b778 100644
--- a/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json
+++ b/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json
@@ -688,10 +688,6 @@
     "translation": "Arguments must be comma separated, and must be quoted if 
they contain spaces."
   },
   {
-    "id": "Invalid arguments: {{.err}}",
-    "translation": "Invalid arguments: {{.err}}"
-  },
-  {
     "id": "The argument `{{.arg}}` is invalid: {{.err}}",
     "translation": "The argument `{{.arg}}` is invalid: {{.err}}"
   },
@@ -872,8 +868,12 @@
     "translation": "Java actions require --main to specify the fully-qualified 
name of the main class"
   },
   {
-    "id": "treat ACTION as docker image path on dockerhub",
-    "translation": "treat ACTION as docker image path on dockerhub"
+    "id": "treat ACTION as native action (zip file provides a compatible 
executable to run)",
+    "translation": "treat ACTION as native action (zip file provides a 
compatible executable to run)"
+  },
+  {
+    "id": "use provided docker image (a path on DockerHub) to run the action",
+    "translation": "use provided docker image (a path on DockerHub) to run the 
action"
   },
   {
     "id": "treat ACTION as the name of an existing action",
@@ -1048,16 +1048,16 @@
     "translation": "The annotation arguments are invalid: {{.err}}"
   },
   {
-    "id": "An action name and action are required.",
-    "translation": "An action name and action are required."
+    "id": "An action name and code artifact are required.",
+    "translation": "An action name and code artifact are required."
   },
   {
     "id": "An action name is required.",
     "translation": "An action name is required."
   },
   {
-    "id": "An action name is required. An action is optional.",
-    "translation": "An action name is required. An action is optional."
+    "id": "An action name is required. A code artifact is optional.",
+    "translation": "An action name is required. A code artifact is optional."
   },
   {
     "id": "An activation ID is required.",

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to