浏览代码

Switch to urfave/cli (#152)

ayntgl 4 年之前
父节点
当前提交
d3001a97c0
共有 5 个文件被更改,包括 126 次插入98 次删除
  1. 5 7
      config/config.go
  2. 3 0
      go.mod
  3. 14 8
      go.sum
  4. 102 82
      main.go
  5. 2 1
      ui/app.go

+ 5 - 7
config/pkg.go → config/config.go

@@ -8,7 +8,6 @@ import (
 )
 
 type Config struct {
-	Path    string        `toml:"-"`
 	General GeneralConfig `toml:"general"`
 	Theme   ThemeConfig   `toml:"theme"`
 	Keys    KeysConfig    `toml:"keys"`
@@ -16,21 +15,20 @@ type Config struct {
 
 func New() *Config {
 	return &Config{
-		Path:    DefaultPath(),
 		General: newGeneralConfig(),
 		Theme:   newThemeConfig(),
 		Keys:    newKeysConfig(),
 	}
 }
 
-func (c *Config) Load() {
-	err := os.MkdirAll(filepath.Dir(c.Path), os.ModePerm)
+func (c *Config) Load(path string) {
+	err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
 	if err != nil {
 		panic(err)
 	}
 
-	if _, err = os.Stat(c.Path); os.IsNotExist(err) {
-		f, err := os.Create(c.Path)
+	if _, err = os.Stat(path); os.IsNotExist(err) {
+		f, err := os.Create(path)
 		if err != nil {
 			panic(err)
 		}
@@ -40,7 +38,7 @@ func (c *Config) Load() {
 			panic(err)
 		}
 	} else {
-		_, err = toml.DecodeFile(c.Path, &c)
+		_, err = toml.DecodeFile(path, &c)
 		if err != nil {
 			panic(err)
 		}

+ 3 - 0
go.mod

@@ -9,11 +9,13 @@ require (
 	github.com/gdamore/tcell/v2 v2.4.1-0.20220313203054-2a1a1b586447
 	github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8
 	github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
+	github.com/urfave/cli/v2 v2.4.0
 	github.com/zalando/go-keyring v0.2.1
 )
 
 require (
 	github.com/alessio/shellescape v1.4.1 // indirect
+	github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
 	github.com/danieljoos/wincred v1.1.2 // indirect
 	github.com/gdamore/encoding v1.0.0 // indirect
 	github.com/godbus/dbus/v5 v5.1.0 // indirect
@@ -21,6 +23,7 @@ require (
 	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
 	github.com/mattn/go-runewidth v0.0.13 // indirect
 	github.com/rivo/uniseg v0.2.0 // indirect
+	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
 	golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect
 	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect

+ 14 - 8
go.sum

@@ -1,13 +1,15 @@
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
 github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
 github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
 github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
 github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
-github.com/ayntgl/astatine v0.24.1-0.20220323171957-44de48cba9b9 h1:7noMugVd2FGlZcq3pawMZ0H+RZu++AFPVPPWFA370v4=
-github.com/ayntgl/astatine v0.24.1-0.20220323171957-44de48cba9b9/go.mod h1:A54lIYhmYBAYhUaiR90Ahlw+oSi5gN+70PNvQ+6xjMY=
 github.com/ayntgl/astatine v0.24.1-0.20220324085605-e85d32085ce8 h1:tn/I/8Zv22Q8ERV/awDfLTSKQR5eH5AAYpzCIuRUaqw=
 github.com/ayntgl/astatine v0.24.1-0.20220324085605-e85d32085ce8/go.mod h1:xRC0h8PGhVmnvNh2eKSkJJ4xvtcQEZpvKmepqRMbNEU=
+github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
+github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/danieljoos/wincred v1.1.0 h1:3RNcEpBg4IhIChZdFRSdlQt1QjCp1sMAPIrOnm7Yf8g=
 github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
 github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0=
 github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=
@@ -18,6 +20,7 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo
 github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1/go.mod h1:Az6Jt+M5idSED2YPGtwnfJV0kXohgdCBPmHGSYc1r04=
 github.com/gdamore/tcell/v2 v2.4.1-0.20220313203054-2a1a1b586447 h1:4idf9699cuWAc7ZIB+2RzuDWU30oRkB0X/FZTUlWOVY=
 github.com/gdamore/tcell/v2 v2.4.1-0.20220313203054-2a1a1b586447/go.mod h1:I8YJFI9gzgl4dHi9UlRDZosCW+jYkDA37AXmXvL51w4=
+github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
 github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
 github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -33,28 +36,30 @@ github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 h1:xe+mmCnDN82KhC010l3N
 github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8/go.mod h1:WIfMkQNY+oq/mWwtsjOYHIZBuwthioY2srOmljJkTnk=
 github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
 github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/urfave/cli/v2 v2.4.0 h1:m2pxjjDFgDxSPtO8WSdbndj17Wu2y8vOT86wE/tjr+I=
+github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg=
 github.com/zalando/go-keyring v0.2.1 h1:MBRN/Z8H4U5wEKXiD67YbDAr5cj/DOStmSga70/2qKc=
 github.com/zalando/go-keyring v0.2.1/go.mod h1:g63M2PPn0w5vjmEbwAX3ib5I+41zdm4esSETOn9Y6Dw=
 golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s=
 golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211113001501-0c823b97ae02 h1:7NCfEGl0sfUojmX78nK9pBJuUlSZWEJA/TwASvfiPLo=
 golang.org/x/sys v0.0.0-20211113001501-0c823b97ae02/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
 golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -65,6 +70,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 102 - 82
main.go

@@ -1,87 +1,75 @@
 package main
 
 import (
-	"flag"
+	"os"
 
-	"github.com/ayntgl/astatine"
 	"github.com/ayntgl/discordo/config"
 	"github.com/ayntgl/discordo/ui"
 	"github.com/gdamore/tcell/v2"
 	"github.com/rivo/tview"
+	"github.com/urfave/cli/v2"
 	"github.com/zalando/go-keyring"
 )
 
-const name = "discordo"
+const (
+	name  = "discordo"
+	usage = "A lightweight, secure, and feature-rich Discord terminal client"
+)
 
 func main() {
-	var token string
-	var cfg string
-	flag.StringVar(&token, "token", "", "The authentication token.")
-	flag.StringVar(&cfg, "config", "", "The path of the configuration file.")
-	flag.Parse()
-
-	if token == "" {
-		token, _ = keyring.Get(name, "token")
-	}
-
-	c := config.New()
-	if cfg != "" {
-		c.Path = cfg
+	t, _ := keyring.Get(name, "token")
+
+	cliApp := &cli.App{
+		Name:                 name,
+		Usage:                usage,
+		EnableBashCompletion: true,
+		Flags: []cli.Flag{
+			&cli.StringFlag{
+				Name:        "token",
+				Usage:       "The client authentication token.",
+				Value:       t,
+				DefaultText: "From keyring",
+				Aliases:     []string{"t"},
+			},
+			&cli.StringFlag{
+				Name:    "config",
+				Usage:   "The path of the configuration file.",
+				Value:   config.DefaultPath(),
+				Aliases: []string{"c"},
+			},
+		},
 	}
-	c.Load()
-
-	app := ui.NewApp(c)
-	if token != "" {
-		app.Session = astatine.New(token)
-		err := app.Connect()
-		if err != nil {
-			panic(err)
-		}
 
-		app.DrawMainFlex()
-		app.SetFocus(app.GuildsList)
-	} else {
-		app.Session = astatine.New(token)
-
-		loginForm := ui.NewLoginForm(false)
-		loginForm.AddButton("Login", func() {
-			email := loginForm.GetFormItem(0).(*tview.InputField).GetText()
-			password := loginForm.GetFormItem(1).(*tview.InputField).GetText()
-			if email == "" || password == "" {
-				return
-			}
+	cliApp.Action = func(ctx *cli.Context) error {
+		c := config.New()
+		c.Load(ctx.String("config"))
 
-			// Login using the email and password
-			lr, err := app.Session.Login(email, password)
+		token := ctx.String("token")
+		app := ui.NewApp(token, c)
+		if token != "" {
+			err := app.Connect()
 			if err != nil {
 				panic(err)
 			}
 
-			if lr.Token != "" && !lr.Mfa {
-				app.Session.Identify.Token = lr.Token
-				err = app.Connect()
+			app.DrawMainFlex()
+			app.SetFocus(app.GuildsList)
+		} else {
+			loginForm := ui.NewLoginForm(false)
+			loginForm.AddButton("Login", func() {
+				email := loginForm.GetFormItem(0).(*tview.InputField).GetText()
+				password := loginForm.GetFormItem(1).(*tview.InputField).GetText()
+				if email == "" || password == "" {
+					return
+				}
+
+				// Login using the email and password
+				lr, err := app.Session.Login(email, password)
 				if err != nil {
 					panic(err)
 				}
 
-				app.DrawMainFlex()
-				app.SetFocus(app.GuildsList)
-
-				go keyring.Set(name, "token", lr.Token)
-			} else {
-				// The account has MFA enabled, reattempt login with MFA code and ticket.
-				mfaLoginForm := ui.NewLoginForm(true)
-				mfaLoginForm.AddButton("Login", func() {
-					code := loginForm.GetFormItem(0).(*tview.InputField).GetText()
-					if code == "" {
-						return
-					}
-
-					lr, err = app.Session.Totp(code, lr.Ticket)
-					if err != nil {
-						panic(err)
-					}
-
+				if lr.Token != "" && !lr.Mfa {
 					app.Session.Identify.Token = lr.Token
 					err = app.Connect()
 					if err != nil {
@@ -92,31 +80,63 @@ func main() {
 					app.SetFocus(app.GuildsList)
 
 					go keyring.Set(name, "token", lr.Token)
-				})
-			}
-		})
+				} else {
+					// The account has MFA enabled, reattempt login with MFA code and ticket.
+					mfaLoginForm := ui.NewLoginForm(true)
+					mfaLoginForm.AddButton("Login", func() {
+						code := loginForm.GetFormItem(0).(*tview.InputField).GetText()
+						if code == "" {
+							return
+						}
+
+						lr, err = app.Session.Totp(code, lr.Ticket)
+						if err != nil {
+							panic(err)
+						}
+
+						app.Session.Identify.Token = lr.Token
+						err = app.Connect()
+						if err != nil {
+							panic(err)
+						}
+
+						app.DrawMainFlex()
+						app.SetFocus(app.GuildsList)
+
+						go keyring.Set(name, "token", lr.Token)
+					})
+				}
+			})
+
+			app.SetRoot(loginForm, true)
+		}
+
+		tview.Borders.TopLeftFocus = tview.Borders.TopLeft
+		tview.Borders.TopRightFocus = tview.Borders.TopRight
+		tview.Borders.BottomLeftFocus = tview.Borders.BottomLeft
+		tview.Borders.BottomRightFocus = tview.Borders.BottomRight
+		tview.Borders.HorizontalFocus = tview.Borders.Horizontal
+		tview.Borders.VerticalFocus = tview.Borders.Vertical
+		tview.Borders.TopLeft = 0
+		tview.Borders.TopRight = 0
+		tview.Borders.BottomLeft = 0
+		tview.Borders.BottomRight = 0
+		tview.Borders.Horizontal = 0
+		tview.Borders.Vertical = 0
+
+		tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(app.Config.Theme.Background)
+		tview.Styles.BorderColor = tcell.GetColor(app.Config.Theme.Border)
+		tview.Styles.TitleColor = tcell.GetColor(app.Config.Theme.Title)
+
+		err := app.Run()
+		if err != nil {
+			panic(err)
+		}
 
-		app.SetRoot(loginForm, true)
+		return nil
 	}
 
-	tview.Borders.TopLeftFocus = tview.Borders.TopLeft
-	tview.Borders.TopRightFocus = tview.Borders.TopRight
-	tview.Borders.BottomLeftFocus = tview.Borders.BottomLeft
-	tview.Borders.BottomRightFocus = tview.Borders.BottomRight
-	tview.Borders.HorizontalFocus = tview.Borders.Horizontal
-	tview.Borders.VerticalFocus = tview.Borders.Vertical
-	tview.Borders.TopLeft = 0
-	tview.Borders.TopRight = 0
-	tview.Borders.BottomLeft = 0
-	tview.Borders.BottomRight = 0
-	tview.Borders.Horizontal = 0
-	tview.Borders.Vertical = 0
-
-	tview.Styles.PrimitiveBackgroundColor = tcell.GetColor(app.Config.Theme.Background)
-	tview.Styles.BorderColor = tcell.GetColor(app.Config.Theme.Border)
-	tview.Styles.TitleColor = tcell.GetColor(app.Config.Theme.Title)
-
-	err := app.Run()
+	err := cliApp.Run(os.Args)
 	if err != nil {
 		panic(err)
 	}

+ 2 - 1
ui/app.go

@@ -23,9 +23,10 @@ type App struct {
 	SelectedMessage   int
 }
 
-func NewApp(c *config.Config) *App {
+func NewApp(token string, c *config.Config) *App {
 	app := &App{
 		MainFlex:        tview.NewFlex(),
+		Session:         astatine.New(token),
 		Config:          c,
 		SelectedMessage: -1,
 	}