From a5affd38222c8e162957f7761455728b328879cf Mon Sep 17 00:00:00 2001 From: sam80180 Date: Mon, 25 Dec 2023 15:38:27 +0800 Subject: [PATCH] fix: launch app with environment variables and arguments --- cmd/app/launch.go | 40 ++++++++++++++++++++++++++++++++++-- cmd/crash.go | 7 ++++--- cmd/devices.go | 2 +- cmd/devmode/arm.go | 2 -- cmd/devmode/confirm.go | 2 -- cmd/devmode/enable.go | 1 - cmd/devmode/list.go | 1 - cmd/devmode/reveal.go | 2 -- cmd/root.go | 26 ++++++++++++++---------- go.mod | 1 + go.sum | 6 ++---- src/util/common.go | 7 ++++--- src/util/log.go | 46 +++++++++++++++++++++++++++++++++++++++++- 13 files changed, 110 insertions(+), 33 deletions(-) diff --git a/cmd/app/launch.go b/cmd/app/launch.go index f756bfc..9ba76f4 100644 --- a/cmd/app/launch.go +++ b/cmd/app/launch.go @@ -18,14 +18,24 @@ package app import ( - "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" + "bytes" + "fmt" "os" + "strings" + giDevice "github.com/SonicCloudOrg/sonic-gidevice" + "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" + envparse "github.com/hashicorp/go-envparse" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) +var bKillExisting bool +var envKVs []string + var launchCmd = &cobra.Command{ Use: "launch", + Args: cobra.ArbitraryArgs, Short: "Launch App", Long: "Launch App", RunE: func(cmd *cobra.Command, args []string) error { @@ -33,7 +43,19 @@ var launchCmd = &cobra.Command{ if device == nil { os.Exit(0) } - _, errLaunch := device.AppLaunch(bundleId) + argv := []any{} + for _, arg := range args { + argv = append(argv, arg) + } + inputEnvVars, errParseEnv := envparse.Parse(bytes.NewReader([]byte(strings.Join(envKVs, "\n")))) + if errParseEnv != nil { + logrus.Warnf("Failed to parse env vars: %+v", errParseEnv) + } + envVars := map[string]any{} + for k, v := range inputEnvVars { + envVars[k] = v + } + _, errLaunch := device.AppLaunch(bundleId, giDevice.WithArguments(argv), giDevice.WithKillExisting(bKillExisting), giDevice.WithEnvironment(envVars)) if errLaunch != nil { return util.NewErrorPrint(util.ErrSendCommand, "launch", errLaunch) } @@ -41,9 +63,23 @@ var launchCmd = &cobra.Command{ }, } +func myHelpFunc(cmd *cobra.Command, args []string) { + fmt.Printf(`%s + + Usage: + %s -- [arguments [arguments ...]] + + Flags: + %s`, cmd.Long, cmd.UseLine(), cmd.Flags().FlagUsages()) +} + func initAppLaunch() { appRootCMD.AddCommand(launchCmd) launchCmd.Flags().StringVarP(&udid, "udid", "u", "", "device's serialNumber") launchCmd.Flags().StringVarP(&bundleId, "bundleId", "b", "", "target bundleId") launchCmd.MarkFlagRequired("bundleId") + launchCmd.Flags().StringSliceVarP(&envKVs, "env", "e", []string{}, "environment variables; format: KEY=VALUE") + launchCmd.Flags().BoolVar(&bKillExisting, "kill-existing", false, "kill the application if it is already running") + launchCmd.SetHelpFunc(myHelpFunc) + launchCmd.UseLine() } diff --git a/cmd/crash.go b/cmd/crash.go index de01324..23c3167 100644 --- a/cmd/crash.go +++ b/cmd/crash.go @@ -19,11 +19,12 @@ package cmd import ( "fmt" + "os" + "path/filepath" + giDevice "github.com/SonicCloudOrg/sonic-gidevice" "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" "github.com/spf13/cobra" - "os" - "path/filepath" ) var crashCmd = &cobra.Command{ @@ -38,7 +39,7 @@ var crashCmd = &cobra.Command{ if !filepath.IsAbs(crashOutputPath) { var err error if crashOutputPath, err = filepath.Abs(crashOutputPath); err != nil { - fmt.Println("path no found!") + fmt.Println("path not found!") os.Exit(0) } } diff --git a/cmd/devices.go b/cmd/devices.go index 7a883f2..47b1b5b 100644 --- a/cmd/devices.go +++ b/cmd/devices.go @@ -111,7 +111,7 @@ var devicesCmd = &cobra.Command{ data := util.ResultData(device) fmt.Println(util.Format(data, isFormat, isDetail)) } else { - fmt.Println("device no found") + fmt.Println("device not found") os.Exit(0) } } else { diff --git a/cmd/devmode/arm.go b/cmd/devmode/arm.go index 5679f00..8992c22 100644 --- a/cmd/devmode/arm.go +++ b/cmd/devmode/arm.go @@ -4,7 +4,6 @@ import ( "fmt" "net/http" - "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "golang.org/x/xerrors" @@ -15,7 +14,6 @@ var devmodeArmCmd = &cobra.Command{ Short: "Arm the Developer Mode (device will reboot)", Long: "Arm the Developer Mode (device will reboot)", RunE: func(cmd *cobra.Command, args []string) error { - util.InitLogger() if bCan, eCan := canToggleDevMode(udid); eCan != nil { strErrMsg := fmt.Sprintf("Failed to check device %s iOS version", udid) logrus.Warn(strErrMsg) diff --git a/cmd/devmode/confirm.go b/cmd/devmode/confirm.go index 0ef3327..5c87166 100644 --- a/cmd/devmode/confirm.go +++ b/cmd/devmode/confirm.go @@ -4,7 +4,6 @@ import ( "fmt" "net/http" - "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "golang.org/x/xerrors" @@ -15,7 +14,6 @@ var devmodeConfirmCmd = &cobra.Command{ Short: "Confirm enabling of Developer Mode", Long: "Confirm enabling of Developer Mode", RunE: func(cmd *cobra.Command, args []string) error { - util.InitLogger() if bPreCheckIOSVer { if bCan, eCan := canToggleDevMode(udid); eCan != nil { strErrMsg := fmt.Sprintf("Failed to check device %s iOS version", udid) diff --git a/cmd/devmode/enable.go b/cmd/devmode/enable.go index 81dbf04..4fc497b 100644 --- a/cmd/devmode/enable.go +++ b/cmd/devmode/enable.go @@ -22,7 +22,6 @@ var devmodeEnableCmd = &cobra.Command{ Short: "Enable Developer Mode (device will reboot)", Long: "Enable Developer Mode (device will reboot)", RunE: func(cmd *cobra.Command, args []string) error { - //util.InitLogger() errArm := devmodeArmCmd.RunE(cmd, args) if errArm != nil { return errArm diff --git a/cmd/devmode/list.go b/cmd/devmode/list.go index 21049d5..844a368 100644 --- a/cmd/devmode/list.go +++ b/cmd/devmode/list.go @@ -16,7 +16,6 @@ var devmodeListCmd = &cobra.Command{ Short: "Print the Developer Mode status of connected devices", Long: "Print the Developer Mode status of connected devices", RunE: func(cmd *cobra.Command, args []string) error { - util.InitLogger() usbMuxClient, err := giDevice.NewUsbmux() if err != nil { return util.NewErrorPrint(util.ErrConnect, "usbMux", err) diff --git a/cmd/devmode/reveal.go b/cmd/devmode/reveal.go index 49e894c..27d1cf0 100644 --- a/cmd/devmode/reveal.go +++ b/cmd/devmode/reveal.go @@ -4,7 +4,6 @@ import ( "fmt" "net/http" - "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "golang.org/x/xerrors" @@ -15,7 +14,6 @@ var devmodeRevealCmd = &cobra.Command{ Short: "Reveal the Developer Mode menu on the device", Long: "Reveal the Developer Mode menu on the device", RunE: func(cmd *cobra.Command, args []string) error { - util.InitLogger() if bCan, eCan := canToggleDevMode(udid); eCan != nil { strErrMsg := fmt.Sprintf("Failed to check device %s iOS version", udid) logrus.Warn(strErrMsg) diff --git a/cmd/root.go b/cmd/root.go index be9ca2c..5f58eef 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,6 +20,7 @@ package cmd import ( "os" + "github.com/SonicCloudOrg/sonic-ios-bridge/src/util" "github.com/spf13/cobra" ) @@ -34,21 +35,24 @@ var rootCmd = &cobra.Command{ Use: strExeccutable, Short: "Bridge of iOS Devices", Long: ` - ▄▄▄▄ ▄▄▄▄ ▄▄▄ ▄▄ ▄▄▄▄▄▄ ▄▄▄▄ - ▄█▀▀▀▀█ ██▀▀██ ███ ██ ▀▀██▀▀ ██▀▀▀▀█ - ██▄ ██ ██ ██▀█ ██ ██ ██▀ - ▀████▄ ██ ██ ██ ██ ██ ██ ██ - ▀██ ██ ██ ██ █▄██ ██ ██▄ - █▄▄▄▄▄█▀ ██▄▄██ ██ ███ ▄▄██▄▄ ██▄▄▄▄█ - ▀▀▀▀▀ ▀▀▀▀ ▀▀ ▀▀▀ ▀▀▀▀▀▀ ▀▀▀▀ - - Copyright (C) 2022 SonicCloudOrg AGPLv3 -https://github.com/SonicCloudOrg/sonic-ios-bridge -`, + ▄▄▄▄ ▄▄▄▄ ▄▄▄ ▄▄ ▄▄▄▄▄▄ ▄▄▄▄ + ▄█▀▀▀▀█ ██▀▀██ ███ ██ ▀▀██▀▀ ██▀▀▀▀█ + ██▄ ██ ██ ██▀█ ██ ██ ██▀ + ▀████▄ ██ ██ ██ ██ ██ ██ ██ + ▀██ ██ ██ ██ █▄██ ██ ██▄ + █▄▄▄▄▄█▀ ██▄▄██ ██ ███ ▄▄██▄▄ ██▄▄▄▄█ + ▀▀▀▀▀ ▀▀▀▀ ▀▀ ▀▀▀ ▀▀▀▀▀▀ ▀▀▀▀ + + Copyright (C) 2022 SonicCloudOrg AGPLv3 + https://github.com/SonicCloudOrg/sonic-ios-bridge + `, } // Execute error func Execute() { + rootCmd.PersistentFlags().String("log-level", "info", "Valid values: [panic, fatal, error, warn, info, debug, trace]") + rootCmd.ParseFlags(os.Args) // parse flags and set log level + util.InitLogger(rootCmd.PersistentFlags().Lookup("log-level").Value.String()) err := rootCmd.Execute() if err != nil { os.Exit(1) diff --git a/go.mod b/go.mod index 9ad7e1a..4b363c0 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/google/gopacket v1.1.19 github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 + github.com/hashicorp/go-envparse v0.1.0 github.com/mitchellh/mapstructure v1.5.0 github.com/satori/go.uuid v1.2.0 github.com/sirupsen/logrus v1.9.3 diff --git a/go.sum b/go.sum index 92abc44..2b2fa74 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/SonicCloudOrg/sonic-gidevice v0.7.6 h1:zSHY1aCrMEQNtnsKsfsOUp7erxf5ocl/eoxjfvKSpNg= -github.com/SonicCloudOrg/sonic-gidevice v0.7.6/go.mod h1:SEquP5doc1Xa9Y0556SJBpFg7Pex+jXk+y4XQ4i0yxo= github.com/SonicCloudOrg/sonic-gidevice v0.7.7 h1:oWNtc5j0ke/VmDVaXYZOR5JAQ8Cr12Fo1UrMq51lVM4= github.com/SonicCloudOrg/sonic-gidevice v0.7.7/go.mod h1:SEquP5doc1Xa9Y0556SJBpFg7Pex+jXk+y4XQ4i0yxo= github.com/SonicCloudOrg/sonic-ios-webkit-adapter v0.0.7 h1:s4OTcJ0VG4mg3501Ec+aSR6gQ8eTWz26fdgCUjxlmJQ= @@ -43,6 +41,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdmPSDFPY= +github.com/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -182,5 +182,3 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM= -howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= diff --git a/src/util/common.go b/src/util/common.go index 1cb14bd..0cd26c0 100644 --- a/src/util/common.go +++ b/src/util/common.go @@ -23,8 +23,6 @@ import ( "encoding/json" "errors" "fmt" - giDevice "github.com/SonicCloudOrg/sonic-gidevice" - "github.com/SonicCloudOrg/sonic-ios-bridge/src/entity" "io" "io/ioutil" "log" @@ -36,6 +34,9 @@ import ( "strings" "sync" "time" + + giDevice "github.com/SonicCloudOrg/sonic-gidevice" + "github.com/SonicCloudOrg/sonic-ios-bridge/src/entity" ) const ( @@ -82,7 +83,7 @@ func GetDeviceByUdId(udId string) (device giDevice.Device) { device = list[0] } if device == nil || device.Properties().SerialNumber == "" { - fmt.Println("device no found") + fmt.Println("device not found") return nil } } else { diff --git a/src/util/log.go b/src/util/log.go index f2da35c..2d5be02 100644 --- a/src/util/log.go +++ b/src/util/log.go @@ -1,16 +1,60 @@ package util import ( + stdlog "log" "os" + "regexp" + "strings" "github.com/sirupsen/logrus" easy "github.com/t-tomalak/logrus-easy-formatter" ) -func InitLogger() { +func InitLogger(strIntLevel string) { logrus.SetOutput(os.Stderr) logrus.SetFormatter(&easy.Formatter{ TimestampFormat: "2006-01-02 15:04:05", LogFormat: "[%lvl%]: %time% - %msg%\n", }) + SetLogLevel(strIntLevel) + stdlog.SetOutput(new(LogrusWriter)) +} + +func SetLogLevel(strIntLevel string) { + loglevel := logrus.InfoLevel + switch strings.ToLower(strIntLevel) { + case "panic": + loglevel = logrus.PanicLevel + case "fatal": + loglevel = logrus.FatalLevel + case "error": + loglevel = logrus.ErrorLevel + case "warn": + loglevel = logrus.WarnLevel + case "info": + loglevel = logrus.InfoLevel + case "debug": + loglevel = logrus.DebugLevel + case "trace": + loglevel = logrus.TraceLevel + } + logrus.SetLevel(loglevel) +} + +/********** work around to this problem **********/ +// https://github.com/google/gousb/issues/87#issuecomment-1100956460 +type LogrusWriter int + +var reStdGoLogFormat = regexp.MustCompile(`(?s)[0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} (?P.+)`) + +func (LogrusWriter) Write(data []byte) (int, error) { + logmessage := string(data) + if reStdGoLogFormat.MatchString(logmessage) { + logmessage = logmessage[20:] + } + if strings.HasSuffix(logmessage, "\n") { + logmessage = logmessage[:len(logmessage)-1] + } + logrus.Infof("[gousb] %s", logmessage) + return len(logmessage), nil }