Added Copyright headers.
[src/xds/xds-cli.git] / main.go
diff --git a/main.go b/main.go
index 508bbdd..1c0d886 100644 (file)
--- a/main.go
+++ b/main.go
@@ -1,4 +1,23 @@
-// xds-cli: command line tool used to control / interface X(cross) Development System.
+/*
+ * Copyright (C) 2017 "IoT.bzh"
+ * Author Sebastien Douheret <sebastien@iot.bzh>
+ *
+ * Licensed 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.
+ *
+ *
+ * xds-cli: command line tool used to control / interface X(cross) Development System.
+ */
+
 package main
 
 import (
@@ -37,7 +56,7 @@ var AppSubVersion = "unknown-dev"
 
 // Application details
 const (
-       appCopyright    = "Apache-2.0"
+       appCopyright    = "Copyright (C) 2017 IoT.bzh - Apache-2.0"
        defaultLogLevel = "error"
 )
 
@@ -62,7 +81,7 @@ func exitError(code int, f string, a ...interface{}) {
 
 // main
 func main() {
-       EnvConfFileMap := make(map[string]string)
+       var earlyDebug []string
 
        // Allow to set app name from cli (useful for debugging)
        if AppName == "" {
@@ -76,16 +95,25 @@ func main() {
        }
        appUsage := fmt.Sprintf("command line tool for X(cross) Development System.")
        appDescription := fmt.Sprintf("%s utility for X(cross) Development System\n", AppName)
-       /* SEB UPDATE DOC
-               appDescription += `
-          xds-cli configuration is driven either by environment variables or by command line
-          options or using a config file knowning that the following priority order is used:
-            1. use option value (for example use project ID set by --id option),
-            2. else use variable 'XDS_xxx' (for example 'XDS_PROJECT_ID' variable) when a
-               config file is specified with '--config|-c' option,
-            3. else use 'XDS_xxx' (for example 'XDS_PROJECT_ID') environment variable.
-       `
-       */
+       appDescription += `
+    Setting of global options is driven either by environment variables or by command
+    line options or using a config file knowning that the following priority order is used:
+      1. use option value (for example --url option),
+      2. else use variable 'XDS_xxx' (for example 'XDS_SERVER_URL' variable) when a
+         config file is specified with '--config|-c' option,
+      3. else use 'XDS_xxx' (for example 'XDS_SERVER_URL') environment variable.
+
+    Examples:
+    # Get help of 'projects' sub-command
+    ` + AppName + ` projects --help
+
+    # List all SDKs
+    ` + AppName + ` sdks ls
+
+    # Add a new project
+    ` + AppName + ` prj add --label="myProject" --type=cs --path=$HOME/xds-workspace/myProject
+`
+
        // Create a new App instance
        app := cli.NewApp()
        app.Name = AppName
@@ -134,7 +162,7 @@ func main() {
                        Value:  defaultLogLevel,
                },
                cli.StringFlag{
-                       Name:   "url",
+                       Name:   "url, u",
                        EnvVar: "XDS_SERVER_URL",
                        Value:  "localhost:8000",
                        Usage:  "remote XDS server url",
@@ -157,24 +185,47 @@ func main() {
        sort.Sort(cli.FlagsByName(app.Flags))
        sort.Sort(cli.CommandsByName(app.Commands))
 
+       // Early and manual processing of --config option in order to set XDS_xxx
+       // variables before parsing of option by app cli
+       confFile := os.Getenv("XDS_CONFIG")
+       for idx, a := range os.Args[1:] {
+               if a == "-c" || a == "--config" || a == "-config" {
+                       confFile = os.Args[idx+2]
+                       break
+               }
+       }
+
+       // Load config file if requested
+       if confFile != "" {
+               earlyDebug = append(earlyDebug, fmt.Sprintf("confFile detected: %v", confFile))
+               if !common.Exists(confFile) {
+                       exitError(1, "Error env config file not found")
+               }
+               // Load config file variables that will overwrite env variables
+               err := godotenv.Overload(confFile)
+               if err != nil {
+                       exitError(1, "Error loading env config file "+confFile)
+               }
+
+               // Keep confFile settings in a map
+               EnvConfFileMap, err = godotenv.Read(confFile)
+               if err != nil {
+                       exitError(1, "Error reading env config file "+confFile)
+               }
+               earlyDebug = append(earlyDebug, fmt.Sprintf("EnvConfFileMap: %v", EnvConfFileMap))
+       }
+
        app.Before = func(ctx *cli.Context) error {
                var err error
 
-               // Load config file if requested
-               confFile := ctx.String("config")
-               if confFile != "" {
-                       if !common.Exists(confFile) {
-                               exitError(1, "Error env config file not found")
-                       }
-                       // Load config file variables that will overwrite env variables
-                       err := godotenv.Overload(confFile)
-                       if err != nil {
-                               exitError(1, "Error loading env config file "+confFile)
-                       }
-                       // Keep confFile settings in a map
-                       EnvConfFileMap, err = godotenv.Read(confFile)
-                       if err != nil {
-                               exitError(1, "Error reading env config file "+confFile)
+               // Don't init anything when no argument or help option is set
+               if ctx.NArg() == 0 {
+                       return nil
+               }
+               for _, a := range ctx.Args() {
+                       switch a {
+                       case "-h", "--h", "-help", "--help":
+                               return nil
                        }
                }
 
@@ -187,7 +238,10 @@ func main() {
                Log.Formatter = &logrus.TextFormatter{}
 
                Log.Infof("%s version: %s", AppName, app.Version)
-               Log.Debugf("Environment: %v", os.Environ())
+               for _, str := range earlyDebug {
+                       Log.Infof("%s", str)
+               }
+               Log.Debugf("\nEnvironment: %v\n", os.Environ())
 
                if err = XdsConnInit(ctx); err != nil {
                        // Directly call HandleExitCoder to avoid to print help (ShowAppHelp)
@@ -212,8 +266,15 @@ func XdsConnInit(ctx *cli.Context) error {
 
        // Define HTTP and WS url
        baseURL := ctx.String("url")
-       if !strings.HasPrefix(ctx.String("url"), "http://") {
-               baseURL = "http://" + ctx.String("url")
+
+       // Allow to only set port number
+       if match, _ := regexp.MatchString("^([0-9]+)$", baseURL); match {
+               baseURL = "http://localhost:" + ctx.String("url")
+       }
+
+       // Add http prefix if missing
+       if !strings.HasPrefix(baseURL, "http://") {
+               baseURL = "http://" + baseURL
        }
 
        // Create HTTP client
@@ -237,6 +298,7 @@ func XdsConnInit(ctx *cli.Context) error {
                return cli.NewExitError(errmsg, 1)
        }
        HTTPCli.SetLogLevel(ctx.String("loglevel"))
+       Log.Infoln("HTTP session ID : ", HTTPCli.GetClientID())
 
        // Create io Websocket client
        Log.Debugln("Connecting IO.socket client on ", baseURL)