From 29763f2b1d10aec7ad9839c86bdffca27aeea090 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 26 Jan 2018 07:51:43 +0100 Subject: [PATCH 1/9] Add configuration setting to set proxy server Signed-off-by: Hanno Braun --- config.ini | 1 + main.go | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/config.ini b/config.ini index eec98cd7a..2dbc36b07 100644 --- a/config.ini +++ b/config.ini @@ -8,3 +8,4 @@ appName = CreateBridge updateUrl = http://downloads.arduino.cc/ #updateUrl = http://localhost/ origins = http://webide.arduino.cc:8080 +#httpProxy = http://your.proxy:port # Proxy server for HTTP requests diff --git a/main.go b/main.go index 58a3c359b..95a88e6c2 100755 --- a/main.go +++ b/main.go @@ -47,6 +47,7 @@ var ( Tools tools.Tools indexURL = flag.String("indexURL", "https://downloads.arduino.cc/packages/package_staging_index.json", "The address from where to download the index json containing the location of upload tools") requiredToolsAPILevel = "v1" + httpProxy = flag.String("httpProxy", "", "Proxy server for HTTP requests") ) type NullWriter int @@ -124,6 +125,21 @@ func main() { iniflags.Parse() } + // If the httpProxy setting is set, use its value to override the + // HTTP_PROXY environment variable. Setting this environment + // variable ensures that all HTTP requests using net/http use this + // proxy server. + if *httpProxy != "" { + log.Printf("Setting HTTP_PROXY variable to %v", *httpProxy) + err := os.Setenv("HTTP_PROXY", *httpProxy) + if err != nil { + // The os.Setenv documentation doesn't specify how it can + // fail, so I don't know how to handle this error + // appropriately. + panic(err) + } + } + // move CORS to config file compatibility, Vagrant version if *origins == "" { log.Println("Patching config.ini for compatibility") From db4513e79e20f403708ed68cc00dc3265544f7ca Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Wed, 25 Jul 2018 11:02:01 +0200 Subject: [PATCH 2/9] Add httpsProxy variable --- main.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/main.go b/main.go index 7ad06cd32..ba8616340 100755 --- a/main.go +++ b/main.go @@ -49,6 +49,7 @@ var ( indexURL = flag.String("indexURL", "https://downloads.arduino.cc/packages/package_staging_index.json", "The address from where to download the index json containing the location of upload tools") requiredToolsAPILevel = "v1" httpProxy = flag.String("httpProxy", "", "Proxy server for HTTP requests") + httpsProxy = flag.String("httpsProxy", "", "Proxy server for HTTPS requests") ) type NullWriter int @@ -141,6 +142,17 @@ func main() { } } + if *httpsProxy != "" { + log.Printf("Setting HTTPS_PROXY variable to %v", *httpProxy) + err := os.Setenv("HTTPS_PROXY", *httpProxy) + if err != nil { + // The os.Setenv documentation doesn't specify how it can + // fail, so I don't know how to handle this error + // appropriately. + panic(err) + } + } + // move CORS to config file compatibility, Vagrant version if *origins == "" { log.Println("Patching config.ini for compatibility") From b60aa54db68385d0d7d050b0eb55403a347f99cd Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Wed, 25 Jul 2018 12:56:56 +0200 Subject: [PATCH 3/9] Handle config better Eliminated iniflags, used a flagset to handle inheritance of config. Changing config restarts the process (so that it can be instantiated again) --- config.ini | 3 +- hub.go | 13 +- info.go | 12 +- main.go | 424 ++++++++++-------- trayicon.go | 16 +- .../github.com/vharitonsky/iniflags/LICENSE | 23 - .../github.com/vharitonsky/iniflags/README.md | 141 ------ .../vharitonsky/iniflags/iniflags.go | 409 ----------------- .../vharitonsky/iniflags/test_bom.ini | 1 - .../vharitonsky/iniflags/test_config.ini | 8 - .../vharitonsky/iniflags/test_config2.ini | 3 - .../iniflags/test_setconfigfile.ini | 1 - vendor/vendor.json | 5 - 13 files changed, 247 insertions(+), 812 deletions(-) delete mode 100644 vendor/github.com/vharitonsky/iniflags/LICENSE delete mode 100644 vendor/github.com/vharitonsky/iniflags/README.md delete mode 100644 vendor/github.com/vharitonsky/iniflags/iniflags.go delete mode 100644 vendor/github.com/vharitonsky/iniflags/test_bom.ini delete mode 100644 vendor/github.com/vharitonsky/iniflags/test_config.ini delete mode 100644 vendor/github.com/vharitonsky/iniflags/test_config2.ini delete mode 100644 vendor/github.com/vharitonsky/iniflags/test_setconfigfile.ini diff --git a/config.ini b/config.ini index fa12c9b2a..3c4348aa2 100644 --- a/config.ini +++ b/config.ini @@ -1,8 +1,7 @@ -configUpdateInterval = 0 # Update interval for re-reading config file set via -config flag. Zero disables config file re-reading. gc = std # Type of garbage collection. std = Normal garbage collection allowing system to decide (this has been known to cause a stop the world in the middle of a CNC job which can cause lost responses from the CNC controller and thus stalled jobs. use max instead to solve.), off = let memory grow unbounded (you have to send in the gc command manually to garbage collect or you will run out of RAM eventually), max = Force garbage collection on each recv or send on a serial port (this minimizes stop the world events and thus lost serial responses, but increases CPU usage) hostname = unknown-hostname # Override the hostname we get from the OS -ls = false # launch self 5 seconds later regex = usb|acm|com # Regular expression to filter serial port list v = true # show debug logging appName = CreateBridge updateUrl = http://downloads.arduino.cc/ +origins = http://downloads.arduino.cc/ diff --git a/hub.go b/hub.go index 45aacffd0..9b0744970 100755 --- a/hub.go +++ b/hub.go @@ -276,7 +276,7 @@ func exit() { } -func restart(path string) { +func restart(path string, args ...string) { log.Println("called restart", path) quitSysTray() // relaunch ourself and exit @@ -302,14 +302,9 @@ func restart(path string) { exePath = strings.Trim(exePath, "\n") - hiberString := "" - if *hibernate == true { - hiberString = "-hibernate" - } - - cmd := exec.Command(exePath, "-ls", "-regex", *regExpFilter, "-gc", *gcType, hiberString) - - fmt.Println(cmd) + args = append(args, "-ls") + args = append(args, "-hibernate="+fmt.Sprint(*hibernate)) + cmd := exec.Command(exePath, args...) err := cmd.Start() if err != nil { diff --git a/info.go b/info.go index 8a84e479a..ad694fc47 100644 --- a/info.go +++ b/info.go @@ -13,12 +13,12 @@ func infoHandler(c *gin.Context) { host = parts[0] c.JSON(200, gin.H{ - "version": version, - "http": "http://" + host + port, - "https": "https://localhost" + portSSL, - "ws": "ws://" + host + port, - "wss": "wss://localhost" + portSSL, - "origins": origins, + "version": version, + "http": "http://" + host + port, + "https": "https://localhost" + portSSL, + "ws": "ws://" + host + port, + "wss": "wss://localhost" + portSSL, + "origins": origins, "update_url": updateUrl, }) } diff --git a/main.go b/main.go index 6f36328d8..3fdc8177e 100755 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ package main import ( "encoding/json" "flag" + "fmt" "os" "os/user" "path/filepath" @@ -15,13 +16,14 @@ import ( "text/template" "time" + "github.com/go-ini/ini" + log "github.com/Sirupsen/logrus" "github.com/arduino/arduino-create-agent/tools" "github.com/arduino/arduino-create-agent/utilities" "github.com/gin-gonic/gin" cors "github.com/itsjamie/gin-cors" "github.com/kardianos/osext" - "github.com/vharitonsky/iniflags" //"github.com/sanbornm/go-selfupdate/selfupdate" #included in update.go to change heavily ) @@ -29,27 +31,40 @@ var ( version = "x.x.x-dev" //don't modify it, Jenkins will take care git_revision = "xxxxxxxx" //don't modify it, Jenkins will take care embedded_autoextract = false - hibernate = flag.Bool("hibernate", false, "start hibernated") - verbose = flag.Bool("v", true, "show debug logging") - isLaunchSelf = flag.Bool("ls", false, "launch self 5 seconds later") - configIni = flag.String("configFile", "config.ini", "config file path") - regExpFilter = flag.String("regex", "usb|acm|com", "Regular expression to filter serial port list") - gcType = flag.String("gc", "std", "Type of garbage collection. std = Normal garbage collection allowing system to decide (this has been known to cause a stop the world in the middle of a CNC job which can cause lost responses from the CNC controller and thus stalled jobs. use max instead to solve.), off = let memory grow unbounded (you have to send in the gc command manually to garbage collect or you will run out of RAM eventually), max = Force garbage collection on each recv or send on a serial port (this minimizes stop the world events and thus lost serial responses, but increases CPU usage)") - logDump = flag.String("log", "off", "off = (default)") - hostname = flag.String("hostname", "unknown-hostname", "Override the hostname we get from the OS") - updateUrl = flag.String("updateUrl", "", "") - appName = flag.String("appName", "", "") - genCert = flag.Bool("generateCert", false, "") port string portSSL string - origins = flag.String("origins", "", "Allowed origin list for CORS") - address = flag.String("address", "127.0.0.1", "The address where to listen. Defaults to localhost") - signatureKey = flag.String("signatureKey", "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvc0yZr1yUSen7qmE3cxF\nIE12rCksDnqR+Hp7o0nGi9123eCSFcJ7CkIRC8F+8JMhgI3zNqn4cUEn47I3RKD1\nZChPUCMiJCvbLbloxfdJrUi7gcSgUXrlKQStOKF5Iz7xv1M4XOP3JtjXLGo3EnJ1\npFgdWTOyoSrA8/w1rck4c/ISXZSinVAggPxmLwVEAAln6Itj6giIZHKvA2fL2o8z\nCeK057Lu8X6u2CG8tRWSQzVoKIQw/PKK6CNXCAy8vo4EkXudRutnEYHEJlPkVgPn\n2qP06GI+I+9zKE37iqj0k1/wFaCVXHXIvn06YrmjQw6I0dDj/60Wvi500FuRVpn9\ntwIDAQAB\n-----END PUBLIC KEY-----", "Pem-encoded public key to verify signed commandlines") - Tools tools.Tools - indexURL = flag.String("indexURL", "https://downloads.arduino.cc/packages/package_staging_index.json", "The address from where to download the index json containing the location of upload tools") requiredToolsAPILevel = "v1" ) +// regular flags +var ( + hibernate = flag.Bool("hibernate", false, "start hibernated") + genCert = flag.Bool("generateCert", false, "") + additionalConfig = flag.String("additional-config", "config.ini", "config file path") + isLaunchSelf = flag.Bool("ls", false, "launch self 5 seconds later") +) + +// iniflags +var ( + iniConf = flag.NewFlagSet("ini", flag.ContinueOnError) + address = iniConf.String("address", "127.0.0.1", "The address where to listen. Defaults to localhost") + appName = iniConf.String("appName", "", "") + gcType = iniConf.String("gc", "std", "Type of garbage collection. std = Normal garbage collection allowing system to decide (this has been known to cause a stop the world in the middle of a CNC job which can cause lost responses from the CNC controller and thus stalled jobs. use max instead to solve.), off = let memory grow unbounded (you have to send in the gc command manually to garbage collect or you will run out of RAM eventually), max = Force garbage collection on each recv or send on a serial port (this minimizes stop the world events and thus lost serial responses, but increases CPU usage)") + hostname = iniConf.String("hostname", "unknown-hostname", "Override the hostname we get from the OS") + indexURL = iniConf.String("indexURL", "https://downloads.arduino.cc/packages/package_staging_index.json", "The address from where to download the index json containing the location of upload tools") + logDump = iniConf.String("log", "off", "off = (default)") + origins = iniConf.String("origins", "", "Allowed origin list for CORS") + regExpFilter = iniConf.String("regex", "usb|acm|com", "Regular expression to filter serial port list") + signatureKey = iniConf.String("signatureKey", "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvc0yZr1yUSen7qmE3cxF\nIE12rCksDnqR+Hp7o0nGi9123eCSFcJ7CkIRC8F+8JMhgI3zNqn4cUEn47I3RKD1\nZChPUCMiJCvbLbloxfdJrUi7gcSgUXrlKQStOKF5Iz7xv1M4XOP3JtjXLGo3EnJ1\npFgdWTOyoSrA8/w1rck4c/ISXZSinVAggPxmLwVEAAln6Itj6giIZHKvA2fL2o8z\nCeK057Lu8X6u2CG8tRWSQzVoKIQw/PKK6CNXCAy8vo4EkXudRutnEYHEJlPkVgPn\n2qP06GI+I+9zKE37iqj0k1/wFaCVXHXIvn06YrmjQw6I0dDj/60Wvi500FuRVpn9\ntwIDAQAB\n-----END PUBLIC KEY-----", "Pem-encoded public key to verify signed commandlines") + updateUrl = iniConf.String("updateUrl", "", "") + verbose = iniConf.Bool("v", true, "show debug logging") +) + +// global clients +var ( + Tools tools.Tools +) + type NullWriter int func (NullWriter) Write([]byte) (int, error) { return 0, nil } @@ -74,197 +89,201 @@ func launchSelfLater() { } func main() { - + // Parse regular flags flag.Parse() + // Generate certificates if *genCert == true { generateCertificates() os.Exit(0) } + fmt.Println(*hibernate) + if *hibernate == false { + // autoextract self + src, _ := osext.Executable() + dest := filepath.Dir(src) + + if embedded_autoextract { + // save the config.ini (if it exists) + if _, err := os.Stat(filepath.Join(dest, "config.ini")); os.IsNotExist(err) { + log.Println("First run, unzipping self") + err := utilities.Unzip(src, dest) + log.Println("Self extraction, err:", err) + } + } + + // Parse ini config + args, err := parseIni("config.ini") + fmt.Println(args) + if err != nil { + panic(err) + } + err = iniConf.Parse(args) + if err != nil { + panic(err) + } + + // Parse additional ini config + args, err = parseIni(*additionalConfig) + if err != nil { + panic(err) + } + iniConf.Parse(args) + + // Instantiate Tools + usr, _ := user.Current() + directory := filepath.Join(usr.HomeDir, ".arduino-create") + Tools = tools.Tools{ + Directory: directory, + IndexURL: *indexURL, + Logger: func(msg string) { + mapD := map[string]string{"DownloadStatus": "Pending", "Msg": msg} + mapB, _ := json.Marshal(mapD) + h.broadcastSys <- mapB + }, + } + Tools.Init(requiredToolsAPILevel) + + log.SetLevel(log.InfoLevel) + + log.SetOutput(os.Stderr) + + // see if we are supposed to wait 5 seconds + if *isLaunchSelf { + launchSelfLater() + } + + log.Println("Version:" + version) + + // hostname + hn, _ := os.Hostname() + if *hostname == "unknown-hostname" { + *hostname = hn + } + log.Println("Hostname:", *hostname) + + // turn off garbage collection + // this is dangerous, as u could overflow memory + //if *isGC { + if *gcType == "std" { + log.Println("Garbage collection is on using Standard mode, meaning we just let Golang determine when to garbage collect.") + } else if *gcType == "max" { + log.Println("Garbage collection is on for MAXIMUM real-time collecting on each send/recv from serial port. Higher CPU, but less stopping of the world to garbage collect since it is being done on a constant basis.") + } else { + log.Println("Garbage collection is off. Memory use will grow unbounded. You WILL RUN OUT OF RAM unless you send in the gc command to manually force garbage collection. Lower CPU, but progressive memory footprint.") + debug.SetGCPercent(-1) + } + + // see if they provided a regex filter + if len(*regExpFilter) > 0 { + log.Printf("You specified a serial port regular expression filter: %v\n", *regExpFilter) + } + + // list serial ports + portList, _ := GetList(false) + log.Println("Your serial ports:") + if len(portList) == 0 { + log.Println("\tThere are no serial ports to list.") + } + for _, element := range portList { + log.Printf("\t%v\n", element) + + } + + if !*verbose { + log.Println("You can enter verbose mode to see all logging by starting with the -v command line switch.") + log.SetOutput(new(NullWriter)) //route all logging to nullwriter + } + + // launch the hub routine which is the singleton for the websocket server + go h.run() + // launch our serial port routine + go sh.run() + // launch our dummy data routine + //go d.run() + + go discoverLoop() + + r := gin.New() + + socketHandler := wsHandler().ServeHTTP + + extraOrigins := []string{ + "https://create.arduino.cc", + "http://create.arduino.cc", "https://create-dev.arduino.cc", "http://create-dev.arduino.cc", "https://create-intel.arduino.cc", "http://create-intel.arduino.cc", + } + + for i := 8990; i < 9001; i++ { + port := strconv.Itoa(i) + extraOrigins = append(extraOrigins, "http://localhost:"+port) + extraOrigins = append(extraOrigins, "https://localhost:"+port) + extraOrigins = append(extraOrigins, "http://127.0.0.1:"+port) + } + + r.Use(cors.Middleware(cors.Config{ + Origins: *origins + ", " + strings.Join(extraOrigins, ", "), + Methods: "GET, PUT, POST, DELETE", + RequestHeaders: "Origin, Authorization, Content-Type", + ExposedHeaders: "", + MaxAge: 50 * time.Second, + Credentials: true, + ValidateHeaders: false, + })) + + r.LoadHTMLFiles("templates/nofirefox.html") + + r.GET("/", homeHandler) + r.GET("/certificate.crt", certHandler) + r.DELETE("/certificate.crt", deleteCertHandler) + r.POST("/upload", uploadHandler) + r.GET("/socket.io/", socketHandler) + r.POST("/socket.io/", socketHandler) + r.Handle("WS", "/socket.io/", socketHandler) + r.Handle("WSS", "/socket.io/", socketHandler) + r.GET("/info", infoHandler) + r.POST("/killbrowser", killBrowserHandler) + r.POST("/pause", pauseHandler) + r.POST("/update", updateHandler) go func() { - - // autoextract self - src, _ := osext.Executable() - dest := filepath.Dir(src) - - // Instantiate Tools - usr, _ := user.Current() - directory := filepath.Join(usr.HomeDir, ".arduino-create") - Tools = tools.Tools{ - Directory: directory, - IndexURL: *indexURL, - Logger: func(msg string) { - mapD := map[string]string{"DownloadStatus": "Pending", "Msg": msg} - mapB, _ := json.Marshal(mapD) - h.broadcastSys <- mapB - }, + // check if certificates exist; if not, use plain http + if _, err := os.Stat(filepath.Join(dest, "cert.pem")); os.IsNotExist(err) { + return } - Tools.Init(requiredToolsAPILevel) - - if embedded_autoextract { - // save the config.ini (if it exists) - if _, err := os.Stat(dest + "/" + *configIni); os.IsNotExist(err) { - log.Println("First run, unzipping self") - err := utilities.Unzip(src, dest) - log.Println("Self extraction, err:", err) - } - if _, err := os.Stat(dest + "/" + *configIni); os.IsNotExist(err) { - flag.Parse() - log.Println("No config.ini at", *configIni) + start := 8990 + end := 9000 + i := start + for i < end { + i = i + 1 + portSSL = ":" + strconv.Itoa(i) + if err := r.RunTLS(*address+portSSL, filepath.Join(dest, "cert.pem"), filepath.Join(dest, "key.pem")); err != nil { + log.Printf("Error trying to bind to port: %v, so exiting...", err) + continue } else { - flag.Parse() - flag.Set("config", dest+"/"+*configIni) - iniflags.Parse() + log.Print("Starting server and websocket (SSL) on " + *address + "" + port) + break } - } else { - flag.Set("config", dest+"/"+*configIni) - iniflags.Parse() - } - - log.SetLevel(log.InfoLevel) - - log.SetOutput(os.Stderr) - - // see if we are supposed to wait 5 seconds - if *isLaunchSelf { - launchSelfLater() - } - - log.Println("Version:" + version) - - // hostname - hn, _ := os.Hostname() - if *hostname == "unknown-hostname" { - *hostname = hn - } - log.Println("Hostname:", *hostname) - - // turn off garbage collection - // this is dangerous, as u could overflow memory - //if *isGC { - if *gcType == "std" { - log.Println("Garbage collection is on using Standard mode, meaning we just let Golang determine when to garbage collect.") - } else if *gcType == "max" { - log.Println("Garbage collection is on for MAXIMUM real-time collecting on each send/recv from serial port. Higher CPU, but less stopping of the world to garbage collect since it is being done on a constant basis.") - } else { - log.Println("Garbage collection is off. Memory use will grow unbounded. You WILL RUN OUT OF RAM unless you send in the gc command to manually force garbage collection. Lower CPU, but progressive memory footprint.") - debug.SetGCPercent(-1) - } - - // see if they provided a regex filter - if len(*regExpFilter) > 0 { - log.Printf("You specified a serial port regular expression filter: %v\n", *regExpFilter) } + }() - // list serial ports - portList, _ := GetList(false) - log.Println("Your serial ports:") - if len(portList) == 0 { - log.Println("\tThere are no serial ports to list.") - } - for _, element := range portList { - log.Printf("\t%v\n", element) - - } - - if !*verbose { - log.Println("You can enter verbose mode to see all logging by starting with the -v command line switch.") - log.SetOutput(new(NullWriter)) //route all logging to nullwriter - } - - // launch the hub routine which is the singleton for the websocket server - go h.run() - // launch our serial port routine - go sh.run() - // launch our dummy data routine - //go d.run() - - go discoverLoop() - - r := gin.New() - - socketHandler := wsHandler().ServeHTTP - - extraOrigins := []string{ - "https://create.arduino.cc", - "http://create.arduino.cc", "https://create-dev.arduino.cc", "http://create-dev.arduino.cc", "https://create-intel.arduino.cc", "http://create-intel.arduino.cc", - } - - for i := 8990; i < 9001; i++ { - port := strconv.Itoa(i) - extraOrigins = append(extraOrigins, "http://localhost:"+port) - extraOrigins = append(extraOrigins, "https://localhost:"+port) - extraOrigins = append(extraOrigins, "http://127.0.0.1:"+port) - } - - r.Use(cors.Middleware(cors.Config{ - Origins: *origins + ", " + strings.Join(extraOrigins, ", "), - Methods: "GET, PUT, POST, DELETE", - RequestHeaders: "Origin, Authorization, Content-Type", - ExposedHeaders: "", - MaxAge: 50 * time.Second, - Credentials: true, - ValidateHeaders: false, - })) - - r.LoadHTMLFiles("templates/nofirefox.html") - - r.GET("/", homeHandler) - r.GET("/certificate.crt", certHandler) - r.DELETE("/certificate.crt", deleteCertHandler) - r.POST("/upload", uploadHandler) - r.GET("/socket.io/", socketHandler) - r.POST("/socket.io/", socketHandler) - r.Handle("WS", "/socket.io/", socketHandler) - r.Handle("WSS", "/socket.io/", socketHandler) - r.GET("/info", infoHandler) - r.POST("/killbrowser", killBrowserHandler) - r.POST("/pause", pauseHandler) - r.POST("/update", updateHandler) - - go func() { - // check if certificates exist; if not, use plain http - if _, err := os.Stat(filepath.Join(dest, "cert.pem")); os.IsNotExist(err) { - return - } - - start := 8990 - end := 9000 - i := start - for i < end { - i = i + 1 - portSSL = ":" + strconv.Itoa(i) - if err := r.RunTLS(*address+portSSL, filepath.Join(dest, "cert.pem"), filepath.Join(dest, "key.pem")); err != nil { - log.Printf("Error trying to bind to port: %v, so exiting...", err) - continue - } else { - log.Print("Starting server and websocket (SSL) on " + *address + "" + port) - break - } - } - }() - - go func() { - start := 8990 - end := 9000 - i := start - for i < end { - i = i + 1 - port = ":" + strconv.Itoa(i) - if err := r.Run(*address + port); err != nil { - log.Printf("Error trying to bind to port: %v, so exiting...", err) - continue - } else { - log.Print("Starting server and websocket on " + *address + "" + port) - break - } + go func() { + start := 8990 + end := 9000 + i := start + for i < end { + i = i + 1 + port = ":" + strconv.Itoa(i) + if err := r.Run(*address + port); err != nil { + log.Printf("Error trying to bind to port: %v, so exiting...", err) + continue + } else { + log.Print("Starting server and websocket on " + *address + "" + port) + break } - }() - + } }() } setupSysTray() @@ -432,3 +451,26 @@ body { ` + +func parseIni(filename string) (args []string, err error) { + cfg, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: false}, filename) + + if err != nil { + return nil, err + } + + for _, section := range cfg.Sections() { + for key, val := range section.KeysHash() { + // Ignore launchself + if key == "ls" { + continue + } // Ignore configUpdateInterval + if key == "configUpdateInterval" { + continue + } + args = append(args, "-"+key, val) + } + } + + return args, nil +} diff --git a/trayicon.go b/trayicon.go index 533487623..7db774c38 100644 --- a/trayicon.go +++ b/trayicon.go @@ -31,7 +31,6 @@ package main import ( - "flag" "os" "path/filepath" "runtime" @@ -42,7 +41,6 @@ import ( "github.com/go-ini/ini" "github.com/kardianos/osext" "github.com/skratchdot/open-golang/open" - "github.com/vharitonsky/iniflags" "go.bug.st/serial.v1" ) @@ -133,7 +131,7 @@ func setupSysTrayReal() { mConfigCheckbox = append(mConfigCheckbox, entry) // decorate configs gliph := " ☐ " - if *configIni == config.Localtion { + if *additionalConfig == config.Localtion { gliph = " 🗹 " } entry.SetTitle(gliph + config.Name) @@ -150,16 +148,8 @@ func setupSysTrayReal() { go func(v int) { for { <-mConfigCheckbox[v].ClickedCh - flag.Set("config", configs[v].Localtion) - iniflags.UpdateConfig() - applyEnvironment(configs[v].Localtion) - mConfigCheckbox[v].SetTitle(" 🗹 " + configs[v].Name) - //mConfigCheckbox[v].Check() - for j, _ := range mConfigCheckbox { - if j != v { - mConfigCheckbox[j].SetTitle(" ☐ " + configs[j].Name) - } - } + + restart("", "-additional-config", configs[v].Localtion) } }(i) } diff --git a/vendor/github.com/vharitonsky/iniflags/LICENSE b/vendor/github.com/vharitonsky/iniflags/LICENSE deleted file mode 100644 index 1d12d1626..000000000 --- a/vendor/github.com/vharitonsky/iniflags/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014 vharitonsky, valyala. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. diff --git a/vendor/github.com/vharitonsky/iniflags/README.md b/vendor/github.com/vharitonsky/iniflags/README.md deleted file mode 100644 index f0138eba2..000000000 --- a/vendor/github.com/vharitonsky/iniflags/README.md +++ /dev/null @@ -1,141 +0,0 @@ -Hybrid configuration library -============================ - -Combine standard go flags with ini files. - -Usage: - -```bash - -go get -u -a github.com/vharitonsky/iniflags -``` - -main.go -```go -package main - -import ( - "flag" - ... - "github.com/vharitonsky/iniflags" - ... -) - -var ( - flag1 = flag.String("flag1", "default1", "Description1") - ... - flagN = flag.Int("flagN", 123, "DescriptionN") -) - -func main() { - iniflags.Parse() // use instead of flag.Parse() -} -``` - -dev.ini - -```ini - # comment1 - flag1 = "val1" # comment2 - - ... - [section] - flagN = 4 # comment3 -``` - -```bash - -go run main.go -config dev.ini -flagX=foobar - -``` - -Now all unset flags obtain their value from .ini file provided in -config path. -If value is not found in the .ini, flag will retain its' default value. - -Flag value priority: - - value set via command-line - - value from ini file - - default value - -Iniflags is compatible with real .ini config files with [sections] and #comments. -Sections and comments are skipped during config file parsing. - -Iniflags can #import another ini files. For example, - -base.ini -```ini -flag1 = value1 -flag2 = value2 -``` - -dev.ini -```ini -#import "base.ini" -# Now flag1="value1", flag2="value2" - -flag2 = foobar -# Now flag1="value1", while flag2="foobar" -``` - -Both -config path and imported ini files can be addressed via http -or https links: - -```bash -/path/to/app -config=https://google.com/path/to/config.ini -``` - -config.ini -```ini -# The following line will import configs from the given http link. -#import "http://google.com/path/to/config.ini" -``` - -All flags defined in the app can be dumped into stdout with ini-compatible sytax -by passing -dumpflags flag to the app. The following command creates ini-file -with all the flags defined in the app: - -```bash -/path/to/the/app -dumpflags > initial-config.ini -``` - - -Iniflags also supports two types of online config reload: - - * Via SIGHUP signal: - -```bash -kill -s SIGHUP -``` - - * Via -configUpdateInterval flag. The following line will re-read config every 5 seconds: - -```bash -/path/to/app -config=/path/to/config.ini -configUpdateInterval=5s -``` - - -Advanced usage. - -```go -package main - -import ( - "flag" - "iniflags" - "log" -) - -var listenPort = flag.Int("listenPort", 1234, "Port to listen to") - -func init() { - iniflags.OnFlagChange("listenPort", func() { - startServerOnPort(*listenPort) - }) -} - -func main() { - // iniflags.Parse() starts the server on the -listenPort via OnFlagChange() - // callback registered above. - iniflags.Parse() -} -``` diff --git a/vendor/github.com/vharitonsky/iniflags/iniflags.go b/vendor/github.com/vharitonsky/iniflags/iniflags.go deleted file mode 100644 index 0933a6b85..000000000 --- a/vendor/github.com/vharitonsky/iniflags/iniflags.go +++ /dev/null @@ -1,409 +0,0 @@ -package iniflags - -import ( - "bufio" - "flag" - "fmt" - "io" - "log" - "net/http" - "net/url" - "os" - "os/signal" - "path" - "strings" - "syscall" - "time" -) - -var ( - config = flag.String("config", "", "Path to ini config for using in go flags. May be relative to the current executable path.") - configUpdateInterval = flag.Duration("configUpdateInterval", 0, "Update interval for re-reading config file set via -config flag. Zero disables config file re-reading.") - dumpflags = flag.Bool("dumpflags", false, "Dumps values for all flags defined in the app into stdout in ini-compatible syntax and terminates the app.") -) - -var ( - flagChangeCallbacks = make(map[string][]FlagChangeCallback) - importStack []string - parsed bool -) - -// Generation is flags' generation number. -// -// It is modified on each flags' modification -// via either -configUpdateInterval or SIGHUP. -var Generation int - -// Parse obtains flag values from config file set via -config. -// -// It obtains flag values from command line like flag.Parse(), then overrides -// them by values parsed from config file set via -config. -// -// Path to config file can also be set via SetConfigFile() before Parse() call. -func Parse() { - if parsed { - panic("iniflags: duplicate call to iniflags.Parse() detected") - } - - parsed = true - flag.Parse() - _, ok := parseConfigFlags() - if !ok { - os.Exit(1) - } - - if *dumpflags { - dumpFlags() - os.Exit(0) - } - - for flagName := range flagChangeCallbacks { - verifyFlagChangeFlagName(flagName) - } - Generation++ - issueAllFlagChangeCallbacks() - - ch := make(chan os.Signal) - signal.Notify(ch, syscall.SIGHUP) - go sighupHandler(ch) - - go configUpdater() -} - -func configUpdater() { - if *configUpdateInterval != 0 { - for { - // Use time.Sleep() instead of time.Tick() for the sake of dynamic flag update. - time.Sleep(*configUpdateInterval) - UpdateConfig() - } - } -} - -func UpdateConfig() { - if oldFlagValues, ok := parseConfigFlags(); ok && len(oldFlagValues) > 0 { - modifiedFlags := make(map[string]string) - for k := range oldFlagValues { - modifiedFlags[k] = flag.Lookup(k).Value.String() - } - log.Printf("iniflags: read updated config. Modified flags are: %v\n", modifiedFlags) - Generation++ - issueFlagChangeCallbacks(oldFlagValues) - } -} - -// FlagChangeCallback is called when the given flag is changed. -// -// The callback may be registered for any flag via OnFlagChange(). -type FlagChangeCallback func() - -// OnFlagChange registers the callback, which is called after the given flag -// value is initialized and/or changed. -// -// Flag values are initialized during iniflags.Parse() call. -// Flag value can be changed on config re-read after obtaining SIGHUP signal -// or if periodic config re-read is enabled with -configUpdateInterval flag. -// -// Note that flags set via command-line cannot be overriden via config file modifications. -func OnFlagChange(flagName string, callback FlagChangeCallback) { - if parsed { - verifyFlagChangeFlagName(flagName) - } - flagChangeCallbacks[flagName] = append(flagChangeCallbacks[flagName], callback) -} - -func verifyFlagChangeFlagName(flagName string) { - if flag.Lookup(flagName) == nil { - log.Fatalf("iniflags: cannot register FlagChangeCallback for non-existing flag [%s]\n", flagName) - } -} - -func issueFlagChangeCallbacks(oldFlagValues map[string]string) { - for flagName := range oldFlagValues { - if fs, ok := flagChangeCallbacks[flagName]; ok { - for _, f := range fs { - f() - } - } - } -} - -func issueAllFlagChangeCallbacks() { - for _, fs := range flagChangeCallbacks { - for _, f := range fs { - f() - } - } -} - -func sighupHandler(ch <-chan os.Signal) { - for _ = range ch { - UpdateConfig() - } -} - -func parseConfigFlags() (oldFlagValues map[string]string, ok bool) { - configPath := *config - if !strings.HasPrefix(configPath, "./") { - if configPath, ok = combinePath(os.Args[0], *config); !ok { - return nil, false - } - } - if configPath == "" { - return nil, true - } - parsedArgs, ok := getArgsFromConfig(configPath) - if !ok { - return nil, false - } - missingFlags := getMissingFlags() - - ok = true - oldFlagValues = make(map[string]string) - for _, arg := range parsedArgs { - f := flag.Lookup(arg.Key) - if f == nil { - log.Printf("iniflags: unknown flag name=[%s] found at line [%d] of file [%s]\n", arg.Key, arg.LineNum, arg.FilePath) - ok = false - continue - } - - if _, found := missingFlags[f.Name]; found { - oldValue := f.Value.String() - if oldValue == arg.Value { - continue - } - if err := f.Value.Set(arg.Value); err != nil { - log.Printf("iniflags: error when parsing flag [%s] value [%s] at line [%d] of file [%s]: [%s]\n", arg.Key, arg.Value, arg.LineNum, arg.FilePath, err) - ok = false - continue - } - if oldValue != f.Value.String() { - oldFlagValues[arg.Key] = oldValue - } - } - } - - if !ok { - // restore old flag values - for k, v := range oldFlagValues { - flag.Set(k, v) - } - oldFlagValues = nil - } - - return oldFlagValues, ok -} - -func checkImportRecursion(configPath string) bool { - for _, path := range importStack { - if path == configPath { - log.Printf("iniflags: import recursion found for [%s]: %v\n", configPath, importStack) - return false - } - } - return true -} - -type flagArg struct { - Key string - Value string - FilePath string - LineNum int -} - -func stripBOM(s string) string { - if len(s) < 3 { - return s - } - bom := s[:3] - if bom == "\ufeff" || bom == "\ufffe" { - return s[3:] - } - return s -} - -func getArgsFromConfig(configPath string) (args []flagArg, ok bool) { - if !checkImportRecursion(configPath) { - return nil, false - } - importStack = append(importStack, configPath) - defer func() { - importStack = importStack[:len(importStack)-1] - }() - - file := openConfigFile(configPath) - if file == nil { - return nil, false - } - defer file.Close() - r := bufio.NewReader(file) - - var lineNum int - for { - lineNum++ - line, err := r.ReadString('\n') - if err != nil && line == "" { - if err == io.EOF { - break - } - log.Printf("iniflags: error when reading file [%s] at line %d: [%s]\n", configPath, lineNum, err) - return nil, false - } - if lineNum == 1 { - line = stripBOM(line) - } - line = strings.TrimSpace(line) - if strings.HasPrefix(line, "#import ") { - importPath, ok := unquoteValue(line[7:], lineNum, configPath) - if !ok { - return nil, false - } - if importPath, ok = combinePath(configPath, importPath); !ok { - return nil, false - } - importArgs, ok := getArgsFromConfig(importPath) - if !ok { - return nil, false - } - args = append(args, importArgs...) - continue - } - if line == "" || line[0] == ';' || line[0] == '#' || line[0] == '[' { - continue - } - parts := strings.SplitN(line, "=", 2) - if len(parts) != 2 { - log.Printf("iniflags: cannot split [%s] at line %d into key and value in config file [%s]\n", line, lineNum, configPath) - return nil, false - } - key := strings.TrimSpace(parts[0]) - value, ok := unquoteValue(parts[1], lineNum, configPath) - if !ok { - return nil, false - } - args = append(args, flagArg{Key: key, Value: value, FilePath: configPath, LineNum: lineNum}) - } - - return args, true -} - -func openConfigFile(path string) io.ReadCloser { - if isHTTP(path) { - resp, err := http.Get(path) - if err != nil { - log.Printf("iniflags: cannot load config file at [%s]: [%s]\n", path, err) - return nil - } - if resp.StatusCode != http.StatusOK { - log.Printf("iniflags: unexpected http status code when obtaining config file [%s]: %d. Expected %d\n", path, resp.StatusCode, http.StatusOK) - return nil - } - return resp.Body - } - - file, err := os.Open(path) - if err != nil { - log.Printf("iniflags: cannot open config file at [%s]: [%s]\n", path, err) - return nil - } - return file -} - -func combinePath(basePath, relPath string) (string, bool) { - if isHTTP(basePath) { - base, err := url.Parse(basePath) - if err != nil { - log.Printf("iniflags: error when parsing http base path [%s]: %s\n", basePath, err) - return "", false - } - rel, err := url.Parse(relPath) - if err != nil { - log.Printf("iniflags: error when parsing http rel path [%s] for base [%s]: %s\n", relPath, basePath, err) - return "", false - } - return base.ResolveReference(rel).String(), true - } - - if relPath == "" || relPath[0] == '/' || isHTTP(relPath) { - return relPath, true - } - return path.Join(path.Dir(basePath), relPath), true -} - -func isHTTP(path string) bool { - return strings.HasPrefix(strings.ToLower(path), "http://") || strings.HasPrefix(strings.ToLower(path), "https://") -} - -func getMissingFlags() map[string]bool { - setFlags := make(map[string]bool) - flag.Visit(func(f *flag.Flag) { - setFlags[f.Name] = true - }) - - missingFlags := make(map[string]bool) - flag.VisitAll(func(f *flag.Flag) { - if _, ok := setFlags[f.Name]; !ok { - missingFlags[f.Name] = true - } - }) - return missingFlags -} - -func dumpFlags() { - flag.VisitAll(func(f *flag.Flag) { - if f.Name != "config" && f.Name != "dumpflags" { - fmt.Printf("%s = %s # %s\n", f.Name, quoteValue(f.Value.String()), escapeUsage(f.Usage)) - } - }) -} - -func escapeUsage(s string) string { - return strings.Replace(s, "\n", "\n # ", -1) -} - -func quoteValue(v string) string { - if !strings.ContainsAny(v, "\n#;") && strings.TrimSpace(v) == v { - return v - } - v = strings.Replace(v, "\\", "\\\\", -1) - v = strings.Replace(v, "\n", "\\n", -1) - v = strings.Replace(v, "\"", "\\\"", -1) - return fmt.Sprintf("\"%s\"", v) -} - -func unquoteValue(v string, lineNum int, configPath string) (string, bool) { - v = strings.TrimSpace(v) - if len(v) == 0 { - return "", true - } - if v[0] != '"' { - return removeTrailingComments(v), true - } - n := strings.LastIndex(v, "\"") - if n == -1 { - log.Printf("iniflags: unclosed string found [%s] at line %d in config file [%s]\n", v, lineNum, configPath) - return "", false - } - v = v[1:n] - v = strings.Replace(v, "\\\"", "\"", -1) - v = strings.Replace(v, "\\n", "\n", -1) - return strings.Replace(v, "\\\\", "\\", -1), true -} - -func removeTrailingComments(v string) string { - v = strings.Split(v, "#")[0] - v = strings.Split(v, ";")[0] - return strings.TrimSpace(v) -} - -// SetConfigFile sets path to config file. -// -// Call this function before Parse() if you need default path to config file -// when -config command-line flag is not set. -func SetConfigFile(path string) { - if parsed { - panic("iniflags: SetConfigFile() must be called before Parse()") - } - *config = path -} diff --git a/vendor/github.com/vharitonsky/iniflags/test_bom.ini b/vendor/github.com/vharitonsky/iniflags/test_bom.ini deleted file mode 100644 index 468e8d394..000000000 --- a/vendor/github.com/vharitonsky/iniflags/test_bom.ini +++ /dev/null @@ -1 +0,0 @@ -bom=привет diff --git a/vendor/github.com/vharitonsky/iniflags/test_config.ini b/vendor/github.com/vharitonsky/iniflags/test_config.ini deleted file mode 100644 index 052c4665a..000000000 --- a/vendor/github.com/vharitonsky/iniflags/test_config.ini +++ /dev/null @@ -1,8 +0,0 @@ -# comment -var0 = val0 ; comment - -[section] -#import "test_config2.ini" # import another config - var1 = "val#1\n\\\"\nx" # this is a test comment - -var3 = # empty value diff --git a/vendor/github.com/vharitonsky/iniflags/test_config2.ini b/vendor/github.com/vharitonsky/iniflags/test_config2.ini deleted file mode 100644 index 00c1f0711..000000000 --- a/vendor/github.com/vharitonsky/iniflags/test_config2.ini +++ /dev/null @@ -1,3 +0,0 @@ - -; this file is imported from test_config.ini -var2 = 1234 # comment diff --git a/vendor/github.com/vharitonsky/iniflags/test_setconfigfile.ini b/vendor/github.com/vharitonsky/iniflags/test_setconfigfile.ini deleted file mode 100644 index 3369c8227..000000000 --- a/vendor/github.com/vharitonsky/iniflags/test_setconfigfile.ini +++ /dev/null @@ -1 +0,0 @@ -x = foobar diff --git a/vendor/vendor.json b/vendor/vendor.json index 1adb11a7f..f448a0901 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -206,11 +206,6 @@ "revision": "c8748311a7528d0ba7330d302adbc5a677ef9c9e", "revisionTime": "2015-02-21T09:03:35-05:00" }, - { - "path": "github.com/vharitonsky/iniflags", - "revision": "02b57ef987a5ee59eedc7dcd93315a43f6dcc4a7", - "revisionTime": "2015-11-14T13:23:54+02:00" - }, { "path": "github.com/xrash/smetrics", "revision": "81a89232431423f9140fa413823ce3045f02f19c", From c774ab79d716a28fda48550540d20d0ffcf55872 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Wed, 25 Jul 2018 14:14:06 +0200 Subject: [PATCH 4/9] Fix config.ini --- config.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.ini b/config.ini index 3c4348aa2..1f9df1eea 100644 --- a/config.ini +++ b/config.ini @@ -4,4 +4,4 @@ regex = usb|acm|com # Regular expression to filter serial port list v = true # show debug logging appName = CreateBridge updateUrl = http://downloads.arduino.cc/ -origins = http://downloads.arduino.cc/ +origins = http://local.arduino.cc:8000 From 7d4794bde728e384284923de5c430207fc6020e0 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Wed, 25 Jul 2018 14:17:09 +0200 Subject: [PATCH 5/9] ignore main in ini --- main.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 3fdc8177e..3f0614a47 100755 --- a/main.go +++ b/main.go @@ -116,7 +116,6 @@ func main() { // Parse ini config args, err := parseIni("config.ini") - fmt.Println(args) if err != nil { panic(err) } @@ -130,7 +129,10 @@ func main() { if err != nil { panic(err) } - iniConf.Parse(args) + err = iniConf.Parse(args) + if err != nil { + panic(err) + } // Instantiate Tools usr, _ := user.Current() @@ -454,7 +456,6 @@ body { func parseIni(filename string) (args []string, err error) { cfg, err := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: false}, filename) - if err != nil { return nil, err } @@ -467,6 +468,9 @@ func parseIni(filename string) (args []string, err error) { } // Ignore configUpdateInterval if key == "configUpdateInterval" { continue + } // Ignore name + if key == "name" { + continue } args = append(args, "-"+key, val) } From f24d15ff58d8c3d6788890b500d7b6dda5f1ecc7 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Wed, 25 Jul 2018 14:18:26 +0200 Subject: [PATCH 6/9] Remove dead code --- trayicon.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/trayicon.go b/trayicon.go index 7db774c38..5f9e3dfd7 100644 --- a/trayicon.go +++ b/trayicon.go @@ -99,21 +99,6 @@ func getConfigs() []ConfigIni { return configs } -func applyEnvironment(filename string) { - src, _ := osext.Executable() - dest := filepath.Dir(src) - cfg, _ := ini.LoadSources(ini.LoadOptions{IgnoreInlineComment: true}, filepath.Join(dest, filename)) - defaultSection, err := cfg.GetSection("env") - if err != nil { - return - } - for _, env := range defaultSection.KeyStrings() { - val := defaultSection.Key(env).String() - log.Info("Applying env setting: " + env + "=" + val) - os.Setenv(env, val) - } -} - func setupSysTrayReal() { systray.SetIcon(icon.GetIcon()) @@ -136,9 +121,6 @@ func setupSysTrayReal() { } entry.SetTitle(gliph + config.Name) } - } else { - // apply env setting from first config immediately - // applyEnvironment(configs[0].Localtion) } //mQuit := systray.AddMenuItem("Quit Plugin", "") From dc9fc17d93e5186aef835a74c93768c25acd9a08 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Thu, 26 Jul 2018 12:18:47 +0200 Subject: [PATCH 7/9] Prevent delays from displaying the trayicon The trayicon is displayed as soon as possible, in a goroutine. A select is used to block forever (before it was the trayicon that did it) --- main.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 3f0614a47..81ac6d860 100755 --- a/main.go +++ b/main.go @@ -6,7 +6,6 @@ package main import ( "encoding/json" "flag" - "fmt" "os" "os/user" "path/filepath" @@ -98,7 +97,8 @@ func main() { os.Exit(0) } - fmt.Println(*hibernate) + // Launch systray + go setupSysTray() if *hibernate == false { // autoextract self @@ -288,7 +288,9 @@ func main() { } }() } - setupSysTray() + + // Block forever until the application is shut down + select {} } var homeTemplate = template.Must(template.New("home").Parse(homeTemplateHtml)) From 2133d4077de2251f3c6c63be453bc778777b34ed Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Thu, 26 Jul 2018 12:43:41 +0200 Subject: [PATCH 8/9] Move proxy flags in iniflags --- main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 03d7ca2a9..3dbced61c 100755 --- a/main.go +++ b/main.go @@ -33,8 +33,6 @@ var ( port string portSSL string requiredToolsAPILevel = "v1" - httpProxy = flag.String("httpProxy", "", "Proxy server for HTTP requests") - httpsProxy = flag.String("httpsProxy", "", "Proxy server for HTTPS requests") ) // regular flags @@ -47,12 +45,14 @@ var ( // iniflags var ( - iniConf = flag.NewFlagSet("ini", flag.ContinueOnError) address = iniConf.String("address", "127.0.0.1", "The address where to listen. Defaults to localhost") appName = iniConf.String("appName", "", "") gcType = iniConf.String("gc", "std", "Type of garbage collection. std = Normal garbage collection allowing system to decide (this has been known to cause a stop the world in the middle of a CNC job which can cause lost responses from the CNC controller and thus stalled jobs. use max instead to solve.), off = let memory grow unbounded (you have to send in the gc command manually to garbage collect or you will run out of RAM eventually), max = Force garbage collection on each recv or send on a serial port (this minimizes stop the world events and thus lost serial responses, but increases CPU usage)") hostname = iniConf.String("hostname", "unknown-hostname", "Override the hostname we get from the OS") + httpProxy = iniConf.String("httpProxy", "", "Proxy server for HTTP requests") + httpsProxy = iniConf.String("httpsProxy", "", "Proxy server for HTTPS requests") indexURL = iniConf.String("indexURL", "https://downloads.arduino.cc/packages/package_staging_index.json", "The address from where to download the index json containing the location of upload tools") + iniConf = flag.NewFlagSet("ini", flag.ContinueOnError) logDump = iniConf.String("log", "off", "off = (default)") origins = iniConf.String("origins", "", "Allowed origin list for CORS") regExpFilter = iniConf.String("regex", "usb|acm|com", "Regular expression to filter serial port list") From 2b3cc4dccf5338f21c8925da22db275931b5cc29 Mon Sep 17 00:00:00 2001 From: Matteo Suppo Date: Thu, 26 Jul 2018 15:57:25 +0200 Subject: [PATCH 9/9] Send ini flags in a more-compatible way The flag parser was confused with flags separated by spaces, resulting in inconsistent behaviour where flags were discarded --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 3dbced61c..d091d519a 100755 --- a/main.go +++ b/main.go @@ -502,7 +502,7 @@ func parseIni(filename string) (args []string, err error) { if key == "name" { continue } - args = append(args, "-"+key, val) + args = append(args, "-"+key+"="+val) } }