houshengbo closed pull request #676: Refactor some utils to their own 
descriptive packages.
URL: https://github.com/apache/incubator-openwhisk-wskdeploy/pull/676
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/cmd/report.go b/cmd/report.go
index 61fb534d..0bc5645d 100644
--- a/cmd/report.go
+++ b/cmd/report.go
@@ -28,6 +28,7 @@ import (
        "path"
        "sync"
     "os"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 )
 
 var wskpropsPath string
@@ -81,7 +82,8 @@ func printDeploymentInfo(client *whisk.Client) error {
        //We currently list packages, actions, triggers, rules.
        wg.Add(4)
 
-       utils.PrintOpenWhiskOutputln("----==== OpenWhisk Deployment Status 
====----")
+       // TODO() i18n
+       wskprint.PrintlnOpenWhiskStatus("----==== OpenWhisk Deployment Status 
====----")
        // we set the default package list options
        pkgoptions := &whisk.PackageListOptions{false, 0, 0, 0, false}
        packages, _, err := client.Packages.List(pkgoptions)
diff --git a/cmd/root.go b/cmd/root.go
index eab75d24..0edf6f33 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -32,6 +32,7 @@ import (
        "regexp"
        "strings"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 )
 
 var stderr = ""
@@ -61,13 +62,13 @@ func Execute() {
        if utils.Flags.WithinOpenWhisk {
                err := substCmdArgs()
                if err != nil {
-                       utils.PrintOpenWhiskError(err)
+                       wskprint.PrintOpenWhiskFromError(err)
                        return
                }
        }
 
        if err := RootCmd.Execute(); err != nil {
-               utils.PrintOpenWhiskError(err)
+               wskprint.PrintOpenWhiskFromError(err)
                os.Exit(-1)
        } else {
                if utils.Flags.WithinOpenWhisk {
@@ -135,7 +136,7 @@ func initConfig() {
                _, err := whisk.ReadProps(utils.Flags.CfgFile)
                if err != nil {
                        utils.Flags.CfgFile = defaultPath
-                       utils.PrintOpenWhiskOutputln("Invalid config file 
detected, so by bdefault it is set to " + utils.Flags.CfgFile)
+                       wskprint.PrintOpenWhiskWarning("Invalid config file 
detected, so by default it is set to " + utils.Flags.CfgFile + "\n")
                }
 
        } else {
diff --git a/deployers/deploymentreader.go b/deployers/deploymentreader.go
index c788b51a..8370f8e0 100644
--- a/deployers/deploymentreader.go
+++ b/deployers/deploymentreader.go
@@ -21,9 +21,10 @@ import (
        "errors"
        "github.com/apache/incubator-openwhisk-client-go/whisk"
        "github.com/apache/incubator-openwhisk-wskdeploy/parsers"
-       "github.com/apache/incubator-openwhisk-wskdeploy/utils"
        "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
 )
 
 type DeploymentReader struct {
@@ -75,7 +76,8 @@ func (reader *DeploymentReader) 
bindPackageInputsAndAnnotations() error {
                // a single package is specified in deployment YAML file with 
"package" key
                if 
len(reader.DeploymentDescriptor.GetProject().Package.Packagename) != 0 {
                        
packMap[reader.DeploymentDescriptor.GetProject().Package.Packagename] = 
reader.DeploymentDescriptor.GetProject().Package
-                       utils.PrintOpenWhiskOutputln("WARNING: The package YAML 
key in deployment file will soon be deprecated. Please use packages instead as 
described in specifications.")
+                       // TODO() i18n
+                       wskprint.PrintlnOpenWhiskWarning("The package YAML key 
in deployment file will soon be deprecated. Please use packages instead as 
described in specifications.")
                } else {
                        if reader.DeploymentDescriptor.Packages != nil {
                                for packName, depPacks := range 
reader.DeploymentDescriptor.Packages {
@@ -98,7 +100,8 @@ func (reader *DeploymentReader) 
bindPackageInputsAndAnnotations() error {
                serviceDeployPack := 
reader.serviceDeployer.Deployment.Packages[packName]
 
                if serviceDeployPack == nil {
-                       utils.PrintOpenWhiskOutputln("WARNING: Package name in 
deployment file " + packName + " does not match with manifest file.")
+                       // TODO() i18n
+                       wskprint.PrintlnOpenWhiskWarning("Package name in 
deployment file " + packName + " does not match with manifest file.")
                        break
                }
 
@@ -110,7 +113,7 @@ func (reader *DeploymentReader) 
bindPackageInputsAndAnnotations() error {
 
                                keyVal.Key = name
 
-                               keyVal.Value = utils.GetEnvVar(input.Value)
+                               keyVal.Value = wskenv.GetEnvVar(input.Value)
 
                                keyValArr = append(keyValArr, keyVal)
                        }
@@ -200,7 +203,7 @@ func (reader *DeploymentReader) 
bindActionInputsAndAnnotations() error {
 
                                        keyVal.Key = name
 
-                                       keyVal.Value = 
utils.GetEnvVar(input.Value)
+                                       keyVal.Value = 
wskenv.GetEnvVar(input.Value)
 
                                        keyValArr = append(keyValArr, keyVal)
                                }
@@ -285,7 +288,7 @@ func (reader *DeploymentReader) 
bindTriggerInputsAndAnnotations() error {
                                        var keyVal whisk.KeyValue
 
                                        keyVal.Key = name
-                                       keyVal.Value = 
utils.GetEnvVar(input.Value)
+                                       keyVal.Value = 
wskenv.GetEnvVar(input.Value)
 
                                        keyValArr = append(keyValArr, keyVal)
                                }
@@ -298,7 +301,8 @@ func (reader *DeploymentReader) 
bindTriggerInputsAndAnnotations() error {
                                        }
 
                                        for _, keyVal := range 
wskTrigger.Parameters {
-                                               
utils.PrintOpenWhiskOutputln("Checking key " + keyVal.Key)
+                                               // TODO() i18n
+                                               
wskprint.PrintlnOpenWhiskOutput("Checking key " + keyVal.Key)
                                                if _, exists := 
depParams[keyVal.Key]; !exists {
                                                        keyValArr = 
append(keyValArr, keyVal)
                                                }
diff --git a/deployers/filesystemreader.go b/deployers/filesystemreader.go
index 3bacf0d8..702da767 100644
--- a/deployers/filesystemreader.go
+++ b/deployers/filesystemreader.go
@@ -27,6 +27,7 @@ import (
        "github.com/apache/incubator-openwhisk-wskdeploy/parsers"
        "github.com/apache/incubator-openwhisk-wskdeploy/utils"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 )
 
 // name of directory that can contain source code
@@ -45,7 +46,8 @@ func NewFileSystemReader(serviceDeployer *ServiceDeployer) 
*FileSystemReader {
 
 func (reader *FileSystemReader) ReadProjectDirectory(manifest *parsers.YAML) 
([]utils.ActionRecord, error) {
 
-    utils.PrintOpenWhiskOutputln("Inspecting project directory for 
actions....")
+       // TODO() i18n
+       wskprint.PrintlnOpenWhiskOutput("Inspecting project directory for 
actions....")
 
        projectPathCount, err := 
reader.getFilePathCount(reader.serviceDeployer.ProjectPath)
        actions := make([]utils.ActionRecord, 0)
@@ -89,7 +91,8 @@ func (reader *FileSystemReader) ReadProjectDirectory(manifest 
*parsers.YAML) ([]
                                        }
                                }
                        } else if strings.HasPrefix(fpath, 
reader.serviceDeployer.ProjectPath+"/"+FileSystemSourceDirectoryName) {
-                utils.PrintOpenWhiskOutputln("Searching directory " + 
filepath.Base(fpath) + " for action source code.")
+                               // TODO() i18n
+                               wskprint.PrintlnOpenWhiskOutput("Searching 
directory " + filepath.Base(fpath) + " for action source code.")
                        } else {
                                return filepath.SkipDir
                        }
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index 5b2cf0c7..65545391 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -34,6 +34,7 @@ import (
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
        "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
        "net/http"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 )
 
 const (
@@ -318,12 +319,12 @@ func (deployer *ServiceDeployer) Deploy() error {
                                return err
                        }
 
-                       utils.PrintOpenWhiskOutput(wski18n.T("Deployment 
completed successfully.\n"))
+                       wskprint.PrintOpenWhiskSuccess(wski18n.T("Deployment 
completed successfully.\n"))
                        return nil
 
                } else {
                        deployer.InteractiveChoice = false
-                       utils.PrintOpenWhiskOutput(wski18n.T("OK. Cancelling 
deployment.\n"))
+                       wskprint.PrintOpenWhiskSuccess(wski18n.T("OK. 
Cancelling deployment.\n"))
                        return nil
                }
        }
@@ -335,7 +336,7 @@ func (deployer *ServiceDeployer) Deploy() error {
                return err
        }
 
-       utils.PrintOpenWhiskOutput(wski18n.T("Deployment completed 
successfully.\n"))
+       wskprint.PrintOpenWhiskSuccess(wski18n.T("Deployment completed 
successfully.\n"))
        return nil
 
 }
@@ -431,7 +432,7 @@ func (deployer *ServiceDeployer) DeployDependencies() error 
{
                                if err := depServiceDeployer.deployAssets(); 
err != nil {
                                        errString := wski18n.T("Deployment of 
dependency {{.depName}} did not complete sucessfully. Run `wskdeploy undeploy` 
to remove partially deployed assets.\n",
                                                
map[string]interface{}{"depName": depName})
-                                       
utils.PrintOpenWhiskErrorMessage(errString)
+                                       wskprint.PrintOpenWhiskError(errString)
                                        return err
                                }
 
@@ -960,16 +961,16 @@ func (deployer *ServiceDeployer) UnDeploy(verifiedPlan 
*DeploymentProject) error
                        deployer.InteractiveChoice = true
 
                        if err := deployer.unDeployAssets(verifiedPlan); err != 
nil {
-                               
utils.PrintOpenWhiskErrorMessage(wski18n.T("Undeployment did not complete 
sucessfully.\n"))
+                               
wskprint.PrintOpenWhiskError(wski18n.T("Undeployment did not complete 
sucessfully.\n"))
                                return err
                        }
 
-                       utils.PrintOpenWhiskOutput(wski18n.T("Deployment 
removed successfully.\n"))
+                       wskprint.PrintOpenWhiskSuccess(wski18n.T("Deployment 
removed successfully.\n"))
                        return nil
 
                } else {
                        deployer.InteractiveChoice = false
-                       utils.PrintOpenWhiskOutput(wski18n.T("OK. Canceling 
undeployment.\n"))
+                       wskprint.PrintOpenWhiskSuccess(wski18n.T("OK. Canceling 
undeployment.\n"))
                        return nil
                }
        }
@@ -981,7 +982,7 @@ func (deployer *ServiceDeployer) UnDeploy(verifiedPlan 
*DeploymentProject) error
                return err
        }
 
-       utils.PrintOpenWhiskOutput(wski18n.T("Deployment removed 
successfully.\n"))
+       wskprint.PrintOpenWhiskSuccess(wski18n.T("Deployment removed 
successfully.\n"))
        return nil
 
 }
@@ -1351,12 +1352,13 @@ func (deployer *ServiceDeployer) getQualifiedName(name 
string, namespace string)
 func (deployer *ServiceDeployer) printDeploymentAssets(assets 
*DeploymentProject) {
 
        // pretty ASCII OpenWhisk graphic
-       utils.PrintOpenWhiskOutputln("         ____      ___                   
_    _ _     _     _\n        /\\   \\    / _ \\ _ __   ___ _ __ | |  | | |__ 
(_)___| | __\n   /\\  /__\\   \\  | | | | '_ \\ / _ \\ '_ \\| |  | | '_ \\| / 
__| |/ /\n  /  \\____ \\  /  | |_| | |_) |  __/ | | | |/\\| | | | | \\__ \\   
<\n  \\   \\  /  \\/    \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n 
  \\___\\/              |_|\n")
+       // TODO() move to separate function and suppress using some flag
+       wskprint.PrintlnOpenWhiskOutput("         ____      ___                 
  _    _ _     _     _\n        /\\   \\    / _ \\ _ __   ___ _ __ | |  | | |__ 
(_)___| | __\n   /\\  /__\\   \\  | | | | '_ \\ / _ \\ '_ \\| |  | | '_ \\| / 
__| |/ /\n  /  \\____ \\  /  | |_| | |_) |  __/ | | | |/\\| | | | | \\__ \\   
<\n  \\   \\  /  \\/    \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n 
  \\___\\/              |_|\n")
 
-       utils.PrintOpenWhiskOutputln("Packages:")
+       wskprint.PrintlnOpenWhiskOutput("Packages:")
        for _, pack := range assets.Packages {
-               utils.PrintOpenWhiskOutputln("Name: " + pack.Package.Name)
-               utils.PrintOpenWhiskOutputln("    bindings: ")
+               wskprint.PrintlnOpenWhiskOutput("Name: " + pack.Package.Name)
+               wskprint.PrintlnOpenWhiskOutput("    bindings: ")
                for _, p := range pack.Package.Parameters {
                        jsonValue, err := utils.PrettyJSON(p.Value)
                        if err != nil {
@@ -1367,18 +1369,18 @@ func (deployer *ServiceDeployer) 
printDeploymentAssets(assets *DeploymentProject
                }
 
                for key, dep := range pack.Dependencies {
-                       utils.PrintOpenWhiskOutputln("  * dependency: " + key)
-                       utils.PrintOpenWhiskOutputln("    location: " + 
dep.Location)
+                       wskprint.PrintlnOpenWhiskOutput("  * dependency: " + 
key)
+                       wskprint.PrintlnOpenWhiskOutput("    location: " + 
dep.Location)
                        if !dep.IsBinding {
-                               utils.PrintOpenWhiskOutputln("    local path: " 
+ dep.ProjectPath)
+                               wskprint.PrintlnOpenWhiskOutput("    local 
path: " + dep.ProjectPath)
                        }
                }
 
-               utils.PrintOpenWhiskOutputln("")
+               wskprint.PrintlnOpenWhiskOutput("")
 
                for _, action := range pack.Actions {
-                       utils.PrintOpenWhiskOutputln("  * action: " + 
action.Action.Name)
-                       utils.PrintOpenWhiskOutputln("    bindings: ")
+                       wskprint.PrintlnOpenWhiskOutput("  * action: " + 
action.Action.Name)
+                       wskprint.PrintlnOpenWhiskOutput("    bindings: ")
                        for _, p := range action.Action.Parameters {
 
                                if reflect.TypeOf(p.Value).Kind() == 
reflect.Map {
@@ -1403,25 +1405,25 @@ func (deployer *ServiceDeployer) 
printDeploymentAssets(assets *DeploymentProject
                                }
 
                        }
-                       utils.PrintOpenWhiskOutputln("    annotations: ")
+                       wskprint.PrintlnOpenWhiskOutput("    annotations: ")
                        for _, p := range action.Action.Annotations {
                                fmt.Printf("        - %s : %v\n", p.Key, 
p.Value)
 
                        }
                }
 
-               utils.PrintOpenWhiskOutputln("")
+               wskprint.PrintlnOpenWhiskOutput("")
                for _, action := range pack.Sequences {
-                       utils.PrintOpenWhiskOutputln("  * sequence: " + 
action.Action.Name)
+                       wskprint.PrintlnOpenWhiskOutput("  * sequence: " + 
action.Action.Name)
                }
 
-               utils.PrintOpenWhiskOutputln("")
+               wskprint.PrintlnOpenWhiskOutput("")
        }
 
-       utils.PrintOpenWhiskOutputln("Triggers:")
+       wskprint.PrintlnOpenWhiskOutput("Triggers:")
        for _, trigger := range assets.Triggers {
-               utils.PrintOpenWhiskOutputln("* trigger: " + trigger.Name)
-               utils.PrintOpenWhiskOutputln("    bindings: ")
+               wskprint.PrintlnOpenWhiskOutput("* trigger: " + trigger.Name)
+               wskprint.PrintlnOpenWhiskOutput("    bindings: ")
 
                for _, p := range trigger.Parameters {
                        jsonValue, err := utils.PrettyJSON(p.Value)
@@ -1432,24 +1434,24 @@ func (deployer *ServiceDeployer) 
printDeploymentAssets(assets *DeploymentProject
                        }
                }
 
-               utils.PrintOpenWhiskOutputln("    annotations: ")
+               wskprint.PrintlnOpenWhiskOutput("    annotations: ")
                for _, p := range trigger.Annotations {
 
                        value := "?"
                        if str, ok := p.Value.(string); ok {
                                value = str
                        }
-                       utils.PrintOpenWhiskOutputln("        - name: " + p.Key 
+ " value: " + value)
+                       wskprint.PrintlnOpenWhiskOutput("        - name: " + 
p.Key + " value: " + value)
                }
        }
 
-       utils.PrintOpenWhiskOutputln("\n Rules")
+       wskprint.PrintlnOpenWhiskOutput("\n Rules")
        for _, rule := range assets.Rules {
-               utils.PrintOpenWhiskOutputln("* rule: " + rule.Name)
-               utils.PrintOpenWhiskOutputln("    - trigger: " + 
rule.Trigger.(string) + "\n    - action: " + rule.Action.(string))
+               wskprint.PrintlnOpenWhiskOutput("* rule: " + rule.Name)
+               wskprint.PrintlnOpenWhiskOutput("    - trigger: " + 
rule.Trigger.(string) + "\n    - action: " + rule.Action.(string))
        }
 
-       utils.PrintOpenWhiskOutputln("")
+       wskprint.PrintlnOpenWhiskOutput("")
 
 }
 
diff --git a/deployers/whiskclient.go b/deployers/whiskclient.go
index a5fb5ad1..c5a5df58 100644
--- a/deployers/whiskclient.go
+++ b/deployers/whiskclient.go
@@ -31,6 +31,7 @@ import (
        "github.com/apache/incubator-openwhisk-wskdeploy/utils"
        "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
 )
 
 const (
@@ -145,17 +146,20 @@ func NewWhiskConfig(proppath string, deploymentPath 
string, manifestPath string,
        whiskproperty, _ := GetWskPropFromWhiskProperty(pi)
        credential = GetPropertyValue(credential, whiskproperty.AuthKey, 
WHISKPROPERTY)
        if credential.Source == WHISKPROPERTY {
-        utils.PrintOpenWhiskOutputln("WARNING: The authentication key was 
retrieved from whisk.properties " +
+               // TODO() i18n
+               wskprint.PrintlnOpenWhiskWarning("The authentication key was 
retrieved from whisk.properties " +
                        "which will soon be deprecated please do not use it 
outside of Travis builds.")
        }
        namespace = GetPropertyValue(namespace, whiskproperty.Namespace, 
WHISKPROPERTY)
        if namespace.Source == WHISKPROPERTY {
-        utils.PrintOpenWhiskOutputln("WARNING: The namespace was retrieved 
from whisk.properties " +
+               // TODO() i18n
+               wskprint.PrintlnOpenWhiskWarning("The namespace was retrieved 
from whisk.properties " +
                        "which will soon be deprecated please do not use it 
outside of Travis builds.")
        }
        apiHost = GetPropertyValue(apiHost, whiskproperty.APIHost, 
WHISKPROPERTY)
        if apiHost.Source == WHISKPROPERTY {
-        utils.PrintOpenWhiskOutputln("WARNING: The API host was retrieved from 
whisk.properties " +
+               // TODO() i18n
+               wskprint.PrintlnOpenWhiskWarning("The API host was retrieved 
from whisk.properties " +
                        "which will soon be deprecated please do not use it 
outside of Travis builds.")
        }
 
@@ -169,8 +173,10 @@ func NewWhiskConfig(proppath string, deploymentPath 
string, manifestPath string,
        // If so, we prompt users for the input.
        // The namespace is set to a default value at this point if not 
provided.
        if len(apiHost.Value) == 0 && isInteractive == true {
+               // TODO() i18n
                host := promptForValue("\nPlease provide the hostname for 
OpenWhisk [default value is openwhisk.ng.bluemix.net]: ")
                if host == "" {
+                       // TODO() tell caller that we are using this default, 
look to make a const at top of file
                        host = "openwhisk.ng.bluemix.net"
                }
                apiHost.Value = host
@@ -178,12 +184,14 @@ func NewWhiskConfig(proppath string, deploymentPath 
string, manifestPath string,
        }
 
        if len(credential.Value) == 0 && isInteractive == true {
+               // TODO() i18n
                cred := promptForValue("\nPlease provide an authentication 
token: ")
                credential.Value = cred
                credential.Source = INTERINPUT
 
                // The namespace is always associated with the credential. Both 
of them should be picked up from the same source.
                if len(namespace.Value) == 0 || namespace.Value == 
whisk.DEFAULT_NAMESPACE {
+                       // TODO() i18n
                        ns := promptForValue("\nPlease provide a namespace 
[default value is guest]: ")
                        source := INTERINPUT
 
@@ -261,5 +269,4 @@ var promptForValue = func(msg string) (string) {
        text = strings.TrimSpace(text)
 
        return text
-
 }
diff --git a/parsers/deploy_parser.go b/parsers/deploy_parser.go
index dbecd0b9..88c52659 100644
--- a/parsers/deploy_parser.go
+++ b/parsers/deploy_parser.go
@@ -34,15 +34,19 @@ func (dm *YAMLParser) unmarshalDeployment(input []byte, 
deploy *YAML) error {
 func (dm *YAMLParser) ParseDeployment(deploymentPath string) (*YAML, error) {
        dplyyaml := YAML{}
        content, err := 
new(utils.ContentReader).LocalReader.ReadLocal(deploymentPath)
-    if err != nil {
-        return &dplyyaml, wskderrors.NewFileReadError(deploymentPath, 
err.Error())
-    }
+
+        if err != nil {
+               return &dplyyaml, wskderrors.NewFileReadError(deploymentPath, 
err.Error())
+       }
+
        err = dm.unmarshalDeployment(content, &dplyyaml)
-    if err != nil {
-        return &dplyyaml, wskderrors.NewYAMLParserErr(deploymentPath, err)
-    }
+
+       if err != nil {
+               return &dplyyaml, wskderrors.NewYAMLParserErr(deploymentPath, 
err)
+       }
+
        dplyyaml.Filepath = deploymentPath
-    dplyyamlEnvVar := ReadEnvVariable(&dplyyaml)
+       dplyyamlEnvVar := ReadEnvVariable(&dplyyaml)
        return dplyyamlEnvVar, nil
 }
 
diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go
index a7497b04..8403b47e 100644
--- a/parsers/manifest_parser.go
+++ b/parsers/manifest_parser.go
@@ -32,6 +32,7 @@ import (
        "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
        "gopkg.in/yaml.v2"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
 )
 
 // Read existing manifest file or create new if none exists
@@ -178,7 +179,7 @@ func (dm *YAMLParser) ComposeDependencies(pkg Package, 
projectPath string, fileP
                for name, value := range dependency.Annotations {
                        var keyVal whisk.KeyValue
                        keyVal.Key = name
-                       keyVal.Value = utils.GetEnvVar(value)
+                       keyVal.Value = wskenv.GetEnvVar(value)
 
                        keyValArrAnot = append(keyValArrAnot, keyVal)
                }
@@ -283,7 +284,7 @@ func (dm *YAMLParser) ComposePackage(pkg Package, 
packageName string, filePath s
        for name, value := range pkg.Annotations {
                var keyVal whisk.KeyValue
                keyVal.Key = name
-               keyVal.Value = utils.GetEnvVar(value)
+               keyVal.Value = wskenv.GetEnvVar(value)
                listOfAnnotations = append(listOfAnnotations, keyVal)
        }
        if len(listOfAnnotations) > 0 {
@@ -352,7 +353,7 @@ func (dm *YAMLParser) ComposeSequences(namespace string, 
sequences map[string]Se
                for name, value := range sequence.Annotations {
                        var keyVal whisk.KeyValue
                        keyVal.Key = name
-                       keyVal.Value = utils.GetEnvVar(value)
+                       keyVal.Value = wskenv.GetEnvVar(value)
 
                        keyValArr = append(keyValArr, keyVal)
                }
@@ -432,8 +433,9 @@ func (dm *YAMLParser) ComposeActions(filePath string, 
actions map[string]Action,
                                if err != nil {
                                        return nil, err
                                }
+                               // TODO() do not use defer in a loop, resource 
leaks possible
                                defer os.Remove(zipName)
-                               // To do: support docker and main entry as did 
by go cli?
+                               // TODO(): support docker and main entry as did 
by go cli?
                                wskaction.Exec, err = utils.GetExec(zipName, 
action.Runtime, false, "")
                                if err != nil {
                                        return nil, err
@@ -592,7 +594,7 @@ func (dm *YAMLParser) ComposeActions(filePath string, 
actions map[string]Action,
                for name, value := range action.Annotations {
                        var keyVal whisk.KeyValue
                        keyVal.Key = name
-                       keyVal.Value = utils.GetEnvVar(value)
+                       keyVal.Value = wskenv.GetEnvVar(value)
                        listOfAnnotations = append(listOfAnnotations, keyVal)
                }
                if len(listOfAnnotations) > 0 {
@@ -739,7 +741,7 @@ func (dm *YAMLParser) ComposeTriggers(filePath string, pkg 
Package, ma whisk.Key
                for name, value := range trigger.Annotations {
                        var keyVal whisk.KeyValue
                        keyVal.Key = name
-                       keyVal.Value = utils.GetEnvVar(value)
+                       keyVal.Value = wskenv.GetEnvVar(value)
                        listOfAnnotations = append(listOfAnnotations, keyVal)
                }
                if len(listOfAnnotations) > 0 {
diff --git a/parsers/parameters.go b/parsers/parameters.go
index 41e7a2be..01d5fffa 100644
--- a/parsers/parameters.go
+++ b/parsers/parameters.go
@@ -22,6 +22,7 @@ import (
        "encoding/json"
        "github.com/apache/incubator-openwhisk-wskdeploy/utils"
        "github.com/apache/incubator-openwhisk-wskdeploy/wskderrors"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
 )
 
 // TODO(): Support other valid Package Manifest types
@@ -322,7 +323,7 @@ func ResolveParameter(paramName string, param *Parameter, 
filePath string) (inte
        // Make sure the parameter's value is a valid, non-empty string
        if ( param.Value != nil && param.Type == "string") {
                // perform $ notation replacement on string if any exist
-               value = utils.GetEnvVar(param.Value)
+               value = wskenv.GetEnvVar(param.Value)
        }
 
        // JSON - Handle both cases, where value 1) is a string containing 
JSON, 2) is a map of JSON
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index bfd345c0..9b95a097 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -19,7 +19,7 @@ package parsers
 
 import (
        "github.com/apache/incubator-openwhisk-client-go/whisk"
-       "github.com/apache/incubator-openwhisk-wskdeploy/utils"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
 )
 
 // structs that denotes the sample manifest.yaml, wrapped yaml.v2
@@ -179,7 +179,7 @@ func (yaml *YAML) GetProject() Project {
 
 func convertSinglePackageName(packageName string) string {
        if len(packageName) != 0 {
-               packageNameEnv := utils.GetEnvVar(packageName)
+               packageNameEnv := wskenv.GetEnvVar(packageName)
                if str, ok := packageNameEnv.(string); ok {
                        return str
                } else {
@@ -193,7 +193,7 @@ func convertPackageName(packageMap map[string]Package) 
map[string]Package {
        packages := make(map[string]Package)
        for packName, depPacks := range packageMap {
                name := packName
-               packageName := utils.GetEnvVar(packName)
+               packageName := wskenv.GetEnvVar(packName)
                if str, ok := packageName.(string); ok {
                        name = str
                }
diff --git a/utils/errorhandlers.go b/utils/errorhandlers.go
deleted file mode 100644
index e566c88c..00000000
--- a/utils/errorhandlers.go
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package utils
-
-import (
-       "fmt"
-       "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
-       "github.com/fatih/color"
-       "github.com/mattn/go-colorable"
-)
-
-func PrintOpenWhiskError(err error) {
-       outputStream := colorable.NewColorableStderr()
-       fmt.Fprintf(outputStream, "%s%s", color.RedString(wski18n.T("Error: 
")), err.Error())
-}
-
-func PrintOpenWhiskOutput(output string) {
-    outputStream := colorable.NewColorableStdout()
-    fmt.Fprintf(outputStream, "%s", color.GreenString(output))
-}
-
-func PrintOpenWhiskOutputln(output string) {
-    fmt.Println(output)
-}
-
-func PrintOpenWhiskErrorMessage(err string) {
-    outputStream := colorable.NewColorableStderr()
-    fmt.Fprintf(outputStream, "%s", color.RedString(err))
-}
diff --git a/utils/misc.go b/utils/misc.go
index 5026c1d9..e10a37e3 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -116,69 +116,6 @@ func Ask(reader *bufio.Reader, question string, def 
string) string {
        return answer[:len-1]
 }
 
-// Test if a string
-func isValidEnvironmentVar(value string) bool {
-
-       // A valid Env. variable should start with or contain '$' (dollar) char.
-       //
-       // If the value is a single Env. variable, it should start with a '$' 
(dollar) char
-       // and have at least 1 additional character after it, e.g. $ENV_VAR
-       // If the value is a concatenation of a string and a Env. variable, it 
should contain '$' (dollar)
-       // and have a string following which is surrounded with '{' and '}', 
e.g. xxx${ENV_VAR}xxx.
-       if value != "" && strings.HasPrefix(value, "$") && len(value) > 1 {
-               return true
-       }
-       if value != "" && strings.Contains(value, "${") && strings.Count(value, 
"{") == strings.Count(value, "}") {
-               return true
-       }
-       return false
-}
-
-// Get the env variable value by key.
-// Get the env variable if the key is start by $
-func GetEnvVar(key interface{}) interface{} {
-       // Assure the key itself is not nil
-       if key == nil {
-               return nil
-       }
-
-       if reflect.TypeOf(key).String() == "string" {
-               keystr := key.(string)
-               if isValidEnvironmentVar(keystr) {
-                       // retrieve the value of the env. var. from the host 
system.
-                       var thisValue string
-                       //split the string with ${}
-                       //test if the substr is a environment var
-                       //if it is, replace it with the value
-                       f := func(c rune) bool {
-                               return c == '$' || c == '{' || c == '}'
-                       }
-                       for _, substr := range strings.FieldsFunc(keystr, f) {
-                               //if the substr is a $ENV_VAR
-                               if strings.Contains(keystr, "$"+substr) {
-                                       thisValue = os.Getenv(substr)
-                                       if thisValue == "" {
-                                               
PrintOpenWhiskOutputln("WARNING: Missing Environment Variable " + substr + ".")
-                                       }
-                                       keystr = strings.Replace(keystr, 
"$"+substr, thisValue, -1)
-                                       //if the substr is a ${ENV_VAR}
-                               } else if strings.Contains(keystr, 
"${"+substr+"}") {
-                                       thisValue = os.Getenv(substr)
-                                       if thisValue == "" {
-                                               
PrintOpenWhiskOutputln("WARNING: Missing Environment Variable " + substr + ".")
-                                       }
-                                       keystr = strings.Replace(keystr, 
"${"+substr+"}", thisValue, -1)
-                               }
-                       }
-                       return keystr
-               }
-
-               // The key was not a valid env. variable, simply return it as 
the value itself (of type string)
-               return keystr
-       }
-       return key
-}
-
 var kindToJSON []string = []string{"", "boolean", "integer", "integer", 
"integer", "integer", "integer", "integer", "integer", "integer",
        "integer", "integer", "integer", "number", "number", "number", 
"number", "array", "", "", "", "object", "", "", "string", "", ""}
 
diff --git a/utils/misc_test.go b/utils/misc_test.go
index 07a799bb..9430823b 100644
--- a/utils/misc_test.go
+++ b/utils/misc_test.go
@@ -21,8 +21,6 @@ package utils
 
 import (
        "testing"
-
-       "fmt"
        "github.com/stretchr/testify/assert"
        "os"
 )
@@ -45,27 +43,6 @@ func TestURLReader_ReadUrl(t *testing.T) {
        }
 }
 
-// The dollar sign test cases.
-func TestGetEnvVar(t *testing.T) {
-       os.Setenv("NoDollar", "NO dollar")
-       os.Setenv("WithDollar", "oh, dollars!")
-       os.Setenv("5000", "5000")
-       fmt.Println(GetEnvVar("NoDollar"))
-       fmt.Println(GetEnvVar("$WithDollar"))
-       fmt.Println(GetEnvVar("$5000"))
-       assert.Equal(t, "NoDollar", GetEnvVar("NoDollar"), "NoDollar should be 
no change.")
-       assert.Equal(t, "oh, dollars!", GetEnvVar("$WithDollar"), "dollar sign 
should be handled.")
-       assert.Equal(t, "5000", GetEnvVar("5000"), "Should be no difference 
between integer and string.")
-       assert.Equal(t, "", GetEnvVar("$WithDollarAgain"), "if not found in 
environemnt, return empty string.")
-       assert.Equal(t, "oh, dollars!.ccc.aaa", 
GetEnvVar("${WithDollar}.ccc.aaa"), "String concatenation fail")
-       assert.Equal(t, "ddd.NO dollar.aaa", GetEnvVar("ddd.${NoDollar}.aaa"), 
"String concatenation fail")
-       assert.Equal(t, "oh, dollars!.NO dollar.aaa", 
GetEnvVar("${WithDollar}.${NoDollar}.aaa"), "String concatenation fail")
-       assert.Equal(t, "ddd.ccc.oh, dollars!", 
GetEnvVar("ddd.ccc.${WithDollar}"), "String concatenation fail")
-       assert.Equal(t, "", GetEnvVar("$WithDollarAgain.ccc.aaa"), "String 
concatenation fail")
-       assert.Equal(t, "ddd..aaa", GetEnvVar("ddd.${WithDollarAgain}.aaa"), 
"String concatenation fail")
-       assert.Equal(t, "oh, dollars!NO dollar.NO dollar", 
GetEnvVar("${WithDollar}${NoDollar}.${NoDollar}"), "String concatenation fail")
-}
-
 func TestDependencies(t *testing.T) {
        var record = 
NewDependencyRecord("projectPath","packageName","http://github.com/user/repo","master",nil,nil,false)
        assert.Equal(t, "projectPath", record.ProjectPath,"ProjectPath is 
wrong")
diff --git a/wskderrors/wskdeployerror_test.go 
b/wskderrors/wskdeployerror_test.go
index 64684257..c4ba8376 100644
--- a/wskderrors/wskdeployerror_test.go
+++ b/wskderrors/wskdeployerror_test.go
@@ -51,81 +51,81 @@ func TestCustomErrorOutputFormat(t *testing.T) {
         * CommandError
         */
        err1 := NewCommandError(TEST_COMMAND, TEST_DEFAULT_ERROR_MESSAGE)
-       actualResult :=  strings.TrimSpace(err1.Error())
+       actualResult := strings.TrimSpace(err1.Error())
        expectedResult := fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
                packageName,
                err1.LineNum,
                ERROR_COMMAND_FAILED,
                STR_COMMAND,
                TEST_COMMAND,
-               TEST_DEFAULT_ERROR_MESSAGE )
+               TEST_DEFAULT_ERROR_MESSAGE)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
         * WhiskClientError
         */
        err2 := NewWhiskClientError(TEST_DEFAULT_ERROR_MESSAGE, 
TEST_ERROR_CODE, nil)
-       actualResult =  strings.TrimSpace(err2.Error())
+       actualResult = strings.TrimSpace(err2.Error())
        expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: %d: %s",
                packageName,
                err2.LineNum,
                ERROR_WHISK_CLIENT_ERROR,
                STR_ERROR_CODE,
                TEST_ERROR_CODE,
-               TEST_DEFAULT_ERROR_MESSAGE )
+               TEST_DEFAULT_ERROR_MESSAGE)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
         * WhiskClientInvalidConfigError
         */
        err3 := NewWhiskClientInvalidConfigError(TEST_DEFAULT_ERROR_MESSAGE)
-       actualResult =  strings.TrimSpace(err3.Error())
+       actualResult = strings.TrimSpace(err3.Error())
        expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s",
                packageName,
                err3.LineNum,
                ERROR_WHISK_CLIENT_INVALID_CONFIG,
-               TEST_DEFAULT_ERROR_MESSAGE )
+               TEST_DEFAULT_ERROR_MESSAGE)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
         * FileReadError
         */
        err4 := NewFileReadError(TEST_NONEXISTANT_MANIFEST_FILE, 
TEST_DEFAULT_ERROR_MESSAGE)
-       actualResult =  strings.TrimSpace(err4.Error())
+       actualResult = strings.TrimSpace(err4.Error())
        expectedResult = fmt.Sprintf("%s [%d]: [%s]: " + STR_FILE + ": [%s]: 
%s",
                packageName,
                err4.LineNum,
                ERROR_FILE_READ_ERROR,
                filepath.Base(TEST_NONEXISTANT_MANIFEST_FILE),
-               TEST_DEFAULT_ERROR_MESSAGE )
+               TEST_DEFAULT_ERROR_MESSAGE)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
         * ManifestFileNotFoundError
         */
        err5 := NewErrorManifestFileNotFound(TEST_NONEXISTANT_MANIFEST_FILE, 
TEST_DEFAULT_ERROR_MESSAGE)
-       actualResult =  strings.TrimSpace(err5.Error())
+       actualResult = strings.TrimSpace(err5.Error())
        expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
                packageName,
                err5.LineNum,
                ERROR_MANIFEST_FILE_NOT_FOUND,
                STR_FILE,
                filepath.Base(TEST_NONEXISTANT_MANIFEST_FILE),
-               TEST_DEFAULT_ERROR_MESSAGE )
+               TEST_DEFAULT_ERROR_MESSAGE)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
          * YAMLFileFormatError
          */
        err6 := NewYAMLFileFormatError(TEST_INVALID_YAML_MANIFEST_FILE, 
TEST_DEFAULT_ERROR_MESSAGE)
-       actualResult =  strings.TrimSpace(err6.Error())
+       actualResult = strings.TrimSpace(err6.Error())
        expectedResult = fmt.Sprintf("%s [%d]: [%s]: %s: [%s]: %s",
                packageName,
                err6.LineNum,
                ERROR_YAML_FILE_FORMAT_ERROR,
                STR_FILE,
                filepath.Base(TEST_INVALID_YAML_MANIFEST_FILE),
-               TEST_DEFAULT_ERROR_MESSAGE )
+               TEST_DEFAULT_ERROR_MESSAGE)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
@@ -136,7 +136,7 @@ func TestCustomErrorOutputFormat(t *testing.T) {
                TEST_PARAM_NAME,
                TEST_PARAM_TYPE_INT,
                TEST_PARAM_TYPE_FLOAT)
-       actualResult =  strings.TrimSpace(err8.Error())
+       actualResult = strings.TrimSpace(err8.Error())
        msg8 := fmt.Sprintf("%s [%s]: %s %s: [%s], %s: [%s]",
                STR_PARAMETER, TEST_PARAM_NAME,
                STR_TYPE,
@@ -148,14 +148,14 @@ func TestCustomErrorOutputFormat(t *testing.T) {
                ERROR_YAML_PARAMETER_TYPE_MISMATCH,
                STR_FILE,
                filepath.Base(TEST_EXISTANT_MANIFEST_FILE),
-               msg8 )
+               msg8)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
         * InvalidParameterType
         */
        err9 := NewInvalidParameterTypeError(TEST_EXISTANT_MANIFEST_FILE, 
TEST_PARAM_NAME, TEST_PARAM_TYPE_FOO)
-       actualResult =  strings.TrimSpace(err9.Error())
+       actualResult = strings.TrimSpace(err9.Error())
        msg9 := fmt.Sprintf("%s [%s]: %s [%s]",
                STR_PARAMETER, TEST_PARAM_NAME,
                STR_TYPE, TEST_PARAM_TYPE_FOO)
@@ -164,7 +164,7 @@ func TestCustomErrorOutputFormat(t *testing.T) {
                err9.LineNum,
                ERROR_YAML_INVALID_PARAMETER_TYPE,
                filepath.Base(TEST_EXISTANT_MANIFEST_FILE),
-               msg9 )
+               msg9)
        assert.Equal(t, expectedResult, actualResult)
 
        /*
diff --git a/wskenv/environment.go b/wskenv/environment.go
new file mode 100644
index 00000000..97023712
--- /dev/null
+++ b/wskenv/environment.go
@@ -0,0 +1,90 @@
+/*
+ * 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 wskenv
+
+import (
+       "strings"
+       "os"
+       "reflect"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wskprint"
+)
+
+// Test if a string
+func isValidEnvironmentVar(value string) bool {
+
+       // A valid Env. variable should start with or contain '$' (dollar) char.
+       //
+       // If the value is a single Env. variable, it should start with a '$' 
(dollar) char
+       // and have at least 1 additional character after it, e.g. $ENV_VAR
+       // If the value is a concatenation of a string and a Env. variable, it 
should contain '$' (dollar)
+       // and have a string following which is surrounded with '{' and '}', 
e.g. xxx${ENV_VAR}xxx.
+       if value != "" && strings.HasPrefix(value, "$") && len(value) > 1 {
+               return true
+       }
+       if value != "" && strings.Contains(value, "${") && strings.Count(value, 
"{") == strings.Count(value, "}") {
+               return true
+       }
+       return false
+}
+
+// Get the env variable value by key.
+// Get the env variable if the key is start by $
+func GetEnvVar(key interface{}) interface{} {
+       // Assure the key itself is not nil
+       if key == nil {
+               return nil
+       }
+
+       if reflect.TypeOf(key).String() == "string" {
+               keystr := key.(string)
+               if isValidEnvironmentVar(keystr) {
+                       // retrieve the value of the env. var. from the host 
system.
+                       var thisValue string
+                       //split the string with ${}
+                       //test if the substr is a environment var
+                       //if it is, replace it with the value
+                       f := func(c rune) bool {
+                               return c == '$' || c == '{' || c == '}'
+                       }
+                       for _, substr := range strings.FieldsFunc(keystr, f) {
+                               //if the substr is a $ENV_VAR
+                               if strings.Contains(keystr, "$"+substr) {
+                                       thisValue = os.Getenv(substr)
+                                       if thisValue == "" {
+                                               // TODO() i18n
+                                               
wskprint.PrintlnOpenWhiskWarning("Missing Environment Variable " + substr + ".")
+                                       }
+                                       keystr = strings.Replace(keystr, 
"$"+substr, thisValue, -1)
+                                       //if the substr is a ${ENV_VAR}
+                               } else if strings.Contains(keystr, 
"${"+substr+"}") {
+                                       thisValue = os.Getenv(substr)
+                                       if thisValue == "" {
+                                               // TODO() i18n
+                                               
wskprint.PrintlnOpenWhiskWarning("Missing Environment Variable " + substr + ".")
+                                       }
+                                       keystr = strings.Replace(keystr, 
"${"+substr+"}", thisValue, -1)
+                               }
+                       }
+                       return keystr
+               }
+
+               // The key was not a valid env. variable, simply return it as 
the value itself (of type string)
+               return keystr
+       }
+       return key
+}
diff --git a/wskenv/environment_test.go b/wskenv/environment_test.go
new file mode 100644
index 00000000..80dda7f8
--- /dev/null
+++ b/wskenv/environment_test.go
@@ -0,0 +1,46 @@
+/*
+ * 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 wskenv
+
+import (
+       "testing"
+       "os"
+       "fmt"
+       "github.com/stretchr/testify/assert"
+)
+
+// The dollar sign test cases.
+func TestGetEnvVar(t *testing.T) {
+os.Setenv("NoDollar", "NO dollar")
+os.Setenv("WithDollar", "oh, dollars!")
+os.Setenv("5000", "5000")
+fmt.Println(GetEnvVar("NoDollar"))
+fmt.Println(GetEnvVar("$WithDollar"))
+fmt.Println(GetEnvVar("$5000"))
+assert.Equal(t, "NoDollar", GetEnvVar("NoDollar"), "NoDollar should be no 
change.")
+assert.Equal(t, "oh, dollars!", GetEnvVar("$WithDollar"), "dollar sign should 
be handled.")
+assert.Equal(t, "5000", GetEnvVar("5000"), "Should be no difference between 
integer and string.")
+assert.Equal(t, "", GetEnvVar("$WithDollarAgain"), "if not found in 
environemnt, return empty string.")
+assert.Equal(t, "oh, dollars!.ccc.aaa", GetEnvVar("${WithDollar}.ccc.aaa"), 
"String concatenation fail")
+assert.Equal(t, "ddd.NO dollar.aaa", GetEnvVar("ddd.${NoDollar}.aaa"), "String 
concatenation fail")
+assert.Equal(t, "oh, dollars!.NO dollar.aaa", 
GetEnvVar("${WithDollar}.${NoDollar}.aaa"), "String concatenation fail")
+assert.Equal(t, "ddd.ccc.oh, dollars!", GetEnvVar("ddd.ccc.${WithDollar}"), 
"String concatenation fail")
+assert.Equal(t, "", GetEnvVar("$WithDollarAgain.ccc.aaa"), "String 
concatenation fail")
+assert.Equal(t, "ddd..aaa", GetEnvVar("ddd.${WithDollarAgain}.aaa"), "String 
concatenation fail")
+assert.Equal(t, "oh, dollars!NO dollar.NO dollar", 
GetEnvVar("${WithDollar}${NoDollar}.${NoDollar}"), "String concatenation fail")
+}
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 15db0cab..540039fa 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -1,21 +1,3 @@
-/*
- * 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.
- */
-
-
 // Code generated by go-bindata.
 // sources:
 // wski18n/resources/de_DE.all.json
@@ -110,12 +92,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x5b\x6f\xe3\x36\x16\x7e\xcf\xaf\x38\xc8\x8b\x5f\x02\xed\x4c\x17\x0b\x2c\xe6\x2d\xd8\xe9\x25\x68\xe7\x82\x99\xd9\x16\x45\x77\x80\xd0\xe2\xb1\xc5\x9a\x22\x05\x92\x72\xea\x0a\xfe\xef\x0b\x92\x92\x2f\x89\x44\x51\xb2\xec\x04\x45\xf3\xe4\xd8\x3a\xdf\xf7\x9d\xc3\xdb\x21\x79\xf4\xdb\x15\x40\x75\x05\x00\x70\xcd\xe8\xf5\x1b\xb8\xfe\x01\x39\x97\xd7\x37\xfe\x2b\xa3\x88\xd0\x9c\x18\x26\x85\xfd\xed\x56\xc0\xed\xc7\x3b\xc8\xa4\x36\x90\x97\xda\xc0\x1c\xa1\x50\x72\xcd\x28\xd2\xe4\xfa\x0a\x60\x7b\xf3\x18\xee\x1d\xd3\x9a\x89\x25\xa4\x39\x85\x15\x6e\x3a\x80\x9b\xa7\x66\x69\x4e\x67\xc0\x44\x51\x1a\xf7\x74\x2b\x24\x29\x4d\x26\x15\xfb\xd3\x59\xc3\xfd\x8f\xdf\xfe\x7a\xdf\x01\xdb\xf6\x64\x2b\xe4\x43\xc6\xf4\xca\xf9\x76\xff\xc3\x87\xcf\x5f\xba\xf0\x9e\x3c\xd6\x0a\x26\x48\x8e\xba\x20\x29\x76\xa0\xec\x7f\xef\xd3\xf2\xf3\xb7\x9f\x3e\xdf\x7d\x78\x1f\x21\x67\xf7\x64\x7b\x23\x10\xc1\x16\xa8\x0d\x2c\x18\x47\x10\xd2\xc0\x42\x96\x82\x02\x31\x50\x10\x93\x41\x55\x25\x85\x92\xbf\x63\x6a\x3e\x12\x93\x6d\xb7\xc9\xff\x44\x57\x43\x8d\x40\x0a\xf6\x8b\xaa\x4a\x36\x24\xe7\xdb\xed\x3f\xec\x27\xfb\xc1\x41\x27\x30\xa1\xe6\x73\x50\x45\xc4\x99\xe9\x63\x2c\x93\xa1\xc7\xfb\xad\xaa\x12\xfb\x84\x47\xfb\x1a\x1b\xed\x21\x78\xad\xf2\xfe\xdb\x84\x21\xaf\x71\xbd\x01\x2c\xa4\x02\x8a\x05\x97\x9b\x1c\x85\xe9\x96\x13\x6f\x3f\x98\xbe\x14\xa7\x0a\x78\x8c\xd0\x2a\xc1\x86\x4c\x95\xc2\xb0\x7c\x17\x4e\x5d\x16\x85\x54\x06\x29\xcc\x37\xf0\xa1\x40\xe1\x47\x55\xc1\x89\x59\x48\x95\x77\x8b\x19\x87\xd5\x2a\xeb\x97\xdb\x4f\xef\xef\xde\x7f\xff\x06\x3e\xd5\x78\xba\xc0\x94\x2d\x18\x52\x60\x02\x1a\x67\xe1\xd7\xdb\x77\x3f\x59\xef\x6b\xd6\xed\x16\xa8\x44\xcf\x9c\x13\x93\x66\xf0\xc0\x4c\x06\x24\x75\xb3\x9d\x96\xa5\x4a\xd1\xf7\x1c\xfc\xc3\xa0\xd0\xf6\xdb\xaa\x4a\xf0\x0f\x53\x87\xac\x7e\xb2\xaa\x12\xff\x29\x34\x88\x5e\x94\xc4\x70\x10\x7f\x71\x41\x7f\xeb\x7a\x03\x64\x44\x43\x9a\x49\x8d\x02\x48\x51\x28\x59\x28\x46\xcc\xbe\xe1\x8e\xa4\xce\x89\x46\x0a\x52\xb8\x91\x15\xd4\x68\xa5\x99\x8c\x98\x71\x21\x7c\x7e\x81\xd3\xf6\xc2\xae\xde\xef\xfd\xd4\xa8\xd6\xa8\x6a\x45\x78\x99\x4e\x37\x81\xa2\xab\xf6\x39\x4c\xec\x31\x9b\x26\x32\x9b\x02\x6f\x40\xa3\x01\x23\x41\x48\x8a\xbf\xeb\xae\xf9\x2b\xd2\xba\x95\xfa\x8b\x95\x5a\x9a\x0c\x85\x61\xa9\xcf\x68\x56\xb8\x69\x5c\x4d\xa5\x58\xb0\x65\xa9\x90\x76\x87\x73\x08\x42\xa7\x84\x5d\x02\x38\x90\x38\x6c\xd7\x49\xb7\x4b\x96\x86\xf2\xf5\x18\x46\xf9\x67\xbb\x44\xc1\xec\x7f\xdb\xed\x0d\x2c\x94\xcc\xeb\xaf\xfc\xa0\x0b\x75\xdd\x51\x50\xc1\x76\x6f\xda\x4a\xa3\x39\x00\x28\x4d\x16\x27\x26\x1a\x22\xae\x29\xaa\x2a\xd9\xfd\x7f\xe8\xd1\xee\xcb\x38\x55\xe3\x31\x5b\x65\x7e\x47\x18\x47\x6a\x47\xd2\x12\x7d\x82\xf4\x64\xc0\x69\x0f\x7b\x3c\x1b\xb0\x14\xdf\xb8\x85\x47\xa9\x90\xe2\xc9\xe0\x5b\xc5\x7f\x36\x44\xb9\x59\xa0\x14\x39\x51\x3a\x23\xfc\x20\x87\x60\x62\x21\x3d\x34\x97\x29\xe1\xb0\x26\xbc\x44\xdd\x2d\x75\x24\x58\xc7\xa4\x17\x82\x60\xc2\xa0\x12\x18\x4a\xdb\xa2\xed\x5b\xe9\xdf\xee\xf2\x3a\x48\x65\x5e\x70\xb4\xe1\xd6\x65\x9a\xa2\xd6\x8b\x92\xf3\x4d\x37\x73\x94\x69\x2b\xe9\xf7\xd2\x00\x2a\x25\x15\xa4\x0a\x89\xb1\x79\x67\x41\xd2\x15\x59\xa2\x4f\x61\xfc\x6f\x39\x6a\x4d\x96\x07\x8d\x0b\x44\xd0\xc6\x4e\x52\xff\x83\xfd\x10\xea\x55\x67\xa1\x8a\x75\xaa\x5e\xfc\xfe\x5a\x3e\x15\xec\x12\x0e\x9d\x46\x13\xeb\x8c\x2a\xf9\x45\xba\xdc\x89\x3c\x3d\xee\x68\x34\x8e\xc5\xcd\x99\x86\x98\x52\x83\x5c\x9c\xdb\xb7\xb3\x90\xc6\xb6\x9b\x51\x6c\xb9\x44\x75\x89\xa6\x3b\x9d\x6a\xa8\x53\x0b\x44\x7a\x49\xcf\x4e\xe4\x1b\x3a\xc3\xcf\x99\xa0\xf6\xff\x0b\xce\x8a\xa7\x53\xf6\xad\x9d\x72\x01\x14\x0b\x14\x14\x45\xba\xb1\xa6\x14\x8b\xf7\xc4\xef\xd1\x19\xad\x53\x64\xbf\x46\xda\x25\x72\xb7\x42\xda\xcd\x17\xdc\x3f\xe8\x95\x3f\x5f\xd9\x1d\xb4\xdc\xdb\xec\x42\x61\x2e\xd7\x08\x05\x51\x86\x11\xce\x37\xf5\x39\x10\x52\x20\x5a\xa3\x09\x24\x28\x2f\x41\x59\x20\x64\x07\x6b\x63\x55\x25\xb2\x34\x45\x69\xb6\x5b\x48\x92\x24\xe8\x4f\xc0\xac\x87\xcc\x4d\x4b\x43\xa9\x5a\x8d\x7a\x88\x8e\xc6\xd4\x50\xc2\xa0\x71\x0f\x71\xd3\xd5\x87\x72\x76\xd9\x45\xd2\x35\x23\x6b\x2c\x6d\x97\x7d\x0f\xfd\x71\x8f\x1e\xc4\x1c\x30\x6d\x25\xfd\xf0\x63\x02\xff\x21\x22\x45\xce\x6b\xf3\xde\x93\xd4\xa0\x49\x0f\x89\x35\x88\x3b\xaf\x0d\xdb\x74\xec\x35\xf6\x0f\x85\x47\x7f\x60\xbb\x31\x00\xa2\x6f\xd6\xf4\xd3\xc8\x88\xfd\x46\x97\xe1\xcb\xf5\xba\x41\x78\xda\x05\xf7\xf3\x71\x77\xf7\x8d\xb5\xee\xf7\x7f\xec\x72\x10\x17\x9a\x13\xd0\x7b\xd2\x08\x8a\x1c\x2f\xb3\xa7\x9a\x8e\x29\xd6\xa5\x33\x67\xea\x53\xf1\xfc\xbd\x0b\x79\x14\xcf\xf3\xef\x42\x26\xa4\x1a\xea\xd4\x99\x77\x21\x53\xf3\xc5\xba\x77\xfe\x73\xa6\x09\xa9\xc2\x37\x49\x5f\x32\x84\x99\x3f\xb5\x9d\xf9\x6b\x1a\x77\x02\x2d\x76\x21\x45\x61\x98\x71\x67\xd2\x14\x0b\x85\x29\x31\x48\x13\xf8\xc8\x91\x68\x84\x52\x23\xcc\x6c\xd0\x67\xc0\x84\x36\x48\x6c\xee\x0e\x14\x75\xaa\xd8\xdc\xdf\x01\xd5\x17\x42\xfe\x36\x23\xb0\xdb\x78\x4e\x45\xb1\xed\xde\x24\x9a\x17\x6c\xff\xe9\x28\xbb\xf2\xa8\xb6\x44\x36\x23\x1a\xe6\x88\xe2\x28\x37\xda\xed\xcf\x82\xd9\xd5\x38\xb8\x56\x71\x1f\x03\xf9\xfd\x58\x85\xa7\x61\x06\x65\x4e\x29\x6f\x02\x59\x5f\xea\xe1\x32\x85\xac\x71\x58\x41\x59\x4f\xf6\xa7\xa7\x6a\x1b\x01\xd8\x2a\xf0\xd3\xe3\x1d\xfb\x58\x61\x23\x80\x5a\x05\xdd\x3e\x3d\xad\x18\x2b\x69\x14\x54\xc4\xc4\xb1\xcf\xd0\xdb\xe1\x9a\x8d\x65\xfc\xdc\x31\x0c\xb1\x6f\x00\xd4\x4b\xc7\x21\x5a\xbd\xfb\x8b\xea\xf3\x61\xf3\x60\x2f\xb2\x59\xe4\x20\xda\x08\xc3\x9e\x5e\xd2\xd4\x48\x0c\x20\x8d\x34\xee\xb9\xd1\x65\x62\x2d\x57\xe8\xd2\x68\x9f\x88\x65\x28\x2e\x94\x13\x5e\x58\x44\x38\xa7\x7a\x47\x04\x25\x46\xaa\x0d\x2c\x18\x72\x0a\xcd\xa4\xfe\x33\x2a\x57\xfa\xd3\x14\xe6\xea\xd0\x95\xec\x58\xb4\xb0\xb4\xc7\xc6\x4d\x19\x0e\x59\xfb\xdc\xc8\x86\x2d\x2d\x95\xb2\xfb\xf0\xfd\xb1\xed\xda\x3f\x1d\x21\xf6\x64\xfc\x71\x91\xfd\x89\xa5\x28\x34\x4e\x14\xd9\x0e\xb4\xb8\xc8\x36\xc6\xe7\x8a\xec\x68\xfc\xb0\xfc\x06\xb6\xaa\x12\xee\x3f\xde\xbd\xdd\x97\x69\x11\x58\x13\xce\x28\x48\x81\x11\x52\x07\x61\xb5\xca\xca\x31\x97\x6a\xf3\x99\xfd\x89\x76\x27\xce\x59\xce\x8c\x3e\x2a\x28\xd3\x99\x2c\x39\xb5\x8d\x43\x84\xab\x4f\xb0\x83\x7a\x8e\xe6\xc1\xce\x58\xaf\xbf\xf9\xb7\x1b\xbe\xff\x7a\xfd\x4d\xb7\xda\x49\x29\xda\x4b\x59\x59\x8e\xb2\x34\xa3\xe0\x5f\xbd\x72\xf0\xff\x7c\x65\xff\x02\x15\xae\x53\x52\xb4\x3a\xc1\xe5\x72\x6c\x8c\x3c\xfe\xeb\x80\xfc\x89\xc0\xc3\x3d\xfb\x4e\xf8\xfe\xe6\x18\x7c\x4d\xdd\xac\x8e\xdb\xcc\x32\xd7\x27\x74\x87\xcc\x4c\x03\x5b\x0a\xa9\x0e\xf6\x95\x69\x86\xe9\xca\x2f\x08\x31\x9b\xd8\xf3\x90\x0e\x77\x74\xdf\xcb\x2f\xeb\xeb\x24\xbc\xc3\xdd\xad\x3b\xd4\x65\x7d\x3d\x9d\xb4\x6f\x6a\x76\x43\xc3\x4f\xa7\x39\x33\xc2\xe7\xc5\xbb\xaa\xc9\x8c\x88\x25\x99\x73\x04\xa2\x7d\x85\xea\xc3\x0d\x3c\x64\xcc\x95\x72\x73\x6e\xc7\x4f\xc3\x1f\x33\x75\x4f\xc8\xd5\xea\x96\x7b\x1f\x42\x2e\xdc\x7a\x95\xac\x70\xe3\xea\xa2\x3b\x64\xb5\x3f\xdb\x0f\x9b\xa2\x32\xd1\xb8\xfb\x87\x83\x75\x95\xcd\xf3\xa4\x28\x78\x53\x9b\xeb\xea\x43\xdd\x3e\xc5\x5f\x2b\xd9\x45\x4e\x1c\x5c\xd5\xf9\x9a\x6f\x62\xdc\xfb\x1f\xfb\xaf\xbf\x63\x36\xb5\xff\xfa\xb8\xf0\xde\x44\x31\x35\x6f\x9c\x6c\x3d\x59\x7e\xf4\x02\x4a\x4d\xd5\x7c\x59\x13\x75\x5d\x08\xfd\x25\x5c\x0b\x8f\x9d\x43\xa2\x16\xfd\xae\xd3\x6a\x29\x85\xed\xb9\xfb\xd3\xc4\x1b\x28\xf6\xa7\x89\xf5\x8b\x45\xcd\x71\x62\xc4\x20\x3a\x0f\xe9\x20\x47\x8f\x63\x77\x11\x37\x27\xa1\x8c\xbc\x7b\xf4\x65\xa2\xee\x20\x98\xa1\x0e\x5e\x0b\x02\x2d\x95\xdd\xf9\xe5\x44\x90\x25\xd2\xc3\x8b\xf4\x33\xd5\xcd\xbc\x58\xb9\xed\xdb\x77\xf7\xb2\x5a\xfb\x5b\x16\xf5\xd4\xee\x4e\xda\xbd\x0f\xae\x1e\xf8\x70\xab\xd1\xb4\xe1\xfe\x0d\xbc\xb6\xc1\xbb\xc3\x99\xe3\x61\x9d\x41\x68\x49\x7a\x7e\x5d\x3d\xe1\x32\x6d\xe7\x43\x2f\x22\x60\xcf\xa7\xac\x27\x64\x07\x75\x42\xf5\xc7\x97\x12\xb2\xe7\x53\x66\x43\x76\x75\xf5\xf5\xea\xff\x01\x00\x00\xff\xff\xad\xc0\x83\x15\xe7\x3d\x00\x00")
+var _wski18nResourcesEn_usAllJson = 
[]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5b\x4d\x6f\xdc\x38\x12\xbd\xfb\x57\x14\x72\xe9\x8b\xa1\x4d\x66\xb1\xc0\x22\xb7\x60\x93\x99\x35\x66\x62\x1b\xb6\x77\x82\xc1\x6c\x30\x66\x4b\xa5\x16\xa7\x25\x52\x20\x29\x3b\x3d\x42\xff\xf7\x05\x49\xa9\x3f\x6c\x8a\xa2\xd4\xea\xb6\x11\xac\x4f\x72\x4b\xf5\xde\xab\xe2\x57\x15\x45\xfd\x7e\x06\x50\x9f\x01\x00\xbc\xa1\xc9\x9b\xf7\xf0\xa6\x90\x8b\x3f\x4a\x81\x29\xfd\xf6\x07\x0a\xc1\xc5\x9b\x73\x7b\x57\x09\xc2\x64\x4e\x14\xe5\x4c\x3f\xf6\xc9\xdc\x3b\x03\x58\x9f\x7b\x10\x1e\x89\x60\x94\x2d\x3a\x30\xbe\x34\x77\xfb\x50\x64\x15\xc7\x28\x65\x07\xca\x6d\x73\xb7\x0f\x85\xb2\x94\x77\x40\x5c\xe8\x5b\x4e\xfb\xcf\x54\x4a\xca\x16\x10\x17\x09\x2c\x71\xd5\x61\xdf\x3e\x35\x8b\x8b\x64\x06\x94\x95\x95\x32\x4f\x3b\x21\x49\xa5\x32\x2e\xe8\x5f\xc6\x1a\xee\x7f\xfe\xf4\xdb\x7d\x07\xac\xeb\x49\x27\xe4\x63\x46\xe5\x12\x3e\x5c\x5f\xc0\xfd\xbf\xaf\x6e\xef\xba\xf0\x9e\x3d\xe6\x04\x63\xa4\x40\x59\x92\x18\x3b\x50\xb6\xf7\xfb\xb4\xfc\xfa\xe9\xe6\xf6\xe2\xea\x32\x40\xce\xe6\x49\x77\x23\x10\x46\x53\x94\x0a\x52\x9a\x23\x30\xae\x20\xe5\x15\x4b\x80\x28\x28\x89\xca\xa0\xae\xa3\x52\xf0\x3f\x31\x56\xd7\x44\x65\xeb\x75\xf4\x5f\xd6\xd5\x50\x23\x90\xbc\xfd\xa2\xae\xa3\x15\x29\xf2\xf5\xfa\x6f\xfa\x4a\x5f\x18\xe8\x08\x26\xd4\x7c\x0c\xaa\x80\x38\x53\xb9\x8f\xa5\x32\xb4\x78\xbf\xd7\x75\xa4\x9f\xb0\x68\x5f\x43\xa3\x3d\x04\xcf\x29\xef\x3f\x6d\x18\x8a\x06\xd7\x1a\x40\xca\x05\x24\x58\xe6\x7c\x55\x20\x53\xdd\x72\xc2\xed\x07\xd3\x57\xec\x50\x01\x4f\x11\x9c\x12\x74\xc8\x44\xc5\x14\x2d\x36\xe1\x94\x55\x59\x72\xa1\x30\x81\xf9\x0a\xae\x4a\x64\x76\x54\x95\x39\x51\x29\x17\x45\xb7\x98\x71\x58\x4e\x59\x5f\x3e\xdc\x5c\x5e\x5c\xfe\xf4\x1e\x6e\x1a\x3c\x59\x62\x4c\x53\x8a\x09\x50\x06\xad\xb3\xf0\xdb\x87\xcf\xbf\x68\xef\x1b\xd6\xf5\x1a\x12\x8e\x96\xb9\x20\x2a\xce\xe0\x91\xaa\x0c\x48\x6c\x66\x3b\xc9\x2b\x11\xa3\xed\x39\xf8\x4d\x21\x93\xfa\xd7\xba\x8e\xf0\x9b\x6a\x42\xd6\x3c\x59\xd7\x91\xbd\xf2\x0d\xa2\x57\x25\xd1\x1f\xc4\x2f\x26\xe8\x1f\x4d\x6f\x80\x8c\x48\x88\x33\x2e\x91\x01\x29\x4b\xc1\x4b\x41\x89\xda\x36\xdc\x9e\xd4\x39\x91\x98\x00\x67\x66\x64\x79\x35\x6a\x69\x2a\x23\x6a\x5c\x08\x5f\x5e\xe0\xb4\xbd\xb0\xab\xf7\x5b\x3f\x25\x8a\x07\x14\x8d\x22\x3c\x4d\xa7\x9b\x40\x91\x7b\x0a\x63\x5b\xc8\xb6\x85\xd4\xaa\xc4\x73\x90\xa8\x40\x71\x60\x3c\xc1\x3f\xbb\x12\xad\x50\x6b\x27\xf5\x9d\x56\x5a\xa9\x0c\x99\xa2\xb1\x4d\x68\x96\xb8\x6a\x3d\x8d\x39\x4b\xe9\xa2\x12\x98\x74\x47\x73\x08\x42\xa7\x04\x9d\x6d\x64\x5c\xaa\xa1\xc4\x7e\xbb\x4e\xba\x4d\xae\x34\x94\xaf\xc7\x30\xc8\x3f\xdd\x23\x4a\xaa\xff\x5b\xaf\xcf\x21\x15\xbc\x68\x7e\xb2\x63\xce\xd7\x73\x47\x41\x79\xdb\xbd\x6d\x2b\x89\x6a\x07\xa0\x52\x59\x98\x98\x60\x88\xb0\xa6\xa8\xeb\x68\xf3\xff\xae\x47\x9b\x1f\xc3\x54\x8d\xc7\x74\xca\xfc\x91\xd0\x1c\x13\x3d\x92\x16\x68\xf3\xa3\x67\x03\x4e\x5a\xd8\xfd\xc9\x80\xc6\xf8\xde\xac\x3b\x42\xf8\x14\x4f\x06\xef\x14\x7f\xab\x88\x30\xb3\x40\xc5\x0a\x22\x64\x46\xf2\x9d\x14\x42\xd7\x5e\x16\x3a\xe7\x31\xc9\xe1\x81\xe4\x15\xca\x6e\xa9\x23\xc1\x3a\x26\x3d\x1f\x04\x65\x0a\x05\x43\x5f\xd6\x16\x6c\xef\xa4\xff\xb8\x49\xeb\x20\xe6\x45\x99\xa3\x0e\x77\x53\xd1\xa6\x55\x9e\xaf\xba\x99\x83\x4c\x9d\xa4\x3f\x71\x05\xa6\x7a\x87\x58\x20\x51\x3a\xed\x2c\x49\xbc\x24\x0b\xb4\x19\x8c\xbd\x57\xa0\x94\x64\xb1\xd3\xb8\x40\x58\xd2\xda\xf1\xc4\xde\xd0\x17\xbe\x5e\x75\x14\xaa\x50\xa7\x9a\xb5\xef\xfb\xf2\xa9\xa4\xa7\x70\xe8\x30\x9a\x50\x67\x44\x95\x9f\xa4\xcb\x1d\xc8\xd3\xe3\x8e\x44\x65\x58\xcc\x9c\xa9\x88\xaa\x24\xf0\xf4\xd8\xbe\x1d\x85\x34\xb4\xdd\x94\xa0\x8b\x05\x8a\x53\x34\xdd\xe1\x54\x43\x9d\x4a\x11\x93\x53\x7a\x76\x20\xdf\xd0\x19\x7e\x4e\x59\xa2\xff\x3f\xe1\xac\x78\x38\x65\xdf\xda\xc9\x53\x48\xb0\x44\x96\x20\x8b\x57\xda\x34\xc1\xf2\x92\xd8\x12\x9d\x26\x4d\x8a\x6c\xd7\x48\xbd\x44\x6e\x56\x48\x5d\x7b\xc1\xfd\xa3\x5c\xda\xed\x95\xcd\x3e\xcb\xbd\xce\x2e\x04\x16\xfc\x01\xa1\x24\x42\x51\x92\xe7\xab\x66\x1b\x08\x13\x20\x52\xa2\xf2\x24\x28\xaf\x41\x99\x27\x64\x3b\x6b\x63\x5d\x47\xbc\x52\x65\xa5\xd6\x6b\x88\xa2\xc8\xeb\x8f\xc7\xac\x87\xcc\x4c\x4b\x43\xa9\x9c\x46\x3d\x44\x7b\x63\x6a\x28\xa1\xd7\xb8\x87\xb8\xed\xea\x43\x39\xbb\xec\x02\xe9\xda\x91\x35\x96\xb6\xcb\xbe\x87\x7e\xbf\x47\x0f\x62\xf6\x98\x3a\x49\xaf\x7e\x8e\xe0\x5f\x84\xc5\x98\xe7\x8d\x79\xef\x46\xaa\xd7\xa4\x87\x44\x1b\x84\x6d\xd7\xfa\x6d\x3a\x6a\x8d\xed\x43\xfe\xd1\xef\x29\x37\x06\x40\xf4\xcd\x9a\x76\x1a\x19\x51\x6f\x74\x19\xbe\x5e\xaf\x5b\x84\xe7\x5d\x70\x3b\x1f\x77\x77\xdf\x50\xeb\x7e\xff\xc7\x2e\x07\x61\xa1\x39\x00\xbd\x27\x8d\x48\x30\xc7\xd3\xd4\x54\xd3\x31\x85\xba\x74\xe4\x4c\x7d\x2a\x9e\xff\x57\x21\x4f\xe2\x79\xfc\x2a\x64\x42\xaa\xa1\x4e\x1d\xb9\x0a\x99\x9a\x2f\xd4\xbd\xe3\xef\x33\x4d\x48\xe5\x7f\x91\x74\x97\x21\xcc\xec\xae\xed\xcc\xbe\xa5\x31\x3b\xd0\x6c\x13\x52\x64\x8a\x2a\xb3\x27\x9d\x60\x29\x30\x26\x0a\x93\x08\xae\x73\x24\x12\xa1\x92\x08\x33\x1d\xf4\x19\x50\x26\x15\x12\x9d\xbb\x43\x82\x32\x16\x74\x6e\x5f\x01\x35\xef\x83\xec\xdb\x0c\x4f\xb5\xf1\x92\x8a\x42\xdb\xbd\x4d\x34\x4f\xd8\xfe\xd3\x51\x76\xe5\x51\xae\x44\x36\x23\x12\xe6\x88\x6c\x2f\x37\xda\xd4\x67\xde\xec\x6a\x1c\x9c\x53\xdc\xb5\x27\xbf\x1f\xab\xf0\x30\x4c\xaf\xcc\x29\xe5\x4d\x20\xeb\xae\x19\x2e\x53\xc8\x1a\x87\xe5\x95\xf5\xac\x3e\x3d\x54\xdb\x08\x40\xa7\xc0\x9b\xa7\x15\xfb\x58\x61\x23\x80\x9c\x82\x3e\x3c\xdf\xad\x18\x2b\x69\x14\x54\xc0\xc4\xb1\xcd\xd0\xdd\x70\x6d\x61\x19\x3e\x77\x0c\x43\xec\x1b\x00\xcd\xd2\xb1\x8b\xd6\x54\x7f\x41\x7d\xde\x6f\xee\xed\x45\x3a\x8b\x1c\x44\x1b\x60\xd8\xd3\x4b\xda\x23\x12\x03\x48\x03\x8d\x7b\xde\xe8\x52\xf6\xc0\x97\x68\xd2\x68\x9b\x88\x65\xc8\x4e\x94\x13\x9e\x58\x84\x3f\xa7\xfa\x4c\x58\x42\x14\x17\x2b\x48\x29\xe6\x09\xb4\x93\xfa\xaf\x28\xcc\xc9\x9f\xa2\x92\x0a\xe6\xa8\xeb\x8e\x80\x7c\x68\x20\x9a\x5f\xda\x53\xe3\xf6\x14\x0e\x79\xb0\xb9\x91\x0e\x5b\x5c\x09\xa1\xeb\xf0\xed\xb6\xed\x83\x7d\x3a\x40\xec\xc1\xf8\xe3\x22\xfb\x0b\x8d\x91\x49\x9c\x28\xb2\x1d\x68\x61\x91\x6d\x8d\x8f\x15\xd9\xd1\xf8\x7e\xf9\x2d\x6c\x5d\x47\xb9\xbd\xbc\xf8\xb8\x3d\xa5\x45\xe0\x81\xe4\x34\x01\xce\x30\x40\xea\x20\x2c\xf7\x91\x76\x2c\xb8\x58\xdd\xd2\xbf\x50\x57\xe2\x39\x2d\xa8\x92\x7b\xe7\xc9\x64\xc6\xab\x3c\xd1\x8d\x43\x98\x39\x9f\xa0\x07\xf5\x1c\xd5\xa3\x9e\xb1\xde\xfd\xf0\x4f\x33\x7c\xff\xf1\xee\x87\x6e\xb5\x93\x52\xb8\x4f\xb2\xd2\x02\x79\xa5\x46\xc1\xbf\x7d\x6b\xe0\xff\xfe\x56\xff\x79\x0e\xb8\x4e\x49\xe1\x74\x22\xe7\x8b\xb1\x31\xb2\xf8\xef\x3c\xf2\x27\x02\xf7\xf7\xec\x0b\x66\xfb\x9b\x61\xb0\x67\xea\x66\x4d\xdc\x66\x9a\xb9\xd9\xa1\xdb\x65\xa6\x12\xe8\x82\x71\xb1\x53\x57\xc6\x19\xc6\x4b\xbb\x20\x84\x14\xb1\xc7\x21\x1d\xee\xe8\xb6\x97\x9f\xd6\xd7\x49\x78\x87\xbb\xdb\x74\xa8\xd3\xfa\x7a\x38\x69\xdf\xd4\x6c\x86\x86\x9d\x4e\x0b\xaa\x98\xcd\x8b\x37\xa7\x26\x33\xc2\x16\x64\x9e\x23\x10\x69\x4f\xa8\x3e\x9e\xc3\x63\x46\xcd\x49\xee\x3c\xd7\xe3\xa7\xe5\x0f\x99\xba\x27\xe4\x72\xba\x65\x3e\x87\xe0\xa9\x59\xaf\xa2\x25\xae\xcc\xb1\xe8\x0e\x59\xee\x67\xfb\x61\x63\x14\x2a\x18\x77\xfb\xb0\xf7\x5c\x65\xfb\x3c\x29\xcb\xbc\x3d\x9b\x6b\xce\x87\x9a\x3a\xc5\xbe\x56\xd2\x8b\x1c\xdb\x79\x55\x67\x8f\x7c\x13\x65\x3e\xff\xd8\xfe\xfc\x23\xd5\xa9\xfd\xd7\xa7\xe7\xee\x55\x10\x53\xfb\xc1\xc9\xda\x92\x15\x7b\xdf\x9f\x34\x54\xed\x8f\x0d\x51\xd7\x0b\xa1\xef\xc2\x35\xff\xd8\xd9\x25\x72\xe8\x37\x9d\x56\x72\xce\x74\xcf\xdd\xee\x26\x9e\x43\xb9\xdd\x4d\x6c\xbe\x2b\x6a\xb7\x13\x03\x06\xd1\x71\x48\x07\x39\xba\x1f\xbb\x93\xb8\x39\x09\x65\xe0\xbb\x47\x7b\x4c\xd4\x6c\x04\x53\x94\xde\xd7\x82\x90\x54\x42\x57\x7e\x05\x61\x64\x81\xc9\xee\x8b\xf4\x23\x9d\x9b\x79\xb5\x72\xdd\xe5\xbb\xf9\x56\xcd\xfd\x91\x45\x33\xb5\x9b\x9d\x76\xeb\x83\x39\x0f\xbc\x5b\x6a\xb4\x6d\xb8\xfd\x00\xcf\x35\x78\x37\x38\x73\xdc\x3d\x67\xe0\x5b\x92\x5e\x5e\x57\x4f\xb8\x94\x6b\x7f\xe8\x55\x04\xec\xe5\x94\xf5\x84\x6c\xe7\x9c\x50\x73\xf9\x5a\x42\xf6\x72\xca\x74\xc8\xce\xce\xbe\x9e\xfd\x2f\x00\x00\xff\xff\xa6\x69\x1e\xd2\xa5\x3e\x00\x00")
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
        return bindataRead(
@@ -130,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
15847, mode: os.FileMode(420), modTime: time.Unix(1513194493, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 
16037, mode: os.FileMode(420), modTime: time.Unix(1514922051, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -150,7 +132,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -170,7 +152,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 
101, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 
101, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -190,7 +172,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -210,7 +192,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -230,7 +212,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -250,7 +232,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 
0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -270,7 +252,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
@@ -290,7 +272,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
                return nil, err
        }
 
-       info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1501631495, 0)}
+       info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", 
size: 0, mode: os.FileMode(420), modTime: time.Unix(1505354770, 0)}
        a := &asset{bytes: bytes, info: info}
        return a, nil
 }
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index cb49feb5..62caf09e 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -1,7 +1,19 @@
 [
   {
-    "id": "Hello",
-    "translation": "An API host must be provided."
+    "id": "msg_prefix_error",
+    "translation": "Error"
+  },
+  {
+    "id": "msg_prefix_warning",
+    "translation": "Warning"
+  },
+  {
+    "id": "msg_prefix_success",
+    "translation": "Success"
+  },
+  {
+    "id": "msg_prefix_info",
+    "translation": "Info"
   },
   {
     "id": "Missing cmd key",
diff --git a/wskprint/console.go b/wskprint/console.go
new file mode 100644
index 00000000..284827b0
--- /dev/null
+++ b/wskprint/console.go
@@ -0,0 +1,83 @@
+/*
+ * 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 wskprint
+
+import (
+       "fmt"
+       "github.com/apache/incubator-openwhisk-wskdeploy/wski18n"
+       "github.com/fatih/color"
+       "github.com/mattn/go-colorable"
+)
+
+const(
+       STR_PREFIXED_MESSAGE = "%s: %s"
+
+       // IDs match those used to look up i18n strings from en_US.all.json
+       ID_I18B_PREFIX_ERROR    = "msg_prefix_error"
+       ID_I18B_PREFIX_WARNING  = "msg_prefix_warning"
+       ID_I18B_PREFIX_SUCCESS  = "msg_prefix_success"
+       ID_I18B_PREFIX_INFO     = "msg_prefix_info"
+)
+
+func PrintOpenWhiskError(message string) {
+       outputStream := colorable.NewColorableStderr()
+       fmsg := fmt.Sprintf( STR_PREFIXED_MESSAGE, 
wski18n.T(ID_I18B_PREFIX_ERROR), message)
+       fmt.Fprintf(outputStream, color.RedString(fmsg))
+}
+
+func PrintlnOpenWhiskError(message string) {
+       PrintOpenWhiskError(message + "\n")
+}
+
+func PrintOpenWhiskFromError(err error) {
+       PrintOpenWhiskError(err.Error())
+}
+
+func PrintOpenWhiskWarning(message string) {
+       outputStream := colorable.NewColorableStdout()
+       fmsg := fmt.Sprintf( STR_PREFIXED_MESSAGE, 
wski18n.T(ID_I18B_PREFIX_WARNING), message)
+       fmt.Fprintf(outputStream, color.YellowString(fmsg))
+}
+
+func PrintlnOpenWhiskWarning(message string) {
+       PrintOpenWhiskWarning(message + "\n")
+}
+
+func PrintOpenWhiskSuccess(message string) {
+       outputStream := colorable.NewColorableStdout()
+       fmsg := fmt.Sprintf( STR_PREFIXED_MESSAGE, 
wski18n.T(ID_I18B_PREFIX_SUCCESS), message)
+       fmt.Fprintf(outputStream, color.GreenString(fmsg))
+}
+
+func PrintlnOpenWhiskSuccess(message string) {
+       PrintOpenWhiskSuccess(message + "\n")
+}
+
+func PrintOpenWhiskStatus(message string) {
+       outputStream := colorable.NewColorableStdout()
+       fmsg := fmt.Sprintf( STR_PREFIXED_MESSAGE, 
wski18n.T(ID_I18B_PREFIX_INFO), message)
+       fmt.Fprintf(outputStream, color.CyanString(fmsg))
+}
+
+func PrintlnOpenWhiskStatus(message string) {
+       PrintOpenWhiskStatus(message + "\n")
+}
+
+func PrintlnOpenWhiskOutput(message string) {
+       fmt.Println(message)
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to