You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2017/08/31 20:06:37 UTC

[incubator-openwhisk-wskdeploy] branch master updated: Add the error handling mechanism (#420)

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

mrutkowski 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 cb96d26  Add the error handling mechanism (#420)
cb96d26 is described below

commit cb96d262065b972d327b580502565677259b9152
Author: Vincent <sh...@us.ibm.com>
AuthorDate: Thu Aug 31 16:06:35 2017 -0400

    Add the error handling mechanism (#420)
    
    This PR makes the following changes:
    * Replace log with fmt, since wskdeploy is a client tool, which does not need to log any
    information.
    * In test cases, read the stardard output and the standard error separately. We need to
    parse the standard error to determine if the execution of the a command succeeds or not.
    
    Closes-Bug: #340 #417
---
 cmd/publish.go                                     |   7 +-
 cmd/root.go                                        | 104 ++--
 cmd/undeploy.go                                    |   6 +-
 deployers/deploymentreader.go                      |   5 +-
 deployers/servicedeployer.go                       |  59 ++-
 deployers/whiskclient.go                           |   9 +-
 parsers/deploy_parser.go                           |   7 +-
 parsers/manifest_parser.go                         |  11 +-
 tests/src/integration/common/wskdeploy.go          |  60 ++-
 .../src/integration/runtimetests/runtimes_test.go  |   2 -
 tests/src/integration/zipaction/zipaction_test.go  |   4 -
 utils/errorhandlers.go                             |  23 +-
 utils/fileoperations.go                            |   3 +-
 utils/misc.go                                      |  15 +-
 utils/{errorhandlers.go => wskdeployerror.go}      |  57 ++-
 wski18n/detection.go                               |  24 +-
 wski18n/i18n.go                                    | 152 +++---
 wski18n/i18n_resources.go                          | 530 ++++++++++-----------
 wski18n/resources/en_US.all.json                   |  17 +-
 19 files changed, 577 insertions(+), 518 deletions(-)

diff --git a/cmd/publish.go b/cmd/publish.go
index 9ae963a..c8bfa71 100644
--- a/cmd/publish.go
+++ b/cmd/publish.go
@@ -24,7 +24,6 @@ import (
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"github.com/spf13/cobra"
-	"log"
 	"net/http"
 	"net/url"
 	"os"
@@ -58,7 +57,7 @@ var publishCmd = &cobra.Command{
 					// TODO: send request to registry to check it exists.
 					break
 				}
-				log.Print("Malformed repository URL. Try again")
+				fmt.Print("Malformed repository URL. Try again")
 
 			}
 			configs["REGISTRY"] = registry
@@ -74,7 +73,7 @@ var publishCmd = &cobra.Command{
 			paths := strings.Split(repoURL, "/")
 			l := len(paths)
 			if l < 2 {
-				log.Print("Fatal error: malformed repository URL in manifest file :" + repoURL)
+				fmt.Print("Fatal error: malformed repository URL in manifest file :" + repoURL)
 				return
 			}
 
@@ -89,7 +88,7 @@ var publishCmd = &cobra.Command{
 			utils.Check(err)
 
 		} else {
-			log.Print("Fatal error: missing repository URL in manifest file.")
+			fmt.Print("Fatal error: missing repository URL in manifest file.")
 		}
 
 	},
diff --git a/cmd/root.go b/cmd/root.go
index e12fb46..abe1533 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -22,11 +22,10 @@ import (
 	"errors"
 	"fmt"
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
-	"github.com/apache/incubator-openwhisk-client-go/wski18n"
+	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/apache/incubator-openwhisk-wskdeploy/deployers"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"github.com/spf13/cobra"
-	"log"
 	"os"
 	"regexp"
 	"strings"
@@ -34,6 +33,8 @@ import (
 	"path/filepath"
 )
 
+var stderr = ""
+var stdout = ""
 var RootCmd = &cobra.Command{
 	Use:   "wskdeploy",
 	Short: "A tool set to help deploy your openwhisk packages in batch.",
@@ -44,11 +45,11 @@ wskdeploy without any commands or flags deploys openwhisk package in the current
       `,
 	// Uncomment the following line if your bare application
 	// has an action associated with it:
-	Run: RootCmdImp,
+	RunE: RootCmdImp,
 }
 
-func RootCmdImp(cmd *cobra.Command, args []string) {
-	Deploy()
+func RootCmdImp(cmd *cobra.Command, args []string) error{
+	return Deploy()
 }
 
 // Execute adds all child commands to the root command sets flags appropriately.
@@ -57,18 +58,14 @@ func Execute() {
 	if utils.Flags.WithinOpenWhisk {
 		err := substCmdArgs()
 		if err != nil {
-			utils.PrintOpenWhiskError(err.Error())
+			utils.PrintOpenWhiskError(err)
 			return
 		}
 	}
 
 	if err := RootCmd.Execute(); err != nil {
-		log.Println(err)
-		if utils.Flags.WithinOpenWhisk {
-			utils.PrintOpenWhiskError(err.Error())
-		} else {
-			os.Exit(-1)
-		}
+        utils.PrintOpenWhiskError(err)
+		os.Exit(-1)
 	} else {
 		if utils.Flags.WithinOpenWhisk {
 			fmt.Print(`{"deploy":"success"}`) // maybe return report of what has been deployed.
@@ -102,17 +99,9 @@ func init() {
 
 	cobra.OnInitialize(initConfig)
 
-	//Initialize the supported runtime infos.
-	op, err := utils.ParseOpenWhisk()
-	if err == nil {
-		utils.Rts = utils.ConvertToMap(op)
-	} else {
-		utils.Rts = utils.DefaultRts
-	}
 	// Here you will define your flags and configuration settings.
 	// Cobra supports Persistent Flags, which, if defined here,
 	// will be global for your application.
-
 	RootCmd.PersistentFlags().StringVar(&utils.Flags.CfgFile, "config", "", "config file (default is $HOME/.wskprops)")
 	// Cobra also supports local flags, which will only run
 	// when this action is called directly.
@@ -138,16 +127,28 @@ func initConfig() {
         _, err := whisk.ReadProps(utils.Flags.CfgFile)
         if err != nil {
             utils.Flags.CfgFile = defaultPath
-            log.Println("Invalid config file detected, so by bdefault it is set to " + utils.Flags.CfgFile)
+            fmt.Println("Invalid config file detected, so by bdefault it is set to " + utils.Flags.CfgFile)
         }
 	} else {
         utils.Flags.CfgFile = defaultPath
     }
 }
 
+func setSupportedRuntimes(apiHost string) {
+    op, error := utils.ParseOpenWhisk(apiHost)
+    if error == nil {
+        utils.Rts = utils.ConvertToMap(op)
+    } else {
+        utils.Rts = utils.DefaultRts
+    }
+}
+
 func Deploy() error {
 
 	whisk.SetVerbose(utils.Flags.Verbose)
+    // Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
+    // also set debug mode to true.
+    whisk.SetDebug(utils.Flags.Verbose)
 
 	projectPath, err := filepath.Abs(utils.Flags.ProjectPath)
 	utils.Check(err)
@@ -155,14 +156,21 @@ func Deploy() error {
 	if utils.Flags.ManifestPath == "" {
 		if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
-			log.Printf("Using %s for deployment \n", utils.Flags.ManifestPath)
+            stdout = wski18n.T("Using {{.manifestPath}} for deployment.\n",
+                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
-			log.Printf("Using %s for deployment", utils.Flags.ManifestPath)
+            stdout = wski18n.T("Using {{.manifestPath}} for deployment.\n",
+                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else {
-			log.Printf("Manifest file not found at path %s", projectPath)
-			return errors.New("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file")
+            stderr = wski18n.T("Manifest file not found at path {{.projectPath}}.\n",
+                map[string]interface{}{"projectPath": projectPath})
+            whisk.Debug(whisk.DbgError, stderr)
+            errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+                map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
+			return utils.NewInputYamlFileError(errString)
 		}
+        whisk.Debug(whisk.DbgInfo, stdout)
 	}
 
 	if utils.Flags.DeploymentPath == "" {
@@ -194,6 +202,9 @@ func Deploy() error {
 		deployer.Client = whiskClient
 		deployer.ClientConfig = clientConfig
 
+        // The auth, apihost and namespace have been chosen, so that we can check the supported runtimes here.
+        setSupportedRuntimes(clientConfig.Host)
+
 		err := deployer.ConstructDeploymentPlan()
 
 		if err != nil {
@@ -210,19 +221,20 @@ func Deploy() error {
 		}
 
 	} else {
-		if utils.Flags.WithinOpenWhisk {
-			utils.PrintOpenWhiskError(wski18n.T("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file"))
-		} else {
-			log.Println("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file")
-		}
-		return errors.New("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file")
+        errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+            map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
+        whisk.Debug(whisk.DbgError, errString)
+        return utils.NewInputYamlFileError(errString)
 	}
 
 }
 
 func Undeploy() error {
-	// TODO: Work your own magic here
+
 	whisk.SetVerbose(utils.Flags.Verbose)
+    // Verbose mode is the only mode for wskdeploy to turn on all the debug messages, so the currenty Verbose mode
+    // also set debug mode to true.
+    whisk.SetDebug(utils.Flags.Verbose)
 
 	projectPath, err := filepath.Abs(utils.Flags.ProjectPath)
 	utils.Check(err)
@@ -230,23 +242,30 @@ func Undeploy() error {
 	if utils.Flags.ManifestPath == "" {
 		if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYaml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYaml)
-			log.Printf("Using %s for undeployment \n", utils.Flags.ManifestPath)
+            stdout = wski18n.T("Using {{.manifestPath}} for undeployment.\n",
+                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else if _, err := os.Stat(path.Join(projectPath, utils.ManifestFileNameYml)); err == nil {
 			utils.Flags.ManifestPath = path.Join(projectPath, utils.ManifestFileNameYml)
-			log.Printf("Using %s for undeployment", utils.Flags.ManifestPath)
+            stdout = wski18n.T("Using {{.manifestPath}} for undeployment.\n",
+                map[string]interface{}{"manifestPath": utils.Flags.ManifestPath})
 		} else {
-			log.Printf("Manifest file not found at path %s", projectPath)
-			return errors.New("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file")
+            stderr = wski18n.T("Manifest file not found at path {{.projectPath}}.\n",
+                map[string]interface{}{"projectPath": projectPath})
+            whisk.Debug(whisk.DbgError, stderr)
+            errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+                map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
+            return utils.NewInputYamlFileError(errString)
 		}
+        whisk.Debug(whisk.DbgInfo, stdout)
 	}
 
 	if utils.Flags.DeploymentPath == "" {
 		if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYaml)); err == nil {
 			utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYaml)
-			log.Printf("Using %s for undeployment \n", utils.Flags.DeploymentPath)
+			fmt.Printf("Using %s for undeployment \n", utils.Flags.DeploymentPath)
 		} else if _, err := os.Stat(path.Join(projectPath, utils.DeploymentFileNameYml)); err == nil {
 			utils.Flags.DeploymentPath = path.Join(projectPath, utils.DeploymentFileNameYml)
-			log.Printf("Using %s for undeployment \n", utils.Flags.DeploymentPath)
+			fmt.Printf("Using %s for undeployment \n", utils.Flags.DeploymentPath)
 		}
 	}
 
@@ -264,6 +283,9 @@ func Undeploy() error {
 		deployer.Client = whiskClient
 		deployer.ClientConfig = clientConfig
 
+        // The auth, apihost and namespace have been chosen, so that we can check the supported runtimes here.
+        setSupportedRuntimes(clientConfig.Host)
+
 		verifiedPlan, err := deployer.ConstructUnDeploymentPlan()
 		err = deployer.UnDeploy(verifiedPlan)
 		if err != nil {
@@ -274,7 +296,9 @@ func Undeploy() error {
 		}
 
 	} else {
-		log.Println("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file")
-		return errors.New("missing "+utils.ManifestFileNameYaml+"/" +utils.ManifestFileNameYml+" file")
+        errString := wski18n.T("Missing {{.yaml}}/{{.yml}} file.\n",
+            map[string]interface{}{"yaml": utils.ManifestFileNameYaml , "yml":utils.ManifestFileNameYml})
+        whisk.Debug(whisk.DbgError, errString)
+        return utils.NewInputYamlFileError(errString)
 	}
 }
diff --git a/cmd/undeploy.go b/cmd/undeploy.go
index 0fcb1ac..379ac36 100644
--- a/cmd/undeploy.go
+++ b/cmd/undeploy.go
@@ -27,11 +27,11 @@ var undeployCmd = &cobra.Command{
 	Use:   "undeploy",
 	Short: "Undeploy assets from OpenWhisk",
 	Long:  `Undeploy removes deployed assets from the manifest and deployment files`,
-	Run:   UndeployCmdImp,
+	RunE:   UndeployCmdImp,
 }
 
-func UndeployCmdImp(cmd *cobra.Command, args []string) {
-	Undeploy()
+func UndeployCmdImp(cmd *cobra.Command, args []string) error {
+	return Undeploy()
 }
 
 func init() {
diff --git a/deployers/deploymentreader.go b/deployers/deploymentreader.go
index 42db43d..3864531 100644
--- a/deployers/deploymentreader.go
+++ b/deployers/deploymentreader.go
@@ -23,7 +23,6 @@ import (
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
-	"log"
 )
 
 type DeploymentReader struct {
@@ -69,7 +68,7 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() {
 	if reader.DeploymentDescriptor.Application.Packages == nil {
 		// a single package is specified in deployment YAML file with "package" key
 		packMap[reader.DeploymentDescriptor.Application.Package.Packagename] = reader.DeploymentDescriptor.Application.Package
-		log.Println("WARNING: The package YAML key in deployment file will soon be deprecated. Please use packages instead as described in specifications.")
+		fmt.Println("WARNING: The package YAML key in deployment file will soon be deprecated. Please use packages instead as described in specifications.")
 	} else {
 		for packName, depPacks := range reader.DeploymentDescriptor.Application.Packages {
 			depPacks.Packagename = packName
@@ -82,7 +81,7 @@ func (reader *DeploymentReader) bindPackageInputsAndAnnotations() {
 		serviceDeployPack := reader.serviceDeployer.Deployment.Packages[packName]
 
 		if serviceDeployPack == nil {
-			log.Println("WARNING: Package name in deployment file " + packName + " does not match with manifest file.")
+			fmt.Println("WARNING: Package name in deployment file " + packName + " does not match with manifest file.")
 			break
 		}
 
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index e3a1fc3..0caea7d 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -20,7 +20,6 @@ package deployers
 import (
 	"bufio"
 	"fmt"
-	"log"
 	"os"
 	"path"
 	"strings"
@@ -198,7 +197,7 @@ func (deployer *ServiceDeployer) Deploy() error {
 		if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") {
 			deployer.InteractiveChoice = true
 			if err := deployer.deployAssets(); err != nil {
-				log.Println("\nDeployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
+				fmt.Println("\nDeployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
 				return err
 			}
 
@@ -214,11 +213,11 @@ func (deployer *ServiceDeployer) Deploy() error {
 
 	// non-interactive
 	if err := deployer.deployAssets(); err != nil {
-		log.Println("\nDeployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
+		fmt.Println("\nDeployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
 		return err
 	}
 
-	log.Println("\nDeployment completed successfully.")
+	fmt.Println("\nDeployment completed successfully.")
 	return nil
 
 }
@@ -287,7 +286,7 @@ func (deployer *ServiceDeployer) DeployDependencies() error {
 				utils.Check(err)
 
 				if err := depServiceDeployer.deployAssets(); err != nil {
-					log.Println("\nDeployment of dependency " + depName + " did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
+					fmt.Println("\nDeployment of dependency " + depName + " did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
 					return err
 				} else {
 					fmt.Println("Done!")
@@ -363,36 +362,36 @@ func (deployer *ServiceDeployer) DeployApis() error {
 }
 
 func (deployer *ServiceDeployer) createBinding(packa *whisk.BindingPackage) {
-	log.Print("Deploying package binding " + packa.Name + " ... ")
+	fmt.Print("Deploying package binding " + packa.Name + " ... ")
 	_, _, err := deployer.Client.Packages.Insert(packa, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating package binding with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating package binding with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
-	log.Println("Done!")
+	fmt.Println("Done!")
 }
 
 func (deployer *ServiceDeployer) createPackage(packa *whisk.Package) {
-	log.Print("Deploying package " + packa.Name + " ... ")
+	fmt.Print("Deploying package " + packa.Name + " ... ")
 	_, _, err := deployer.Client.Packages.Insert(packa, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating package with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating package with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
-	log.Println("Done!")
+	fmt.Println("Done!")
 }
 
 func (deployer *ServiceDeployer) createTrigger(trigger *whisk.Trigger) {
 	_, _, err := deployer.Client.Triggers.Insert(trigger, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
 	fmt.Println("Done!")
 }
 
 func (deployer *ServiceDeployer) createFeedAction(trigger *whisk.Trigger, feedName string) {
-	log.Println("Deploying trigger feed " + trigger.Name + " ... ")
+	fmt.Println("Deploying trigger feed " + trigger.Name + " ... ")
 	// to hold and modify trigger parameters, not passed by ref?
 	params := make(map[string]interface{})
 
@@ -415,7 +414,7 @@ func (deployer *ServiceDeployer) createFeedAction(trigger *whisk.Trigger, feedNa
 	_, _, err := deployer.Client.Triggers.Insert(t, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	} else {
 
 		qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace)
@@ -429,7 +428,7 @@ func (deployer *ServiceDeployer) createFeedAction(trigger *whisk.Trigger, feedNa
 
 		if err != nil {
 			wskErr := err.(*whisk.WskError)
-			log.Printf("Got error creating trigger feed with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+			fmt.Printf("Got error creating trigger feed with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 		}
 	}
 	fmt.Println("Done!")
@@ -453,13 +452,13 @@ func (deployer *ServiceDeployer) createRule(rule *whisk.Rule) {
 	_, _, err := deployer.Client.Rules.Insert(rule, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
 
 	_, _, err = deployer.Client.Rules.SetState(rule.Name, "active")
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error activating rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error activating rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
 	fmt.Println("Done!")
 }
@@ -471,14 +470,14 @@ func (deployer *ServiceDeployer) createAction(pkgname string, action *whisk.Acti
 		// the action will be created under package with pattern 'packagename/actionname'
 		action.Name = strings.Join([]string{pkgname, action.Name}, "/")
 	}
-	log.Print("Deploying action " + action.Name + " ... ")
+	fmt.Print("Deploying action " + action.Name + " ... ")
 	_, _, err := deployer.Client.Actions.Insert(action, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating action with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating action with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 		return err
 	}
-	log.Println("Done!")
+	fmt.Println("Done!")
 	return nil
 }
 
@@ -487,9 +486,9 @@ func (deployer *ServiceDeployer) createApi(api *whisk.ApiCreateRequest) {
 	_, _, err := deployer.Client.Apis.Insert(api, nil, true)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error creating api with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error creating api with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
-	log.Println("Done!")
+	fmt.Println("Done!")
 }
 
 func (deployer *ServiceDeployer) UnDeploy(verifiedPlan *DeploymentApplication) error {
@@ -582,7 +581,7 @@ func (deployer *ServiceDeployer) UnDeployDependencies() error {
 				utils.Check(err)
 
 				if err := depServiceDeployer.unDeployAssets(plan); err != nil {
-					log.Println("\nUndeployment of dependency " + depName + " did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
+					fmt.Println("\nUndeployment of dependency " + depName + " did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
 					return err
 				} else {
 					fmt.Println("Done!")
@@ -655,7 +654,7 @@ func (deployer *ServiceDeployer) deletePackage(packa *whisk.Package) {
 	_, err := deployer.Client.Packages.Delete(packa.Name)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error deleteing package with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error deleteing package with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
 	fmt.Println("Done!")
 }
@@ -665,7 +664,7 @@ func (deployer *ServiceDeployer) deleteTrigger(trigger *whisk.Trigger) {
 	_, _, err := deployer.Client.Triggers.Delete(trigger.Name)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error deleting trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error deleting trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	}
 	fmt.Println("Done!")
 }
@@ -682,7 +681,7 @@ func (deployer *ServiceDeployer) deleteFeedAction(trigger *whisk.Trigger, feedNa
 	_, _, err := deployer.Client.Triggers.Delete(trigger.Name)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error deleting trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error deleting trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	} else {
 		parameters := make(map[string]interface{})
 		for _, keyVal := range params {
@@ -700,7 +699,7 @@ func (deployer *ServiceDeployer) deleteFeedAction(trigger *whisk.Trigger, feedNa
 
 		if err != nil {
 			wskErr := err.(*whisk.WskError)
-			log.Printf("Got error deleting trigger feed with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+			fmt.Printf("Got error deleting trigger feed with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 		}
 	}
 	fmt.Println("Done!")
@@ -712,14 +711,14 @@ func (deployer *ServiceDeployer) deleteRule(rule *whisk.Rule) {
 
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error deleting rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error deleting rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 	} else {
 
 		_, err = deployer.Client.Rules.Delete(rule.Name)
 
 		if err != nil {
 			wskErr := err.(*whisk.WskError)
-			log.Printf("Got error deleting rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+			fmt.Printf("Got error deleting rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 		}
 
 		fmt.Println("Done!")
@@ -738,7 +737,7 @@ func (deployer *ServiceDeployer) deleteAction(pkgname string, action *whisk.Acti
 	_, err := deployer.Client.Actions.Delete(action.Name)
 	if err != nil {
 		wskErr := err.(*whisk.WskError)
-		log.Printf("Got error deleting action with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
+		fmt.Printf("Got error deleting action with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
 		return err
 	}
 	fmt.Println("Done!")
diff --git a/deployers/whiskclient.go b/deployers/whiskclient.go
index 7bd7d08..d5d9da4 100644
--- a/deployers/whiskclient.go
+++ b/deployers/whiskclient.go
@@ -28,9 +28,8 @@ import (
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
 	"github.com/apache/incubator-openwhisk-wskdeploy/parsers"
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
-        "errors"
-        "log"
     "path"
+    "errors"
 )
 
 const (
@@ -172,9 +171,9 @@ func NewWhiskClient(proppath string, deploymentPath string, manifestPath string,
         utils.Check(err)
     }
 
-    log.Println("The URL is " + baseURL.String() + ", selected from " + apiHost.Source)
-    log.Println("The auth key is set, selected from " + credential.Source)
-    log.Println("The namespace is " + namespace.Value + ", selected from " + namespace.Source)
+    fmt.Println("The URL is " + baseURL.String() + ", selected from " + apiHost.Source)
+    fmt.Println("The auth key is set, selected from " + credential.Source)
+    fmt.Println("The namespace is " + namespace.Value + ", selected from " + namespace.Source)
     clientConfig = &whisk.Config{
         AuthToken: credential.Value, //Authtoken
         Namespace: namespace.Value,  //Namespace
diff --git a/parsers/deploy_parser.go b/parsers/deploy_parser.go
index 1978cd2..62a3292 100644
--- a/parsers/deploy_parser.go
+++ b/parsers/deploy_parser.go
@@ -18,16 +18,15 @@
 package parsers
 
 import (
-	"log"
-
 	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
 	"gopkg.in/yaml.v2"
+    "fmt"
 )
 
 func (dm *YAMLParser) UnmarshalDeployment(input []byte, deploy *DeploymentYAML) error {
 	err := yaml.Unmarshal(input, deploy)
 	if err != nil {
-		log.Printf("error happened during unmarshal :%v", err)
+		fmt.Printf("error happened during unmarshal :%v", err)
 		return err
 	}
 	return nil
@@ -36,7 +35,7 @@ func (dm *YAMLParser) UnmarshalDeployment(input []byte, deploy *DeploymentYAML)
 func (dm *YAMLParser) MarshalDeployment(deployment *DeploymentYAML) (output []byte, err error) {
 	data, err := yaml.Marshal(deployment)
 	if err != nil {
-		log.Printf("err happened during marshal :%v", err)
+		fmt.Printf("err happened during marshal :%v", err)
 		return nil, err
 	}
 	return data, nil
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index ca1ab13..9abfe49 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -20,7 +20,6 @@ package parsers
 import (
 	"errors"
 	"io/ioutil"
-	"log"
 	"os"
 	"path"
 	"reflect"
@@ -62,7 +61,7 @@ func Write(manifest *ManifestYAML, filename string) {
 func (dm *YAMLParser) Unmarshal(input []byte, manifest *ManifestYAML) error {
 	err := yaml.Unmarshal(input, manifest)
 	if err != nil {
-		log.Printf("error happened during unmarshal :%v", err)
+		fmt.Printf("error happened during unmarshal :%v", err)
 		return err
 	}
 	return nil
@@ -71,7 +70,7 @@ func (dm *YAMLParser) Unmarshal(input []byte, manifest *ManifestYAML) error {
 func (dm *YAMLParser) Marshal(manifest *ManifestYAML) (output []byte, err error) {
 	data, err := yaml.Marshal(manifest)
 	if err != nil {
-		log.Printf("err happened during marshal :%v", err)
+		fmt.Printf("err happened during marshal :%v", err)
 		return nil, err
 	}
 	return data, nil
@@ -281,7 +280,7 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 					kind = "java"
 				default:
 					kind = "nodejs:6"
-					log.Println("Unsupported runtime type, set to nodejs")
+					fmt.Println("Unsupported runtime type, set to nodejs")
 					//add the user input kind here
 				}
 
@@ -295,7 +294,7 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 					code = base64.StdEncoding.EncodeToString([]byte(dat))
 				}
 				if ext == ".zip" && action.Runtime == "" {
-					log.Println("need explicit action Runtime value")
+					fmt.Println("need explicit action Runtime value")
 				}
 				wskaction.Exec.Code = &code
 			}
@@ -306,7 +305,7 @@ func (dm *YAMLParser) ComposeActions(mani *ManifestYAML, manipath string) (ar []
 			if utils.CheckExistRuntime(action.Runtime, utils.Rts) {
 				wskaction.Exec.Kind = action.Runtime
 			} else {
-				log.Println("the runtime is not supported by Openwhisk platform.")
+				fmt.Println("the runtime is not supported by Openwhisk platform.")
 			}
 		}
 
diff --git a/tests/src/integration/common/wskdeploy.go b/tests/src/integration/common/wskdeploy.go
index abd3b93..37f731d 100644
--- a/tests/src/integration/common/wskdeploy.go
+++ b/tests/src/integration/common/wskdeploy.go
@@ -22,6 +22,10 @@ import (
 	"os"
 	"os/exec"
 	"strings"
+    "bytes"
+    "github.com/apache/incubator-openwhisk-wskdeploy/utils"
+    "github.com/mattn/go-colorable"
+    "github.com/fatih/color"
 )
 
 const cmd = "wskdeploy"
@@ -46,54 +50,66 @@ func printCommand(cmd *exec.Cmd) {
 	fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " "))
 }
 
-func printError(err error) {
-	if err != nil {
-		os.Stderr.WriteString(fmt.Sprintf("==> Error: %s\n", err.Error()))
-	}
+func printError(err string) {
+    outputStream := colorable.NewColorableStderr()
+	if len(err) > 0 {
+        fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString(err))
+	} else {
+        fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString("No error message"))
+    }
 }
 
-func printOutput(outs []byte) {
+func printOutput(outs string) {
 	if len(outs) > 0 {
-		fmt.Printf("==> Output: %s\n", string(outs))
+		fmt.Printf("==> Output: %s.\n", outs)
 	}
 }
 
-func (wskdeploy *Wskdeploy) RunCommand(s ...string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) RunCommand(s ...string) (string, error) {
 	command := exec.Command(wskdeploy.Path, s...)
 	command.Dir = wskdeploy.Dir
-
-    fmt.Println("wskdeploy.Path is " + wskdeploy.Path)
-    //fmt.Println("s is " + string(s))
 	printCommand(command)
 
-	output, err := command.CombinedOutput()
-
-	printOutput(output)
-	printError(err)
-
-	return output, err
+    var outb, errb bytes.Buffer
+    command.Stdout = &outb
+    command.Stderr = &errb
+	err := command.Run()
+
+    var returnError error = nil
+    if err != nil {
+        returnError = err
+    } else {
+        if (len(errb.String()) > 0) {
+            returnError = utils.NewTestCaseError(errb.String())
+        }
+    }
+    printOutput(outb.String())
+    if returnError != nil {
+        printError(returnError.Error())
+    }
+    return outb.String(), returnError
 }
 
-func (wskdeploy *Wskdeploy) Deploy(manifestPath string, deploymentPath string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) Deploy(manifestPath string, deploymentPath string) (string, error) {
 	return wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath)
 }
 
-func (wskdeploy *Wskdeploy) Undeploy(manifestPath string, deploymentPath string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) Undeploy(manifestPath string, deploymentPath string) (string, error) {
 	return wskdeploy.RunCommand("undeploy", "-m", manifestPath, "-d", deploymentPath)
 }
 
-func (wskdeploy *Wskdeploy) DeployProjectPathOnly(projectPath string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) DeployProjectPathOnly(projectPath string) (string, error) {
 	return wskdeploy.RunCommand( "-p", projectPath)
 }
 
-func (wskdeploy *Wskdeploy) UndeployProjectPathOnly(projectPath string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) UndeployProjectPathOnly(projectPath string) (string, error) {
     return wskdeploy.RunCommand("undeploy", "-p", projectPath)
 }
 
-func (wskdeploy *Wskdeploy) DeployManifestPathOnly(manifestpath string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) DeployManifestPathOnly(manifestpath string) (string, error) {
 	return wskdeploy.RunCommand("-m", manifestpath)
 }
 
-func (wskdeploy *Wskdeploy) UndeployManifestPathOnly(manifestpath string) ([]byte, error) {
+func (wskdeploy *Wskdeploy) UndeployManifestPathOnly(manifestpath string) (string, error) {
     return wskdeploy.RunCommand("undeploy", "-m", manifestpath)
 }
diff --git a/tests/src/integration/runtimetests/runtimes_test.go b/tests/src/integration/runtimetests/runtimes_test.go
index f436768..340c992 100644
--- a/tests/src/integration/runtimetests/runtimes_test.go
+++ b/tests/src/integration/runtimetests/runtimes_test.go
@@ -26,8 +26,6 @@ import (
 	"testing"
 )
 
-var wskprops = common.GetWskprops()
-
 func TestExplicitRuntimes(t *testing.T) {
 	wskdeploy := common.NewWskdeploy()
     projectPath := os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/runtimetests"
diff --git a/tests/src/integration/zipaction/zipaction_test.go b/tests/src/integration/zipaction/zipaction_test.go
index 70b6bb9..e39ddd6 100644
--- a/tests/src/integration/zipaction/zipaction_test.go
+++ b/tests/src/integration/zipaction/zipaction_test.go
@@ -26,10 +26,6 @@ import (
     "testing"
 )
 
-
-var wskprops = common.GetWskprops()
-
-
 func TestZipAction(t *testing.T) {
     wskdeploy := common.NewWskdeploy()
     _, err := wskdeploy.Deploy(manifestPath, deploymentPath)
diff --git a/utils/errorhandlers.go b/utils/errorhandlers.go
index 2b87f49..297e441 100644
--- a/utils/errorhandlers.go
+++ b/utils/errorhandlers.go
@@ -20,24 +20,26 @@ package utils
 import (
 	"errors"
 	"fmt"
-	"log"
 	"os"
+    "github.com/mattn/go-colorable"
+    "github.com/fatih/color"
+    "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 )
 
 // Check is a util function to panic when there is an error.
 func Check(e error) {
 	defer func() {
 		if err := recover(); err != nil {
-			log.Printf("Runtime panic : %v", err)
+			fmt.Printf("Runtime panic : %v", err)
 		}
 	}()
 
 	if e != nil {
-		log.Printf("%v", e)
+		fmt.Printf("%v", e)
 		erro := errors.New("Error happened during execution, please type 'wskdeploy -h' for help messages.")
-		log.Printf("%v", erro)
+		fmt.Printf("%v", erro)
 		if Flags.WithinOpenWhisk {
-			PrintOpenWhiskError(e.Error())
+			PrintOpenWhiskError(e)
 		} else {
 			os.Exit(1)
 		}
@@ -45,6 +47,13 @@ func Check(e error) {
 	}
 }
 
-func PrintOpenWhiskError(err string) {
-	fmt.Print(`{"error":"` + err + `"}`)
+func PrintOpenWhiskError(err error) {
+    outputStream := colorable.NewColorableStderr()
+    fmt.Fprintf(outputStream, "%s%s\n", color.RedString(wski18n.T("Error: ")), err.Error())
 }
+
+func PrintOpenWhiskOutput(err error) {
+    outputStream := colorable.NewColorableStderr()
+    fmt.Fprintf(outputStream, "%s%s\n", color.RedString(wski18n.T("Error: ")), err.Error())
+}
+
diff --git a/utils/fileoperations.go b/utils/fileoperations.go
index 9080c11..92e7375 100644
--- a/utils/fileoperations.go
+++ b/utils/fileoperations.go
@@ -27,7 +27,6 @@ import (
 	"strings"
 
 	"github.com/apache/incubator-openwhisk-client-go/whisk"
-	"log"
 )
 
 func MayExists(file string) bool {
@@ -127,7 +126,7 @@ func ReadProps(path string) (map[string]string, error) {
 	file, err := os.Open(path)
 	if err != nil {
 		// If file does not exist, just return props
-		log.Printf("Warning: Unable to read whisk properties file '%s' (file open error: %s)\n", path, err)
+		fmt.Printf("Warning: Unable to read whisk properties file '%s' (file open error: %s)\n", path, err)
 		return props, nil
 	}
 	defer file.Close()
diff --git a/utils/misc.go b/utils/misc.go
index 91a2f72..afb6dc4 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -37,7 +37,6 @@ import (
 	"github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 	"github.com/hokaccha/go-prettyjson"
 	"io/ioutil"
-	"log"
 	"net/http"
 )
 
@@ -460,9 +459,9 @@ type OpenWhiskInfo struct {
 // We could get the openwhisk info from bluemix through running the command
 // `curl -k https://openwhisk.ng.bluemix.net`
 // hard coding it here in case of network unavailable or failure.
-func ParseOpenWhisk() (op OpenWhiskInfo, err error) {
+func ParseOpenWhisk(apiHost string) (op OpenWhiskInfo, err error) {
 	ct := "application/json; charset=UTF-8"
-	req, _ := http.NewRequest("GET", "https://openwhisk.ng.bluemix.net", nil)
+	req, _ := http.NewRequest("GET", "https://" + apiHost, nil)
 	req.Header.Set("Content-Type", ct)
 	tlsConfig := &tls.Config{
 		InsecureSkipVerify: true,
@@ -473,14 +472,16 @@ func ParseOpenWhisk() (op OpenWhiskInfo, err error) {
 	}
 	res, err := http.DefaultClient.Do(req)
 	defer res.Body.Close()
-	if err != nil || res.Header.Get("Content-Type") != ct {
-		log.Println("failed get openwhisk info from internet")
-		log.Println("Start unmarshal Openwhisk info from local values")
+
+    // Local openwhisk deployment sometimes only returns "application/json" as the content type
+	if err != nil || !strings.Contains(ct, res.Header.Get("Content-Type")) {
+        fmt.Println("failed get openwhisk info from internet")
+		fmt.Println("Start unmarshal Openwhisk info from local values")
 		err = json.Unmarshal(runtimeInfo, &op)
 	} else {
 		b, _ := ioutil.ReadAll(res.Body)
 		if b != nil && len(b) > 0 {
-			log.Println("Unmarshal Openwhisk info from internet")
+			fmt.Println("Unmarshal Openwhisk info from internet")
 			err = json.Unmarshal(b, &op)
 		}
 	}
diff --git a/utils/errorhandlers.go b/utils/wskdeployerror.go
similarity index 51%
copy from utils/errorhandlers.go
copy to utils/wskdeployerror.go
index 2b87f49..3b23a92 100644
--- a/utils/errorhandlers.go
+++ b/utils/wskdeployerror.go
@@ -18,33 +18,40 @@
 package utils
 
 import (
-	"errors"
-	"fmt"
-	"log"
-	"os"
+    "fmt"
+    "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
 )
 
-// Check is a util function to panic when there is an error.
-func Check(e error) {
-	defer func() {
-		if err := recover(); err != nil {
-			log.Printf("Runtime panic : %v", err)
-		}
-	}()
-
-	if e != nil {
-		log.Printf("%v", e)
-		erro := errors.New("Error happened during execution, please type 'wskdeploy -h' for help messages.")
-		log.Printf("%v", erro)
-		if Flags.WithinOpenWhisk {
-			PrintOpenWhiskError(e.Error())
-		} else {
-			os.Exit(1)
-		}
-
-	}
+const (
+    INVALID_YAML_INPUT = "Invalid input of Yaml file"
+)
+
+type TestCaseError struct {
+    errorMessage string
+}
+
+func NewTestCaseError(errorMessage string) *TestCaseError {
+    return &TestCaseError{
+        errorMessage: errorMessage,
+    }
+}
+
+func (e *TestCaseError) Error() string {
+    return e.errorMessage
+}
+
+type InputYamlFileError struct {
+    errorMessage string
+    errorType string
+}
+
+func NewInputYamlFileError(errorMessage string) *InputYamlFileError {
+    return &InputYamlFileError{
+        errorMessage: errorMessage,
+        errorType: wski18n.T(INVALID_YAML_INPUT),
+    }
 }
 
-func PrintOpenWhiskError(err string) {
-	fmt.Print(`{"error":"` + err + `"}`)
+func (e *InputYamlFileError) Error() string {
+    return fmt.Sprintf("%s =====> %s", e.errorType, e.errorMessage)
 }
diff --git a/wski18n/detection.go b/wski18n/detection.go
index c3866dd..b442cc4 100644
--- a/wski18n/detection.go
+++ b/wski18n/detection.go
@@ -20,24 +20,24 @@ package wski18n
 import "github.com/cloudfoundry/jibber_jabber"
 
 type Detector interface {
-	DetectLocale() string
-	DetectLanguage() string
+    DetectLocale() string
+    DetectLanguage() string
 }
 
 type JibberJabberDetector struct{}
 
 func (d *JibberJabberDetector) DetectLocale() string {
-	userLocale, err := jibber_jabber.DetectIETF()
-	if err != nil {
-		userLocale = ""
-	}
-	return userLocale
+    userLocale, err := jibber_jabber.DetectIETF()
+    if err != nil {
+        userLocale = ""
+    }
+    return userLocale
 }
 
 func (d *JibberJabberDetector) DetectLanguage() string {
-	lang, err := jibber_jabber.DetectLanguage()
-	if err != nil {
-		lang = ""
-	}
-	return lang
+    lang, err := jibber_jabber.DetectLanguage()
+    if err != nil {
+        lang = ""
+    }
+    return lang
 }
diff --git a/wski18n/i18n.go b/wski18n/i18n.go
index 02a25d3..245dc3b 100644
--- a/wski18n/i18n.go
+++ b/wski18n/i18n.go
@@ -18,131 +18,131 @@
 package wski18n
 
 import (
-	"path/filepath"
-	"strings"
+    "path/filepath"
+    "strings"
 
-	goi18n "github.com/nicksnyder/go-i18n/i18n"
+    goi18n "github.com/nicksnyder/go-i18n/i18n"
 )
 
 const (
-	DEFAULT_LOCALE = "en_US"
+    DEFAULT_LOCALE = "en_US"
 )
 
 var SUPPORTED_LOCALES = []string{
-	"de_DE",
-	"en_US",
-	"es_ES",
-	"fr_FR",
-	"it_IT",
-	"ja_JA",
-	"ko_KR",
-	"pt_BR",
-	"zh_Hans",
-	"zh_Hant",
+    "de_DE",
+    "en_US",
+    "es_ES",
+    "fr_FR",
+    "it_IT",
+    "ja_JA",
+    "ko_KR",
+    "pt_BR",
+    "zh_Hans",
+    "zh_Hant",
 }
 
 var resourcePath = filepath.Join("wski18n", "resources")
 
 func GetResourcePath() string {
-	return resourcePath
+    return resourcePath
 }
 
 func SetResourcePath(path string) {
-	resourcePath = path
+    resourcePath = path
 }
 
 var T goi18n.TranslateFunc
 var curLocale string
 
 func init() {
-	curLocale = Init(new(JibberJabberDetector))
+    curLocale = Init(new(JibberJabberDetector))
 }
 
 func CurLocale() string {
-	return curLocale
+    return curLocale
 }
 
 func Locale(detector Detector) string {
 
-	// Use default locale until strings are translated
-	/*sysLocale := normalize(detector.DetectLocale())
-	  if isSupported(sysLocale) {
-	      return sysLocale
-	  }
+    // Use default locale until strings are translated
+    /*sysLocale := normalize(detector.DetectLocale())
+      if isSupported(sysLocale) {
+          return sysLocale
+      }
 
-	  locale := defaultLocaleForLang(detector.DetectLanguage())
-	  if locale != "" {
-	      return locale
-	  }*/
+      locale := defaultLocaleForLang(detector.DetectLanguage())
+      if locale != "" {
+          return locale
+      }*/
 
-	return DEFAULT_LOCALE
+    return DEFAULT_LOCALE
 }
 
 func Init(detector Detector) string {
-	l := Locale(detector)
-	InitWithLocale(l)
-	return l
+    l := Locale(detector)
+    InitWithLocale(l)
+    return l
 }
 
 func InitWithLocale(locale string) {
-	err := loadFromAsset(locale)
-	if err != nil {
-		panic(err)
-	}
-	T = goi18n.MustTfunc(locale)
+    err := loadFromAsset(locale)
+    if err != nil {
+        panic(err)
+    }
+    T = goi18n.MustTfunc(locale)
 }
 
 func loadFromAsset(locale string) (err error) {
-	assetName := locale + ".all.json"
-	assetKey := filepath.Join(resourcePath, assetName)
-	bytes, err := Asset(assetKey)
-	if err != nil {
-		return
-	}
-	err = goi18n.ParseTranslationFileBytes(assetName, bytes)
-	return
+    assetName := locale + ".all.json"
+    assetKey := filepath.Join(resourcePath, assetName)
+    bytes, err := Asset(assetKey)
+    if err != nil {
+        return
+    }
+    err = goi18n.ParseTranslationFileBytes(assetName, bytes)
+    return
 }
 
 func normalize(locale string) string {
-	locale = strings.ToLower(strings.Replace(locale, "-", "_", 1))
-	for _, l := range SUPPORTED_LOCALES {
-		if strings.EqualFold(locale, l) {
-			return l
-		}
-	}
-	switch locale {
-	case "zh_cn", "zh_sg":
-		return "zh_Hans"
-	case "zh_hk", "zh_tw":
-		return "zh_Hant"
-	}
-	return locale
+    locale = strings.ToLower(strings.Replace(locale, "-", "_", 1))
+    for _, l := range SUPPORTED_LOCALES {
+        if strings.EqualFold(locale, l) {
+            return l
+        }
+    }
+    switch locale {
+    case "zh_cn", "zh_sg":
+        return "zh_Hans"
+    case "zh_hk", "zh_tw":
+        return "zh_Hant"
+    }
+    return locale
 }
 
 func isSupported(locale string) bool {
-	for _, l := range SUPPORTED_LOCALES {
-		if strings.EqualFold(locale, l) {
-			return true
-		}
-	}
-	return false
+    for _, l := range SUPPORTED_LOCALES {
+        if strings.EqualFold(locale, l) {
+            return true
+        }
+    }
+    return false
 }
 
 func defaultLocaleForLang(lang string) string {
-	if lang != "" {
-		lang = strings.ToLower(lang)
-		for _, l := range SUPPORTED_LOCALES {
-			if lang == LangOfLocale(l) {
-				return l
-			}
-		}
-	}
-	return ""
+    if lang != "" {
+        lang = strings.ToLower(lang)
+        for _, l := range SUPPORTED_LOCALES {
+            if lang == LangOfLocale(l) {
+                return l
+            }
+        }
+    }
+    return ""
 }
 
 func LangOfLocale(locale string) string {
-	if len(locale) < 2 {
-		return ""
-	}
-	return locale[0:2]
+    if len(locale) < 2 {
+        return ""
+    }
+    return locale[0:2]
 }
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 0fa6ed5..23da48f 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -15,330 +15,330 @@
 package wski18n
 
 import (
-	"bytes"
-	"compress/gzip"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
+    "bytes"
+    "compress/gzip"
+    "fmt"
+    "io"
+    "io/ioutil"
+    "os"
+    "path/filepath"
+    "strings"
+    "time"
 )
 
 func bindataRead(data []byte, name string) ([]byte, error) {
-	gz, err := gzip.NewReader(bytes.NewBuffer(data))
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
+    gz, err := gzip.NewReader(bytes.NewBuffer(data))
+    if err != nil {
+        return nil, fmt.Errorf("Read %q: %v", name, err)
+    }
 
-	var buf bytes.Buffer
-	_, err = io.Copy(&buf, gz)
-	clErr := gz.Close()
+    var buf bytes.Buffer
+    _, err = io.Copy(&buf, gz)
+    clErr := gz.Close()
 
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
-	if clErr != nil {
-		return nil, err
-	}
+    if err != nil {
+        return nil, fmt.Errorf("Read %q: %v", name, err)
+    }
+    if clErr != nil {
+        return nil, err
+    }
 
-	return buf.Bytes(), nil
+    return buf.Bytes(), nil
 }
 
 type asset struct {
-	bytes []byte
-	info  os.FileInfo
+    bytes []byte
+    info  os.FileInfo
 }
 
 type bindataFileInfo struct {
-	name    string
-	size    int64
-	mode    os.FileMode
-	modTime time.Time
+    name    string
+    size    int64
+    mode    os.FileMode
+    modTime time.Time
 }
 
 func (fi bindataFileInfo) Name() string {
-	return fi.name
+    return fi.name
 }
 func (fi bindataFileInfo) Size() int64 {
-	return fi.size
+    return fi.size
 }
 func (fi bindataFileInfo) Mode() os.FileMode {
-	return fi.mode
+    return fi.mode
 }
 func (fi bindataFileInfo) ModTime() time.Time {
-	return fi.modTime
+    return fi.modTime
 }
 func (fi bindataFileInfo) IsDir() bool {
-	return false
+    return false
 }
 func (fi bindataFileInfo) Sys() interface{} {
-	return nil
+    return nil
 }
 
-var _wski18nResourcesDe_deAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesDe_deAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesDe_deAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesDe_deAllJson,
-		"wski18n/resources/de_DE.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesDe_deAllJson,
+        "wski18n/resources/de_DE.all.json",
+    )
 }
 
 func wski18nResourcesDe_deAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesDe_deAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesDe_deAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8a\xe6\x52\x50\xa8\xe6\x52\x50\x50\x50\x50\xca\x4c\x51\xb2\x52\x50\xf2\x48\xcd\xc9\xc9\x57\xd2\x81\x08\x95\x14\x25\xe6\x15\xe7\x24\x96\x64\xe6\xe7\x81\xe4\x1c\xf3\x14\x1c\x03\x3c\x15\x32\xf2\x8b\x4b\x14\x72\x4b\x8b\x4b\x14\x92\x52\x15\x0a\x8a\xf2\xcb\x32\x53\x52\x53\xf4\x94\xb8\x14\x14\x6a\xb9\x62\xb9\x00\x01\x00\x00\xff\xff\x8d\xb9\x36\xf2\x52\x00\x00\x00")
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x92\xcd\x4e\xeb\x30\x14\x84\xf7\x79\x8a\x51\x36\xdd\x54\xb9\xfb\xbb\xeb\xa2\x52\x2b\x04\xad\x28\x20\x21\x40\x8a\x89\x1d\x62\x1a\xff\x28\x3e\x01\x95\x28\xef\x8e\xe2\xb6\x80\x8a\xd3\x14\xd8\x59\xf1\xcc\x37\x93\x73\x7c\x17\x01\x4d\x04\x00\xb1\xe4\xf1\x7f\xc4\x33\x51\x96\x26\x1e\x6f\x3f\x51\xc5\xb4\x2b\x19\x49\xa3\xbb\xbb\x89\xc6\x64\x39\x47\x61\x1c\x41\xd5\x8e\xf0\x28\x60\x2b\xf3\x22\xb9\xe0\x49\x1c\x01 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesEn_usAllJson,
-		"wski18n/resources/en_US.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesEn_usAllJson,
+        "wski18n/resources/en_US.all.json",
+    )
 }
 
 func wski18nResourcesEn_usAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesEn_usAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesEn_usAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 82, mode: os.FileMode(420), modTime: time.Unix(1488811063, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 1082, mode: os.FileMode(420), modTime: time.Unix(1504207585, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesEs_esAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesEs_esAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesEs_esAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesEs_esAllJson,
-		"wski18n/resources/es_ES.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesEs_esAllJson,
+        "wski18n/resources/es_ES.all.json",
+    )
 }
 
 func wski18nResourcesEs_esAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesEs_esAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesEs_esAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesFr_frAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8a\xe6\x52\x50\xa8\xe6\x52\x50\x50\x50\x50\xca\x4c\x51\xb2\x52\x50\x4a\xaa\x2c\x48\x2c\x2e\x56\x48\x4e\x2d\x2a\xc9\x4c\xcb\x4c\x4e\x2c\x49\x55\x48\xce\x48\x4d\xce\xce\xcc\x4b\x57\xd2\x81\x28\x2c\x29\x4a\xcc\x2b\xce\x49\x2c\xc9\xcc\xcf\x03\xe9\x08\xce\xcf\x4d\x55\x40\x12\x53\xc8\xcc\x53\x70\x2b\x4a\xcd\x4b\xce\x50\xe2\x52\x50\xa8\xe5\x8a\xe5\x02\x04\x00\x00\xff\xff\x45\xa4\xe9\x62\x65\x00\x00\x00")
+var _wski18nResourcesFr_frAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\xe6\x52\x50\xa8\xe6\x52\x50\x50\x50\x50\xca\x4c\x51\xb2\x52\x50\x4a\xaa\x2c\x48\x2c\x2e\x56\x48\x4e\x2d\x2a\xc9\x4c\xcb\x4c\x4e\x2c\x49\x55\x48\xce\x48\x4d\xce\xce\xcc\x4b\x57\xd2\x81\x28\x2c\x29\x4a\xcc\x2b\xce\x49\x2c\xc9\xcc\xcf\x03\xe9\x08\xce\xcf\x4d\x55\x40\x12\x53\xc8\xcc\x53\x70\x2b\x4a\xcd\x4b\xce\x50\xe2\x52\x50\xa8\xe5\x8a\xe5\x02\x04\x00\x00\xff\xff\x45\xa4\xe9\x62\x65\x00\x00\x00")
 
 func wski18nResourcesFr_frAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesFr_frAllJson,
-		"wski18n/resources/fr_FR.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesFr_frAllJson,
+        "wski18n/resources/fr_FR.all.json",
+    )
 }
 
 func wski18nResourcesFr_frAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesFr_frAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesFr_frAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesIt_itAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesIt_itAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesIt_itAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesIt_itAllJson,
-		"wski18n/resources/it_IT.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesIt_itAllJson,
+        "wski18n/resources/it_IT.all.json",
+    )
 }
 
 func wski18nResourcesIt_itAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesIt_itAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesIt_itAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesJa_jaAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesJa_jaAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesJa_jaAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesJa_jaAllJson,
-		"wski18n/resources/ja_JA.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesJa_jaAllJson,
+        "wski18n/resources/ja_JA.all.json",
+    )
 }
 
 func wski18nResourcesJa_jaAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesJa_jaAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesJa_jaAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesKo_krAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesKo_krAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesKo_krAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesKo_krAllJson,
-		"wski18n/resources/ko_KR.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesKo_krAllJson,
+        "wski18n/resources/ko_KR.all.json",
+    )
 }
 
 func wski18nResourcesKo_krAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesKo_krAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesKo_krAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesPt_brAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesPt_brAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesPt_brAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesPt_brAllJson,
-		"wski18n/resources/pt_BR.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesPt_brAllJson,
+        "wski18n/resources/pt_BR.all.json",
+    )
 }
 
 func wski18nResourcesPt_brAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesPt_brAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesPt_brAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesZh_hansAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesZh_hansAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesZh_hansAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesZh_hansAllJson,
-		"wski18n/resources/zh_Hans.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesZh_hansAllJson,
+        "wski18n/resources/zh_Hans.all.json",
+    )
 }
 
 func wski18nResourcesZh_hansAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesZh_hansAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesZh_hansAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesZh_hantAllJson = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+var _wski18nResourcesZh_hantAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesZh_hantAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesZh_hantAllJson,
-		"wski18n/resources/zh_Hant.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesZh_hantAllJson,
+        "wski18n/resources/zh_Hant.all.json",
+    )
 }
 
 func wski18nResourcesZh_hantAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesZh_hantAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesZh_hantAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1487338781, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 // Asset loads and returns the asset for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
 func Asset(name string) ([]byte, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
-		}
-		return a.bytes, nil
-	}
-	return nil, fmt.Errorf("Asset %s not found", name)
+    cannonicalName := strings.Replace(name, "\\", "/", -1)
+    if f, ok := _bindata[cannonicalName]; ok {
+        a, err := f()
+        if err != nil {
+            return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+        }
+        return a.bytes, nil
+    }
+    return nil, fmt.Errorf("Asset %s not found", name)
 }
 
 // MustAsset is like Asset but panics when Asset would return an error.
 // It simplifies safe initialization of global variables.
 func MustAsset(name string) []byte {
-	a, err := Asset(name)
-	if err != nil {
-		panic("asset: Asset(" + name + "): " + err.Error())
-	}
+    a, err := Asset(name)
+    if err != nil {
+        panic("asset: Asset(" + name + "): " + err.Error())
+    }
 
-	return a
+    return a
 }
 
 // AssetInfo loads and returns the asset info for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
 func AssetInfo(name string) (os.FileInfo, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
-		}
-		return a.info, nil
-	}
-	return nil, fmt.Errorf("AssetInfo %s not found", name)
+    cannonicalName := strings.Replace(name, "\\", "/", -1)
+    if f, ok := _bindata[cannonicalName]; ok {
+        a, err := f()
+        if err != nil {
+            return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+        }
+        return a.info, nil
+    }
+    return nil, fmt.Errorf("AssetInfo %s not found", name)
 }
 
 // AssetNames returns the names of the assets.
 func AssetNames() []string {
-	names := make([]string, 0, len(_bindata))
-	for name := range _bindata {
-		names = append(names, name)
-	}
-	return names
+    names := make([]string, 0, len(_bindata))
+    for name := range _bindata {
+        names = append(names, name)
+    }
+    return names
 }
 
 // _bindata is a table, holding each asset generator, mapped to its name.
 var _bindata = map[string]func() (*asset, error){
-	"wski18n/resources/de_DE.all.json":   wski18nResourcesDe_deAllJson,
-	"wski18n/resources/en_US.all.json":   wski18nResourcesEn_usAllJson,
-	"wski18n/resources/es_ES.all.json":   wski18nResourcesEs_esAllJson,
-	"wski18n/resources/fr_FR.all.json":   wski18nResourcesFr_frAllJson,
-	"wski18n/resources/it_IT.all.json":   wski18nResourcesIt_itAllJson,
-	"wski18n/resources/ja_JA.all.json":   wski18nResourcesJa_jaAllJson,
-	"wski18n/resources/ko_KR.all.json":   wski18nResourcesKo_krAllJson,
-	"wski18n/resources/pt_BR.all.json":   wski18nResourcesPt_brAllJson,
-	"wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
-	"wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
+    "wski18n/resources/de_DE.all.json": wski18nResourcesDe_deAllJson,
+    "wski18n/resources/en_US.all.json": wski18nResourcesEn_usAllJson,
+    "wski18n/resources/es_ES.all.json": wski18nResourcesEs_esAllJson,
+    "wski18n/resources/fr_FR.all.json": wski18nResourcesFr_frAllJson,
+    "wski18n/resources/it_IT.all.json": wski18nResourcesIt_itAllJson,
+    "wski18n/resources/ja_JA.all.json": wski18nResourcesJa_jaAllJson,
+    "wski18n/resources/ko_KR.all.json": wski18nResourcesKo_krAllJson,
+    "wski18n/resources/pt_BR.all.json": wski18nResourcesPt_brAllJson,
+    "wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
+    "wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
 }
 
 // AssetDir returns the file names below a certain
@@ -355,92 +355,92 @@ var _bindata = map[string]func() (*asset, error){
 // AssetDir("foo.txt") and AssetDir("notexist") would return an error
 // AssetDir("") will return []string{"data"}.
 func AssetDir(name string) ([]string, error) {
-	node := _bintree
-	if len(name) != 0 {
-		cannonicalName := strings.Replace(name, "\\", "/", -1)
-		pathList := strings.Split(cannonicalName, "/")
-		for _, p := range pathList {
-			node = node.Children[p]
-			if node == nil {
-				return nil, fmt.Errorf("Asset %s not found", name)
-			}
-		}
-	}
-	if node.Func != nil {
-		return nil, fmt.Errorf("Asset %s not found", name)
-	}
-	rv := make([]string, 0, len(node.Children))
-	for childName := range node.Children {
-		rv = append(rv, childName)
-	}
-	return rv, nil
+    node := _bintree
+    if len(name) != 0 {
+        cannonicalName := strings.Replace(name, "\\", "/", -1)
+        pathList := strings.Split(cannonicalName, "/")
+        for _, p := range pathList {
+            node = node.Children[p]
+            if node == nil {
+                return nil, fmt.Errorf("Asset %s not found", name)
+            }
+        }
+    }
+    if node.Func != nil {
+        return nil, fmt.Errorf("Asset %s not found", name)
+    }
+    rv := make([]string, 0, len(node.Children))
+    for childName := range node.Children {
+        rv = append(rv, childName)
+    }
+    return rv, nil
 }
 
 type bintree struct {
-	Func     func() (*asset, error)
-	Children map[string]*bintree
+    Func     func() (*asset, error)
+    Children map[string]*bintree
 }
-
 var _bintree = &bintree{nil, map[string]*bintree{
-	"wski18n": &bintree{nil, map[string]*bintree{
-		"resources": &bintree{nil, map[string]*bintree{
-			"de_DE.all.json":   &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
-			"en_US.all.json":   &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
-			"es_ES.all.json":   &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
-			"fr_FR.all.json":   &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
-			"it_IT.all.json":   &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
-			"ja_JA.all.json":   &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
-			"ko_KR.all.json":   &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
-			"pt_BR.all.json":   &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
-			"zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
-			"zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
-		}},
-	}},
+    "wski18n": &bintree{nil, map[string]*bintree{
+        "resources": &bintree{nil, map[string]*bintree{
+            "de_DE.all.json": &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
+            "en_US.all.json": &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
+            "es_ES.all.json": &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
+            "fr_FR.all.json": &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
+            "it_IT.all.json": &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
+            "ja_JA.all.json": &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
+            "ko_KR.all.json": &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
+            "pt_BR.all.json": &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
+            "zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
+            "zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
+        }},
+    }},
 }}
 
 // RestoreAsset restores an asset under the given directory
 func RestoreAsset(dir, name string) error {
-	data, err := Asset(name)
-	if err != nil {
-		return err
-	}
-	info, err := AssetInfo(name)
-	if err != nil {
-		return err
-	}
-	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
-	if err != nil {
-		return err
-	}
-	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
-	if err != nil {
-		return err
-	}
-	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-	if err != nil {
-		return err
-	}
-	return nil
+    data, err := Asset(name)
+    if err != nil {
+        return err
+    }
+    info, err := AssetInfo(name)
+    if err != nil {
+        return err
+    }
+    err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+    if err != nil {
+        return err
+    }
+    err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+    if err != nil {
+        return err
+    }
+    err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+    if err != nil {
+        return err
+    }
+    return nil
 }
 
 // RestoreAssets restores an asset under the given directory recursively
 func RestoreAssets(dir, name string) error {
-	children, err := AssetDir(name)
-	// File
-	if err != nil {
-		return RestoreAsset(dir, name)
-	}
-	// Dir
-	for _, child := range children {
-		err = RestoreAssets(dir, filepath.Join(name, child))
-		if err != nil {
-			return err
-		}
-	}
-	return nil
+    children, err := AssetDir(name)
+    // File
+    if err != nil {
+        return RestoreAsset(dir, name)
+    }
+    // Dir
+    for _, child := range children {
+        err = RestoreAssets(dir, filepath.Join(name, child))
+        if err != nil {
+            return err
+        }
+    }
+    return nil
 }
 
 func _filePath(dir, name string) string {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+    cannonicalName := strings.Replace(name, "\\", "/", -1)
+    return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
 }
+
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 54de351..fccfc6f 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -26,6 +26,21 @@
   {
     "id": "whisk API `VERSION`",
     "translation": "whisk API `VERSION`"
+  },
+  {
+    "id": "Manifest file not found at path {{.projectPath}}.\n",
+    "translation": "Manifest file not found at path {{.projectPath}}.\n"
+  },
+  {
+    "id": "Missing {{.yaml}}/{{.yml}} file.\n",
+    "translation": "Missing {{.yaml}}/{{.yml}} file.\n"
+  },
+  {
+    "id": "Using {{.manifestPath}} for deployment.\n",
+    "translation": "Using {{.manifestPath}} for deployment.\n"
+  },
+  {
+    "id": "Using {{.manifestPath}} for undeployment.\n",
+    "translation": "Using {{.manifestPath}} for undeployment.\n"
   }
-
 ]

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].