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

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


The following commit(s) were added to refs/heads/master by this push:
     new e6daeea  Extend export to support project with dependencies (#828)
e6daeea is described below

commit e6daeeafae8339a8e4a3dd9ecb28bf5db0a576a2
Author: kpavel <[email protected]>
AuthorDate: Thu Mar 29 00:24:40 2018 +0300

    Extend export to support project with dependencies (#828)
    
    * Resolves #730
    
    - Provides support to export projects with dependencies
    - Optimizes rule export (leveraging added rule annotations)
    - Adds MANAGED annotation to dependencies in OW package bindings
    
    * bug fix
    
    * Added integration tests for export
    
    * bug fix
    
    * bug fix
    
    * added undeployments to export test case
    
    * minor bug fixes
    
    * change export attribute ProjectPath to ProjectName
---
 cmd/export.go                                   | 149 +++++++++++++++---------
 parsers/manifest_parser.go                      |   3 +-
 parsers/manifest_parser_test.go                 |  11 +-
 parsers/yamlparser.go                           |   7 ++
 tests/src/integration/common/wskdeploy.go       |  19 ++-
 tests/src/integration/export/export_test.go     |  72 ++++++++++++
 tests/src/integration/export/manifest_ext.yaml  |  35 ++++++
 tests/src/integration/export/manifest_lib1.yaml |  35 ++++++
 tests/src/integration/export/manifest_lib2.yaml |  35 ++++++
 tests/src/integration/export/src/greeting.js    |  11 ++
 utils/managedannotations.go                     |   3 +-
 wski18n/i18n_ids.go                             |   1 +
 12 files changed, 313 insertions(+), 68 deletions(-)

diff --git a/cmd/export.go b/cmd/export.go
index 437fb4f..3585da5 100644
--- a/cmd/export.go
+++ b/cmd/export.go
@@ -44,18 +44,7 @@ var exportCmd = &cobra.Command{
 
 var config *whisk.Config
 
-func ExportRule(wskRule whisk.Rule, pkgName string, maniyaml *parsers.YAML) {
-       if maniyaml.Packages[pkgName].Rules == nil {
-               pkg := maniyaml.Packages[pkgName]
-               pkg.Rules = make(map[string]parsers.Rule)
-               maniyaml.Packages[pkgName] = pkg
-       }
-
-       // export rule to manifest
-       maniyaml.Packages[pkgName].Rules[wskRule.Name] = 
*maniyaml.ComposeParsersRule(wskRule)
-}
-
-func ExportAction(actionName string, packageName string, maniyaml 
*parsers.YAML) error {
+func ExportAction(actionName string, packageName string, maniyaml 
*parsers.YAML, targetManifest string) error {
 
        pkg := maniyaml.Packages[packageName]
        if pkg.Actions == nil {
@@ -71,7 +60,7 @@ func ExportAction(actionName string, packageName string, 
maniyaml *parsers.YAML)
                seq := new(parsers.Sequence)
                for _, component := range wskAction.Exec.Components {
                        // must ommit namespace from seq component name
-                       ExportAction(strings.SplitN(component, "/", 3)[2], 
packageName, maniyaml)
+                       ExportAction(strings.SplitN(component, "/", 3)[2], 
packageName, maniyaml, targetManifest)
                        slices := strings.Split(component, "/")
 
                        // save in the seq list only action names
@@ -90,7 +79,7 @@ func ExportAction(actionName string, packageName string, 
maniyaml *parsers.YAML)
                pkg.Sequences[wskAction.Name] = *seq
        } else {
                parsedAction := *maniyaml.ComposeParsersAction(*wskAction)
-               manifestDir := filepath.Dir(utils.Flags.ManifestPath)
+               manifestDir := filepath.Dir(targetManifest)
 
                // store function file under action package name subdirectory 
in the specified manifest folder
                functionDir := filepath.Join(manifestDir, packageName)
@@ -111,24 +100,18 @@ func ExportAction(actionName string, packageName string, 
maniyaml *parsers.YAML)
        return nil
 }
 
-func ExportCmdImp(cmd *cobra.Command, args []string) error {
-
-       projectName := utils.Flags.ProjectPath
+func exportProject(projectName string, targetManifest string) error {
        maniyaml := &parsers.YAML{}
        maniyaml.Project.Name = projectName
 
-       config, _ = deployers.NewWhiskConfig(wskpropsPath, 
utils.Flags.DeploymentPath, utils.Flags.ManifestPath)
-       client, _ = deployers.CreateNewClient(config)
-
-       // Init supported runtimes and action files extensions maps
-       setSupportedRuntimes(config.Host)
-
        // Get the list of packages in your namespace
        packages, _, err := client.Packages.List(&whisk.PackageListOptions{})
        if err != nil {
                return err
        }
 
+       var bindings = make(map[string]whisk.Binding)
+
        // iterate over each package to find managed annotations
        // check if "managed" annotation is attached to a package
        // add to export when managed project name matches with the
@@ -141,6 +124,12 @@ func ExportCmdImp(cmd *cobra.Command, args []string) error 
{
                        // we have found a package which is part of the current 
project
                        if pa[utils.OW_PROJECT_NAME] == projectName {
 
+                               // check if the package is dependency
+                               if pkg.Annotations.GetValue(wski18n.BINDING) != 
nil {
+                                       bindings[pkg.Name] = *pkg.Binding
+                                       continue
+                               }
+
                                if maniyaml.Packages == nil {
                                        maniyaml.Packages = 
make(map[string]parsers.Package)
                                }
@@ -172,7 +161,7 @@ func ExportCmdImp(cmd *cobra.Command, args []string) error {
                                                if aa[utils.OW_PROJECT_NAME] == 
projectName {
                                                        actionName := 
strings.Join([]string{pkg.Name, action.Name}, "/")
                                                        // export action to 
file system
-                                                       err = 
ExportAction(actionName, pkg.Name, maniyaml)
+                                                       err = 
ExportAction(actionName, pkg.Name, maniyaml, targetManifest)
                                                        if err != nil {
                                                                return err
                                                        }
@@ -220,49 +209,101 @@ func ExportCmdImp(cmd *cobra.Command, args []string) 
error {
                return err
        }
 
-       // TODO: can be simplifyed once OW permits to add annotation to rules
-       // iterate over the list of rules to determine whether any of them is 
part of
-       // managed trigger -> action set for specified managed project. if yes, 
add to manifest
+       // iterate over the list of rules to determine whether any of them is 
part of the manage dproject
        for _, rule := range rules {
                // get rule from OW
                wskRule, _, _ := client.Rules.Get(rule.Name)
-               ruleAction := 
wskRule.Action.(map[string]interface{})["name"].(string)
-               ruleTrigger := 
wskRule.Trigger.(map[string]interface{})["name"].(string)
-
-               // can be simplified once rules moved to top level next to 
triggers
-               for pkgName := range maniyaml.Packages {
-                       if maniyaml.Packages[pkgName].Namespace == 
wskRule.Namespace {
-                               // iterate over all managed triggers in manifest
-                               for _, trigger := range 
maniyaml.Packages[pkgName].Triggers {
-                                       // check that managed trigger equals to 
rule trigger
-                                       if ruleTrigger == trigger.Name && 
trigger.Namespace == wskRule.Namespace {
-                                               // check that there a managed 
action (or sequence action) equals to rule action
-                                               for _, action := range 
maniyaml.Packages[pkgName].Actions {
-                                                       if action.Name == 
ruleAction {
-                                                               // export rule 
to manifest
-                                                               
ExportRule(*wskRule, pkgName, maniyaml)
-                                                       }
-                                               }
+               // rule has attached managed annotation
+               if a := wskRule.Annotations.GetValue(utils.MANAGED); a != nil {
+                       // decode the JSON blob and retrieve __OW_PROJECT_NAME
+                       ta := a.(map[string]interface{})
+                       if ta[utils.OW_PROJECT_NAME] == projectName {
 
-                                               // check that there a managed 
sequence action with name matching the rule action
-                                               for name := range 
maniyaml.Packages[pkgName].Sequences {
-                                                       if name == ruleAction {
-                                                               // export rule 
to manifest
-                                                               
ExportRule(*wskRule, pkgName, maniyaml)
-                                                       }
+                               for pkgName := range maniyaml.Packages {
+                                       if maniyaml.Packages[pkgName].Namespace 
== wskRule.Namespace {
+                                               if 
maniyaml.Packages[pkgName].Rules == nil {
+                                                       pkg := 
maniyaml.Packages[pkgName]
+                                                       pkg.Rules = 
make(map[string]parsers.Rule)
+                                                       
maniyaml.Packages[pkgName] = pkg
                                                }
+
+                                               // export rule to manifest
+                                               
maniyaml.Packages[pkgName].Rules[wskRule.Name] = 
*maniyaml.ComposeParsersRule(*wskRule)
                                        }
                                }
                        }
                }
+
+       }
+
+       // adding dependencies to the first package
+       for pkgName := range maniyaml.Packages {
+               for bPkg, binding := range bindings {
+                       if maniyaml.Packages[pkgName].Dependencies == nil {
+                               pkg := maniyaml.Packages[pkgName]
+                               pkg.Dependencies = 
make(map[string]parsers.Dependency)
+                               maniyaml.Packages[pkgName] = pkg
+                       }
+                       maniyaml.Packages[pkgName].Dependencies[bPkg] = 
*maniyaml.ComposeParsersDependency(binding)
+               }
+
+               break
+       }
+
+       // find exported manifest parent directory
+       manifestDir := filepath.Dir(utils.Flags.ManifestPath)
+       os.MkdirAll(manifestDir, os.ModePerm)
+
+       // export manifest to file
+       parsers.Write(maniyaml, targetManifest)
+       fmt.Println("Manifest exported to: " + targetManifest)
+
+       // create dependencies directory if not exists
+       depDir := filepath.Join(manifestDir, "dependencies")
+
+       if len(bindings) > 0 {
+               fmt.Println("Exporting project dependencies to " + depDir)
        }
 
-       parsers.Write(maniyaml, utils.Flags.ManifestPath)
-       fmt.Println("Manifest exported to: " + utils.Flags.ManifestPath)
+       // now export dependencies to their own manifests
+       for _, binding := range bindings {
+               pkg, _, err := client.Packages.Get(binding.Name)
+               if err != nil {
+                       return err
+               }
+
+               if a := pkg.Annotations.GetValue(utils.MANAGED); a != nil {
+                       // decode the JSON blob and retrieve __OW_PROJECT_NAME
+                       pa := a.(map[string]interface{})
+
+                       os.MkdirAll(depDir, os.ModePerm)
+                       depManifestPath := filepath.Join(depDir, 
pa[utils.OW_PROJECT_NAME].(string)+".yaml")
+
+                       // export the whole project as dependency
+                       err := 
exportProject(pa[utils.OW_PROJECT_NAME].(string), depManifestPath)
+                       if err != nil {
+                               return err
+                       }
+               } else {
+                       // showing warning to notify user that exported 
manifest dependent on unmanaged library which can't be exported
+                       fmt.Println("Warning! Dependency package " + 
binding.Name + " currently unmanaged by any project. Unable to export this 
package")
+               }
+       }
 
        return nil
 }
 
+func ExportCmdImp(cmd *cobra.Command, args []string) error {
+
+       config, _ = deployers.NewWhiskConfig(wskpropsPath, 
utils.Flags.DeploymentPath, utils.Flags.ManifestPath)
+       client, _ = deployers.CreateNewClient(config)
+
+       // Init supported runtimes and action files extensions maps
+       setSupportedRuntimes(config.Host)
+
+       return exportProject(utils.Flags.ProjectName, utils.Flags.ManifestPath)
+}
+
 const (
        JAVA_EXT = ".jar"
        ZIP_EXT  = ".zip"
@@ -310,10 +351,6 @@ func saveCode(action whisk.Action, directory string) 
(string, error) {
 
        path := filepath.Join(directory, filename)
 
-       if utils.FileExists(path) {
-               return "", wskderrors.NewFileReadError(path, 
wski18n.T(wski18n.ID_ERR_FILE_ALREADY_EXISTS))
-       }
-
        if err := utils.WriteFile(path, code); err != nil {
                return "", err
        }
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index 88f8d9f..9cfa673 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -27,13 +27,14 @@ import (
 
        "gopkg.in/yaml.v2"
 
+       "path/filepath"
+
        "github.com/apache/incubator-openwhisk-client-go/whisk"
        "github.com/apache/incubator-openwhisk-wskdeploy/utils"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
        "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
-       "path/filepath"
 )
 
 const (
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index f96ebc1..6c64492 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -21,11 +21,6 @@ package parsers
 
 import (
        "fmt"
-       "github.com/apache/incubator-openwhisk-client-go/whisk"
-       "github.com/apache/incubator-openwhisk-wskdeploy/utils"
-       "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
-       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
-       "github.com/stretchr/testify/assert"
        "io/ioutil"
        "os"
        "path/filepath"
@@ -33,6 +28,12 @@ import (
        "strconv"
        "strings"
        "testing"
+
+       "github.com/apache/incubator-openwhisk-client-go/whisk"
+       "github.com/apache/incubator-openwhisk-wskdeploy/utils"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
+       "github.com/stretchr/testify/assert"
 )
 
 const (
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index c136dfe..c65896f 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -416,6 +416,13 @@ func (yaml *YAML) ComposeParsersTrigger(wsktrg 
whisk.Trigger) *Trigger {
        return trigger
 }
 
+func (yaml *YAML) ComposeParsersDependency(binding whisk.Binding) *Dependency {
+       dependency := new(Dependency)
+       dependency.Location = "/" + binding.Namespace + "/" + binding.Name
+
+       return dependency
+}
+
 func (yaml *YAML) ComposeParsersRule(wskrule whisk.Rule) *Rule {
        rule := new(Rule)
        rule.Name = wskrule.Name
diff --git a/tests/src/integration/common/wskdeploy.go 
b/tests/src/integration/common/wskdeploy.go
index 17755a9..abcbc3a 100644
--- a/tests/src/integration/common/wskdeploy.go
+++ b/tests/src/integration/common/wskdeploy.go
@@ -21,17 +21,18 @@ import (
        "bytes"
        "errors"
        "fmt"
+       "os"
+       "os/exec"
+       "path"
+       "path/filepath"
+       "strings"
+
        "github.com/apache/incubator-openwhisk-client-go/whisk"
        "github.com/apache/incubator-openwhisk-wskdeploy/deployers"
        "github.com/apache/incubator-openwhisk-wskdeploy/utils"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
        "github.com/fatih/color"
        "github.com/mattn/go-colorable"
-       "os"
-       "os/exec"
-       "path"
-       "path/filepath"
-       "strings"
 )
 
 const (
@@ -166,6 +167,10 @@ func (wskdeploy *Wskdeploy) 
UndeployManifestPathOnly(manifestpath string) (strin
        return wskdeploy.RunCommand("undeploy", "-m", manifestpath)
 }
 
+func (Wskdeploy *Wskdeploy) ManagedDeploymentOnlyManifest(manifestPath string) 
(string, error) {
+       return Wskdeploy.RunCommand("sync", "-m", manifestPath)
+}
+
 func (Wskdeploy *Wskdeploy) ManagedDeployment(manifestPath string, 
deploymentPath string) (string, error) {
        return Wskdeploy.RunCommand("sync", "-m", manifestPath, "-d", 
deploymentPath)
 }
@@ -174,6 +179,10 @@ func (Wskdeploy *Wskdeploy) 
HeadlessManagedDeployment(manifestPath string, deplo
        return Wskdeploy.RunCommand("sync", "-m", manifestPath, "-d", 
deploymentPath, "--projectname", name)
 }
 
+func (wskdeploy *Wskdeploy) ExportProject(projectName string, 
targetManifestPath string) (string, error) {
+       return wskdeploy.RunCommand("export", "-m", targetManifestPath, 
"--projectname", projectName)
+}
+
 // This method is only for testing
 // This method will mock a construction of deployment plan, creating all the 
memory objects
 // This method CANNOT be used for real deployment!
diff --git a/tests/src/integration/export/export_test.go 
b/tests/src/integration/export/export_test.go
new file mode 100644
index 0000000..2f3e530
--- /dev/null
+++ b/tests/src/integration/export/export_test.go
@@ -0,0 +1,72 @@
+// +build integration
+
+/*
+ * 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 tests
+
+import (
+       "os"
+       "testing"
+
+       
"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestExport(t *testing.T) {
+       projectName := "EXT_PROJECT"
+       wskdeploy := common.NewWskdeploy()
+
+       _, err := wskdeploy.ManagedDeploymentOnlyManifest(manifestLib1Path)
+       assert.Equal(t, nil, err, "Failed to deploy the lib1 manifest file.")
+
+       _, err = wskdeploy.ManagedDeploymentOnlyManifest(manifestLib2Path)
+       assert.Equal(t, nil, err, "Failed to deploy the lib2 manifest file.")
+
+       _, err = wskdeploy.ManagedDeploymentOnlyManifest(manifestExtPath)
+       assert.Equal(t, nil, err, "Failed to deploy the ext manifest file.")
+
+       _, err = wskdeploy.ExportProject(projectName, targetManifestPath)
+       assert.Equal(t, nil, err, "Failed to export project.")
+
+       _, err = os.Stat(targetManifestPath)
+       assert.Equal(t, nil, err, "Missing exported manifest file")
+
+       _, err = os.Stat(targetManifestFolder + "dependencies/lib1.yaml")
+       assert.Equal(t, nil, err, "Missing exported dependencies lib1 manifest")
+
+       _, err = os.Stat(targetManifestFolder + 
"dependencies/lib1_package/lib1_greeting1.js")
+       assert.Equal(t, nil, err, "Missing exported dependencies lib1 
resources")
+
+       _, err = wskdeploy.UndeployManifestPathOnly(manifestExtPath)
+       assert.Equal(t, nil, err, "Failed to undeploy the ext.")
+
+       _, err = wskdeploy.UndeployManifestPathOnly(manifestLib2Path)
+       assert.Equal(t, nil, err, "Failed to undeploy the lib1.")
+
+       _, err = wskdeploy.UndeployManifestPathOnly(manifestLib1Path)
+       assert.Equal(t, nil, err, "Failed to undeploy the lib2.")
+}
+
+var (
+       manifestLib1Path = os.Getenv("GOPATH") + 
"/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/export/manifest_lib1.yaml"
+       manifestLib2Path = os.Getenv("GOPATH") + 
"/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/export/manifest_lib2.yaml"
+       manifestExtPath  = os.Getenv("GOPATH") + 
"/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/export/manifest_ext.yaml"
+
+       targetManifestFolder = os.Getenv("GOPATH") + 
"/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/export/tmp/"
+       targetManifestPath   = targetManifestFolder + "manifest.yaml"
+)
diff --git a/tests/src/integration/export/manifest_ext.yaml 
b/tests/src/integration/export/manifest_ext.yaml
new file mode 100644
index 0000000..b0dcfb8
--- /dev/null
+++ b/tests/src/integration/export/manifest_ext.yaml
@@ -0,0 +1,35 @@
+#
+# 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:
+  name: EXT_PROJECT
+packages:
+  EXT_PACKAGE:
+      dependencies:
+        ext_lib1_bind:
+          location: /_/lib1_package
+        ext_lib2_bind:
+          location: /_/lib2_package
+      triggers:
+        trigger_ext1:
+        trigger_ext2:
+      rules:
+        rule_ext1:
+          trigger: trigger_ext1
+          action: ext_lib1_bind/lib1_greeting1
+        rule_ext2:
+          trigger: trigger_ext2
+          action: ext_lib2_bind/lib2_greeting1
diff --git a/tests/src/integration/export/manifest_lib1.yaml 
b/tests/src/integration/export/manifest_lib1.yaml
new file mode 100644
index 0000000..446d90b
--- /dev/null
+++ b/tests/src/integration/export/manifest_lib1.yaml
@@ -0,0 +1,35 @@
+#
+# 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:
+  name: lib1
+packages:
+  lib1_package:
+      version: 1.0
+      license: Apache-2.0
+      actions:
+        lib1_greeting1:
+          version: 1.0
+          function: src/greeting.js
+          runtime: nodejs:6
+        lib1_greeting2:
+          version: 1.0
+          function: src/greeting.js
+          runtime: nodejs:6
+        lib1_greeting3:
+          version: 1.0
+          function: src/greeting.js
+          runtime: nodejs:6
diff --git a/tests/src/integration/export/manifest_lib2.yaml 
b/tests/src/integration/export/manifest_lib2.yaml
new file mode 100644
index 0000000..e9dab41
--- /dev/null
+++ b/tests/src/integration/export/manifest_lib2.yaml
@@ -0,0 +1,35 @@
+#
+# 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:
+  name: lib2
+packages:
+  lib2_package:
+      version: 1.0
+      license: Apache-2.0
+      actions:
+        lib2_greeting1:
+          version: 1.0
+          function: src/greeting.js
+          runtime: nodejs:6
+        lib2_greeting2:
+          version: 1.0
+          function: src/greeting.js
+          runtime: nodejs:6
+        lib2_greeting3:
+          version: 1.0
+          function: src/greeting.js
+          runtime: nodejs:6
diff --git a/tests/src/integration/export/src/greeting.js 
b/tests/src/integration/export/src/greeting.js
new file mode 100644
index 0000000..eaa6834
--- /dev/null
+++ b/tests/src/integration/export/src/greeting.js
@@ -0,0 +1,11 @@
+/**
+ * Return a simple greeting message for someone.
+ *
+ * @param name A person's name.
+ * @param place Where the person is from.
+ */
+function main(params) {
+    var name = params.name || params.payload || 'stranger';
+    var place = params.place || 'somewhere';
+    return {payload:  'Hello, ' + name + ' from ' + place + '!'};
+}
diff --git a/utils/managedannotations.go b/utils/managedannotations.go
index 858b2b5..4023c10 100644
--- a/utils/managedannotations.go
+++ b/utils/managedannotations.go
@@ -21,8 +21,9 @@ import (
        "crypto/sha1"
        "encoding/json"
        "fmt"
-       "github.com/apache/incubator-openwhisk-client-go/whisk"
        "os"
+
+       "github.com/apache/incubator-openwhisk-client-go/whisk"
 )
 
 /*
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index 25ceb06..3677f90 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -41,6 +41,7 @@ const (
        CMD_UNDEPLOY       = "undeploy"
        CMD_SYNC           = "sync"
        TRIGGERS           = "Triggers"
+       BINDING            = "binding"
 )
 
 // DO NOT TRANSLATE

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

Reply via email to