Added cli module with first papero subcommand

This commit is contained in:
Blallo 2021-01-31 01:15:07 +01:00
parent 54a31ad825
commit 87c86a8090
No known key found for this signature in database
GPG key ID: 0CBE577C9B72DC3F
5 changed files with 275 additions and 1 deletions

137
cli/papero/info.go Normal file
View file

@ -0,0 +1,137 @@
package main
import (
"flag"
"fmt"
"io"
"os"
"git.lattuga.net/blallo/papero/cli"
"git.lattuga.net/blallo/papero/imaputils"
)
var infoVerbs cli.CommandMap
func init() {
lsMailbox := LsMailboxCmd{}
lsMessages := LsMsgCmd{}
catMessage := CatMsgCmd{}
infoVerbs = cli.CommandMap{
"list-mailboxes": lsMailbox,
"list-messages": lsMessages,
"display-message": catMessage,
}
}
type InfoCmd struct{}
func (i InfoCmd) Func(args []string) error {
flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.Usage = func() { i.Help(os.Stdout, flagset) }
flagset.Parse(args[1:])
subArgs := flagset.Args()
if len(subArgs) == 0 {
i.Help(os.Stderr, flagset)
os.Exit(1)
}
cmd := subArgs[0]
if Session.Info.Opts.Debug {
Log.Debug("info verb:", cmd)
}
return infoVerbs[cmd].Func(subArgs)
}
func (i InfoCmd) Help(w io.Writer, set *flag.FlagSet) {
fmt.Fprintf(w, "USAGE: %s info VERB [verb opts]\n", Session.Info.Name)
fmt.Fprintf(w, "\nVERBS:\n")
for verb := range infoVerbs {
fmt.Fprintf(w, "\t%s\n", verb)
}
}
// VERBS
type LsMailboxCmd struct{}
func (l LsMailboxCmd) Func(args []string) error {
if Session.Info.Opts.Debug {
Log.Debug("enter info list-mailboxes")
}
var withAttributes bool
flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.BoolVar(&withAttributes, "with-attrs", false, "toggle attributes display")
flagset.Usage = func() { l.Help(os.Stdout, flagset) }
flagset.Parse(args[1:])
mboxInfo, err := imaputils.ListMailboxes(Session.Config, Session.Info.Opts.Debug)
if err != nil {
return err
}
if Session.Info.Opts.Debug {
Log.Debug(mboxInfo)
}
for _, box := range mboxInfo {
if withAttributes {
attrs := fmt.Sprint(box.Attributes)
fmt.Printf("%s (attrs: %s)", box.Name, attrs)
} else {
fmt.Println(box.Name)
}
}
return nil
}
func (l LsMailboxCmd) Help(w io.Writer, set *flag.FlagSet) {
fmt.Fprintf(w, "USAGE: %s info list-mailboxes\n", Session.Info.Name)
set.PrintDefaults()
}
type LsMsgCmd struct{}
func (l LsMsgCmd) Func(args []string) error {
if Session.Info.Opts.Debug {
Log.Debug("enter info list-messages")
}
var limit uint
flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.UintVar(&limit, "limit", 0, "maximum number of messages to display (0 means no limit)")
flagset.Usage = func() { l.Help(os.Stdout, flagset) }
flagset.Parse(args[1:])
subArgs := flagset.Args()
if len(subArgs) != 1 {
l.Help(os.Stderr, flagset)
os.Exit(1)
}
return nil
}
func (l LsMsgCmd) Help(w io.Writer, set *flag.FlagSet) {
fmt.Fprintf(w, "USAGE: %s info list-messages [opts] MAILBOX_NAME\n", Session.Info.Name)
fmt.Fprintf(w, "\nOPTS:\n")
set.PrintDefaults()
}
type CatMsgCmd struct{}
func (c CatMsgCmd) Func(args []string) error {
if Session.Info.Opts.Debug {
Log.Debug("enter info display-message")
}
flagset := flag.NewFlagSet(args[0], flag.ExitOnError)
flagset.Usage = func() { c.Help(os.Stdout, flagset) }
flagset.Parse(args[1:])
subArgs := flagset.Args()
if len(subArgs) != 1 {
c.Help(os.Stderr, flagset)
os.Exit(1)
}
return nil
}
func (c CatMsgCmd) Help(w io.Writer, set *flag.FlagSet) {
fmt.Fprintf(w, "USAGE: %s info display-message MAILBOX_NAME MESSAGE_ID\n", Session.Info.Name)
set.PrintDefaults()
}

85
cli/papero/main.go Normal file
View file

@ -0,0 +1,85 @@
package main
import (
"flag"
"os"
"git.lattuga.net/blallo/papero/cli"
"git.lattuga.net/blallo/papero/config"
"github.com/withmandala/go-log"
)
var Session struct {
Info cli.ProgramInfo
Config *config.AccountData
}
var Log *log.Logger
func init() {
info := InfoCmd{}
Session.Info.Commands = cli.CommandMap{
"info": info,
}
Session.Info.Name = "papero"
flag.Usage = func() { cli.Usage(os.Stdout, Session.Info) }
Log = log.New(os.Stdout)
}
func main() {
var configPath string
flag.StringVar(&Session.Info.Opts.ConfigPath, "config", "", "path to the configuration")
flag.BoolVar(&Session.Info.Opts.Debug, "debug", false, "execute in debug mode")
flag.StringVar(&Session.Info.Opts.ConfigStanza, "account", "", "specify which account to use")
flag.Parse()
args := flag.Args()
if len(args) == 0 {
cli.Usage(os.Stderr, Session.Info)
os.Exit(1)
}
if Session.Info.Opts.Debug {
Log.WithDebug()
Log.Debugf(
"opts -> config: %s\tdebug: %v\taccount: %s\n",
Session.Info.Opts.ConfigPath,
Session.Info.Opts.Debug,
Session.Info.Opts.ConfigStanza,
)
}
if Session.Info.Opts.ConfigPath == "" {
var err error
configPath, err = config.Find()
if err != nil {
Log.Fatal(err)
}
} else {
configPath = Session.Info.Opts.ConfigPath
}
fullConfig, err := config.Parse(configPath)
if err != nil {
os.Exit(2)
}
var ok bool
var account string
if Session.Info.Opts.ConfigStanza != "" {
account = Session.Info.Opts.ConfigStanza
Session.Config, ok = fullConfig.Accounts[account]
} else {
account = fullConfig.Default
Session.Config, ok = fullConfig.Accounts[account]
}
if !ok {
Log.Error("Account not found in config:", account)
os.Exit(2)
}
err = Session.Info.Commands[args[0]].Func(args)
if err != nil {
Log.Error(err)
os.Exit(-1)
}
}

38
cli/utils.go Normal file
View file

@ -0,0 +1,38 @@
package cli
import (
"flag"
"fmt"
"io"
)
type GlobalOpts struct {
ConfigPath string
Debug bool
ConfigStanza string
}
func (o GlobalOpts) String() string {
return "--config --debug --account"
}
type Command interface {
Func([]string) error
Help(io.Writer, *flag.FlagSet)
}
type CommandMap map[string]Command
type ProgramInfo struct {
Name string
Opts GlobalOpts
Commands CommandMap
}
func Usage(w io.Writer, info ProgramInfo) {
fmt.Fprintf(w, "USAGE: %s [%s] SUBCOMMAND [subcommand opts]\n", info.Name, info.Opts)
fmt.Fprintf(w, "\nSUBCOMMANDS:\n")
for command := range info.Commands {
fmt.Fprintf(w, "\t%s\n", command)
}
}

4
go.mod
View file

@ -4,7 +4,9 @@ go 1.15
require ( require (
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/emersion/go-imap v1.0.6 // indirect github.com/emersion/go-imap v1.0.6
github.com/google/go-cmp v0.5.4 github.com/google/go-cmp v0.5.4
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/withmandala/go-log v0.1.0
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
) )

12
go.sum
View file

@ -16,6 +16,18 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/withmandala/go-log v0.1.0 h1:wINmTEe7BQ6zEA8sE7lSsYeaxCLluK6RFjF/IB5tzkA=
github.com/withmandala/go-log v0.1.0/go.mod h1:/V9xQUTW74VjYm3u2Liv/bIUGLWoL9z2GlHwtscp4vg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=