argset shape
This commit is contained in:
parent
d1209b8af1
commit
b772ca5df4
|
@ -20,8 +20,7 @@ type AddCmd struct {
|
|||
localIDRepo storage.LocalID
|
||||
eventRepo storage.Event
|
||||
syncRepo storage.Sync
|
||||
title string
|
||||
flags map[string]Flag
|
||||
argSet *ArgSet
|
||||
}
|
||||
|
||||
func NewAddCmd(localRepo storage.LocalID, eventRepo storage.Event, syncRepo storage.Sync) Command {
|
||||
|
@ -29,35 +28,38 @@ func NewAddCmd(localRepo storage.LocalID, eventRepo storage.Event, syncRepo stor
|
|||
localIDRepo: localRepo,
|
||||
eventRepo: eventRepo,
|
||||
syncRepo: syncRepo,
|
||||
flags: map[string]Flag{
|
||||
FlagOn: &FlagDate{},
|
||||
FlagAt: &FlagTime{},
|
||||
FlagFor: &FlagDuration{},
|
||||
argSet: &ArgSet{
|
||||
Flags: map[string]Flag{
|
||||
FlagOn: &FlagDate{},
|
||||
FlagAt: &FlagTime{},
|
||||
FlagFor: &FlagDuration{},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (add *AddCmd) Parse(as *ArgSet) error {
|
||||
if len(as.Main) == 0 || as.Main[0] != "add " {
|
||||
func (add *AddCmd) Parse(main []string, flags map[string]string) error {
|
||||
if len(main) == 0 || main[0] != "add " {
|
||||
return ErrWrongCommand
|
||||
}
|
||||
add.title = strings.Join(as.Main[1:], " ")
|
||||
for k := range add.flags {
|
||||
if err := add.flags[k].Set(as.Flags[k]); err != nil {
|
||||
as := add.argSet
|
||||
as.Main = strings.Join(main[1:], " ")
|
||||
for k := range as.Flags {
|
||||
if err := as.Set(k, flags[k]); err != nil {
|
||||
return fmt.Errorf("could not set %s: %v", k, err)
|
||||
}
|
||||
}
|
||||
if add.title == "" {
|
||||
if as.Main == "" {
|
||||
return fmt.Errorf("%w: title is required", ErrInvalidArg)
|
||||
}
|
||||
if !add.flags[FlagOn].IsSet() {
|
||||
if !as.IsSet(FlagOn) {
|
||||
return fmt.Errorf("%w: date is required", ErrInvalidArg)
|
||||
}
|
||||
if !add.flags[FlagAt].IsSet() && add.flags[FlagFor].IsSet() {
|
||||
if !as.IsSet(FlagAt) && as.IsSet(FlagFor) {
|
||||
return fmt.Errorf("%w: can not have duration without start time", ErrInvalidArg)
|
||||
}
|
||||
if !add.flags[FlagAt].IsSet() && !add.flags[FlagFor].IsSet() {
|
||||
if err := add.flags[FlagFor].Set("24h"); err != nil {
|
||||
if !as.IsSet(FlagAt) && !as.IsSet(FlagFor) {
|
||||
if err := as.Flags[FlagFor].Set("24h"); err != nil {
|
||||
return fmt.Errorf("could not set duration to 24 hours")
|
||||
}
|
||||
}
|
||||
|
@ -66,15 +68,13 @@ func (add *AddCmd) Parse(as *ArgSet) error {
|
|||
}
|
||||
|
||||
func (add *AddCmd) Do() error {
|
||||
startFormat := "2006-01-02"
|
||||
startStr := as.Flag(FlagOn)
|
||||
if as.HasFlag(FlagAt) {
|
||||
startFormat = fmt.Sprintf("%s 15:04", startFormat)
|
||||
startStr = fmt.Sprintf("%s %s", startStr, as.Flag(FlagAt))
|
||||
}
|
||||
start, err := time.Parse(startFormat, startStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: could not parse start time and date: %v", ErrInvalidArg, err)
|
||||
as := add.argSet
|
||||
start := as.GetTime(FlagOn)
|
||||
if as.IsSet(FlagAt) {
|
||||
at := as.GetTime(FlagAt)
|
||||
h := time.Duration(at.Hour()) * time.Hour
|
||||
m := time.Duration(at.Minute()) * time.Minute
|
||||
start = start.Add(h).Add(m)
|
||||
}
|
||||
|
||||
e := item.Event{
|
||||
|
@ -85,12 +85,8 @@ func (add *AddCmd) Do() error {
|
|||
},
|
||||
}
|
||||
|
||||
if as.HasFlag(FlagFor) {
|
||||
fr, err := time.ParseDuration(as.Flag(FlagFor))
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: could not parse duration: %s", ErrInvalidArg, err)
|
||||
}
|
||||
e.Duration = fr
|
||||
if as.IsSet(FlagFor) {
|
||||
e.Duration = as.GetDuration(FlagFor)
|
||||
}
|
||||
if err := add.eventRepo.Store(e); err != nil {
|
||||
return fmt.Errorf("could not store event: %v", err)
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ArgSet struct {
|
||||
Main string
|
||||
Flags map[string]Flag
|
||||
}
|
||||
|
||||
func (as *ArgSet) Set(name, val string) error {
|
||||
f, ok := as.Flags[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown flag %s", name)
|
||||
}
|
||||
return f.Set(val)
|
||||
}
|
||||
|
||||
func (as *ArgSet) IsSet(name string) bool {
|
||||
f, ok := as.Flags[name]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return f.IsSet()
|
||||
}
|
||||
|
||||
func (as *ArgSet) GetString(name string) string {
|
||||
flag, ok := as.Flags[name]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
val, ok := flag.Get().(string)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (as *ArgSet) GetTime(name string) time.Time {
|
||||
flag, ok := as.Flags[name]
|
||||
if !ok {
|
||||
return time.Time{}
|
||||
}
|
||||
val, ok := flag.Get().(time.Time)
|
||||
if !ok {
|
||||
return time.Time{}
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (as *ArgSet) GetDuration(name string) time.Duration {
|
||||
flag, ok := as.Flags[name]
|
||||
if !ok {
|
||||
return time.Duration(0)
|
||||
}
|
||||
val, ok := flag.Get().(time.Duration)
|
||||
if !ok {
|
||||
return time.Duration(0)
|
||||
}
|
||||
return val
|
||||
}
|
|
@ -6,13 +6,8 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
type ArgSet struct {
|
||||
Main []string
|
||||
Flags map[string]string
|
||||
}
|
||||
|
||||
type Command interface {
|
||||
Parse(args *ArgSet) error
|
||||
Parse([]string, map[string]string) error
|
||||
Do() error
|
||||
}
|
||||
|
||||
|
@ -21,12 +16,12 @@ type CLI struct {
|
|||
}
|
||||
|
||||
func (cli *CLI) Run(args []string) error {
|
||||
as, err := ParseFlags(args)
|
||||
main, flags, err := ParseFlags(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, c := range cli.Commands {
|
||||
err := c.Parse(as)
|
||||
err := c.Parse(main, flags)
|
||||
switch {
|
||||
case errors.Is(err, ErrWrongCommand):
|
||||
continue
|
||||
|
@ -40,7 +35,7 @@ func (cli *CLI) Run(args []string) error {
|
|||
return fmt.Errorf("could not find matching command")
|
||||
}
|
||||
|
||||
func ParseFlags(args []string) (*ArgSet, error) {
|
||||
func ParseFlags(args []string) ([]string, map[string]string, error) {
|
||||
flags := make(map[string]string)
|
||||
main := make([]string, 0)
|
||||
var inMain bool
|
||||
|
@ -48,7 +43,7 @@ func ParseFlags(args []string) (*ArgSet, error) {
|
|||
if strings.HasPrefix(args[i], "-") {
|
||||
inMain = false
|
||||
if i+1 >= len(args) {
|
||||
return nil, fmt.Errorf("flag wihout value")
|
||||
return nil, nil, fmt.Errorf("flag wihout value")
|
||||
}
|
||||
flags[strings.TrimPrefix(args[i], "-")] = args[i+1]
|
||||
i++
|
||||
|
@ -56,14 +51,11 @@ func ParseFlags(args []string) (*ArgSet, error) {
|
|||
}
|
||||
|
||||
if !inMain && len(main) > 0 {
|
||||
return nil, fmt.Errorf("two mains")
|
||||
return nil, nil, fmt.Errorf("two mains")
|
||||
}
|
||||
inMain = true
|
||||
main = append(main, args[i])
|
||||
}
|
||||
|
||||
return &ArgSet{
|
||||
Main: main,
|
||||
Flags: flags,
|
||||
}, nil
|
||||
return main, flags, nil
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ var (
|
|||
type Flag interface {
|
||||
Set(val string) error
|
||||
IsSet() bool
|
||||
Get() any
|
||||
}
|
||||
|
||||
type FlagString struct {
|
||||
|
@ -35,6 +36,10 @@ func (fs *FlagString) IsSet() bool {
|
|||
return fs.Value != ""
|
||||
}
|
||||
|
||||
func (fs *FlagString) Get() any {
|
||||
return fs.Value
|
||||
}
|
||||
|
||||
type FlagDate struct {
|
||||
Name string
|
||||
Value time.Time
|
||||
|
@ -54,6 +59,10 @@ func (ft *FlagDate) IsSet() bool {
|
|||
return ft.Value.IsZero()
|
||||
}
|
||||
|
||||
func (fs *FlagDate) Get() any {
|
||||
return fs.Value
|
||||
}
|
||||
|
||||
type FlagTime struct {
|
||||
Name string
|
||||
Value time.Time
|
||||
|
@ -73,6 +82,10 @@ func (fd *FlagTime) IsSet() bool {
|
|||
return fd.Value.IsZero()
|
||||
}
|
||||
|
||||
func (fs *FlagTime) Get() any {
|
||||
return fs.Value
|
||||
}
|
||||
|
||||
type FlagDuration struct {
|
||||
Name string
|
||||
Value time.Duration
|
||||
|
@ -90,3 +103,7 @@ func (fd *FlagDuration) Set(val string) error {
|
|||
func (fd *FlagDuration) IsSet() bool {
|
||||
return fd.Value.String() != "0s"
|
||||
}
|
||||
|
||||
func (fs *FlagDuration) Get() any {
|
||||
return fs.Value
|
||||
}
|
||||
|
|
17
plan/main.go
17
plan/main.go
|
@ -5,7 +5,6 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"go-mod.ewintr.nl/planner/plan/command"
|
||||
"go-mod.ewintr.nl/planner/plan/storage/sqlite"
|
||||
"go-mod.ewintr.nl/planner/sync/client"
|
||||
|
@ -32,19 +31,17 @@ func main() {
|
|||
|
||||
syncClient := client.New(conf.SyncURL, conf.ApiKey)
|
||||
|
||||
app := &cli.App{
|
||||
Name: "plan",
|
||||
Usage: "Plan your day with events",
|
||||
Commands: []*cli.Command{
|
||||
cli := command.CLI{
|
||||
Commands: []command.Command{
|
||||
command.NewAddCmd(localIDRepo, eventRepo, syncRepo),
|
||||
command.NewListCmd(localIDRepo, eventRepo),
|
||||
command.NewUpdateCmd(localIDRepo, eventRepo, syncRepo),
|
||||
command.NewDeleteCmd(localIDRepo, eventRepo, syncRepo),
|
||||
command.NewSyncCmd(syncClient, syncRepo, localIDRepo, eventRepo),
|
||||
// command.NewListCmd(localIDRepo, eventRepo),
|
||||
// command.NewUpdateCmd(localIDRepo, eventRepo, syncRepo),
|
||||
// command.NewDeleteCmd(localIDRepo, eventRepo, syncRepo),
|
||||
// command.NewSyncCmd(syncClient, syncRepo, localIDRepo, eventRepo),
|
||||
},
|
||||
}
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
if err := cli.Run(os.Args); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue