improve cli field args parser
This commit is contained in:
parent
d53363f1ca
commit
248edf6379
|
@ -2,9 +2,12 @@ package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"ewintr.nl/gte/internal/configuration"
|
"ewintr.nl/gte/internal/configuration"
|
||||||
|
"ewintr.nl/gte/internal/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -12,6 +15,9 @@ var (
|
||||||
ErrInvalidArg = errors.New("invalid argument")
|
ErrInvalidArg = errors.New("invalid argument")
|
||||||
ErrCouldNotFindTask = errors.New("could not find task")
|
ErrCouldNotFindTask = errors.New("could not find task")
|
||||||
ErrUnknownFolder = errors.New("unknown folder")
|
ErrUnknownFolder = errors.New("unknown folder")
|
||||||
|
ErrFieldAlreadyUsed = errors.New("field was already used")
|
||||||
|
ErrInvalidDate = errors.New("could not understand date format")
|
||||||
|
ErrInvalidProject = errors.New("could not understand project")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command interface {
|
type Command interface {
|
||||||
|
@ -89,3 +95,66 @@ func parseRemote(conf *configuration.Configuration, cmdArgs []string) (Command,
|
||||||
return cmd, ErrInvalidArg
|
return cmd, ErrInvalidArg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseTaskFieldArgs(args []string) (*task.LocalUpdate, error) {
|
||||||
|
lu := &task.LocalUpdate{}
|
||||||
|
|
||||||
|
action, fields := []string{}, []string{}
|
||||||
|
for _, f := range args {
|
||||||
|
if project, ok := parseProjectField(f); ok {
|
||||||
|
if lu.Project != "" {
|
||||||
|
return &task.LocalUpdate{}, fmt.Errorf("%w: %s", ErrFieldAlreadyUsed, task.FIELD_PROJECT)
|
||||||
|
|
||||||
|
}
|
||||||
|
if project == "" {
|
||||||
|
return &task.LocalUpdate{}, ErrInvalidProject
|
||||||
|
}
|
||||||
|
lu.Project = project
|
||||||
|
fields = append(fields, task.FIELD_PROJECT)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if due, ok := parseDueField(f); ok {
|
||||||
|
if due.IsZero() {
|
||||||
|
return &task.LocalUpdate{}, ErrInvalidDate
|
||||||
|
}
|
||||||
|
if !lu.Due.IsZero() {
|
||||||
|
return &task.LocalUpdate{}, fmt.Errorf("%w: %s", ErrFieldAlreadyUsed, task.FIELD_DUE)
|
||||||
|
}
|
||||||
|
lu.Due = due
|
||||||
|
fields = append(fields, task.FIELD_DUE)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(f) > 0 {
|
||||||
|
action = append(action, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(action) > 0 {
|
||||||
|
lu.Action = strings.Join(action, " ")
|
||||||
|
fields = append(fields, task.FIELD_ACTION)
|
||||||
|
}
|
||||||
|
|
||||||
|
lu.Fields = fields
|
||||||
|
|
||||||
|
return lu, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseProjectField(s string) (string, bool) {
|
||||||
|
if !strings.HasPrefix(s, "project:") && !strings.HasPrefix(s, "p:") {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
split := strings.SplitN(s, ":", 2)
|
||||||
|
|
||||||
|
return split[1], true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDueField(s string) (task.Date, bool) {
|
||||||
|
if !strings.HasPrefix(s, "due:") && !strings.HasPrefix(s, "d:") {
|
||||||
|
return task.Date{}, false
|
||||||
|
}
|
||||||
|
split := strings.SplitN(s, ":", 2)
|
||||||
|
|
||||||
|
due := task.NewDateFromString(split[1])
|
||||||
|
|
||||||
|
return due, true
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package format_test
|
package command_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"ewintr.nl/go-kit/test"
|
"ewintr.nl/go-kit/test"
|
||||||
"ewintr.nl/gte/cmd/cli/format"
|
"ewintr.nl/gte/cmd/cli/command"
|
||||||
"ewintr.nl/gte/internal/task"
|
"ewintr.nl/gte/internal/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -53,12 +53,47 @@ func TestParseTaskFieldArgs(t *testing.T) {
|
||||||
name: "two projects",
|
name: "two projects",
|
||||||
input: "project:project1 project:project2",
|
input: "project:project1 project:project2",
|
||||||
expUpdate: &task.LocalUpdate{},
|
expUpdate: &task.LocalUpdate{},
|
||||||
expErr: format.ErrFieldAlreadyUsed,
|
expErr: command.ErrFieldAlreadyUsed,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "abbreviated",
|
||||||
|
input: "p:project1 d:2022-09-28",
|
||||||
|
expUpdate: &task.LocalUpdate{
|
||||||
|
Fields: []string{task.FIELD_PROJECT, task.FIELD_DUE},
|
||||||
|
Project: "project1",
|
||||||
|
Due: task.NewDate(2022, 9, 28),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty project",
|
||||||
|
input: "action project:",
|
||||||
|
expUpdate: &task.LocalUpdate{},
|
||||||
|
expErr: command.ErrInvalidProject,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty date",
|
||||||
|
input: "action due:",
|
||||||
|
expUpdate: &task.LocalUpdate{},
|
||||||
|
expErr: command.ErrInvalidDate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "url",
|
||||||
|
input: "https://ewintr.nl/something?arg=1",
|
||||||
|
expUpdate: &task.LocalUpdate{
|
||||||
|
Fields: []string{task.FIELD_ACTION},
|
||||||
|
Action: "https://ewintr.nl/something?arg=1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "misformatted date",
|
||||||
|
input: "d:20-wrong",
|
||||||
|
expUpdate: &task.LocalUpdate{},
|
||||||
|
expErr: command.ErrInvalidDate,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
args := strings.Split(tc.input, " ")
|
args := strings.Split(tc.input, " ")
|
||||||
act, err := format.ParseTaskFieldArgs(args)
|
act, err := command.ParseTaskFieldArgs(args)
|
||||||
test.Equals(t, tc.expUpdate, act)
|
test.Equals(t, tc.expUpdate, act)
|
||||||
test.Assert(t, errors.Is(err, tc.expErr), "wrong err")
|
test.Assert(t, errors.Is(err, tc.expErr), "wrong err")
|
||||||
})
|
})
|
|
@ -18,7 +18,7 @@ func NewNew(conf *configuration.Configuration, cmdArgs []string) (*New, error) {
|
||||||
return &New{}, err
|
return &New{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
update, err := format.ParseTaskFieldArgs(cmdArgs)
|
update, err := ParseTaskFieldArgs(cmdArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &New{}, err
|
return &New{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func NewUpdate(localId int, conf *configuration.Configuration, cmdArgs []string)
|
||||||
return &Update{}, err
|
return &Update{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
update, err := format.ParseTaskFieldArgs(cmdArgs)
|
update, err := ParseTaskFieldArgs(cmdArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Update{}, err
|
return &Update{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
package format
|
package format
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"ewintr.nl/gte/internal/task"
|
"ewintr.nl/gte/internal/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ErrFieldAlreadyUsed = errors.New("field was already used")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Column int
|
type Column int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -42,41 +36,3 @@ due: %s
|
||||||
|
|
||||||
return fmt.Sprintf("%s\n", output)
|
return fmt.Sprintf("%s\n", output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseTaskFieldArgs(args []string) (*task.LocalUpdate, error) {
|
|
||||||
lu := &task.LocalUpdate{}
|
|
||||||
|
|
||||||
action, fields := []string{}, []string{}
|
|
||||||
for _, f := range args {
|
|
||||||
split := strings.SplitN(f, ":", 2)
|
|
||||||
if len(split) == 2 {
|
|
||||||
switch split[0] {
|
|
||||||
case "project":
|
|
||||||
if lu.Project != "" {
|
|
||||||
return &task.LocalUpdate{}, fmt.Errorf("%w: %s", ErrFieldAlreadyUsed, task.FIELD_PROJECT)
|
|
||||||
}
|
|
||||||
lu.Project = split[1]
|
|
||||||
fields = append(fields, task.FIELD_PROJECT)
|
|
||||||
case "due":
|
|
||||||
if !lu.Due.IsZero() {
|
|
||||||
return &task.LocalUpdate{}, fmt.Errorf("%w: %s", ErrFieldAlreadyUsed, task.FIELD_DUE)
|
|
||||||
}
|
|
||||||
lu.Due = task.NewDateFromString(split[1])
|
|
||||||
fields = append(fields, task.FIELD_DUE)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(f) > 0 {
|
|
||||||
action = append(action, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(action) > 0 {
|
|
||||||
lu.Action = strings.Join(action, " ")
|
|
||||||
fields = append(fields, task.FIELD_ACTION)
|
|
||||||
}
|
|
||||||
|
|
||||||
lu.Fields = fields
|
|
||||||
|
|
||||||
return lu, nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue