done command
This commit is contained in:
parent
addf95a2e7
commit
56c4b22a43
|
@ -29,6 +29,8 @@ func Parse(args []string, conf *configuration.Configuration) (Command, error) {
|
|||
return NewTomorrow(conf)
|
||||
case "new":
|
||||
return NewNew(conf, cmdArgs)
|
||||
case "done":
|
||||
return NewDone(conf, cmdArgs)
|
||||
default:
|
||||
return NewEmpty()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"git.ewintr.nl/gte/cmd/cli/format"
|
||||
"git.ewintr.nl/gte/internal/configuration"
|
||||
"git.ewintr.nl/gte/internal/process"
|
||||
"git.ewintr.nl/gte/internal/storage"
|
||||
"git.ewintr.nl/gte/pkg/msend"
|
||||
)
|
||||
|
||||
// Done updates a task to be marked done
|
||||
type Done struct {
|
||||
doner *process.Update
|
||||
}
|
||||
|
||||
func NewDone(conf *configuration.Configuration, cmdArgs []string) (*Done, error) {
|
||||
local, err := storage.NewSqlite(conf.Sqlite())
|
||||
if err != nil {
|
||||
return &Done{}, err
|
||||
}
|
||||
|
||||
disp := storage.NewDispatcher(msend.NewSSLSMTP(conf.SMTP()))
|
||||
fields := process.UpdateFields{"done": "true"}
|
||||
|
||||
updater := process.NewUpdate(local, disp, cmdArgs[0], fields)
|
||||
|
||||
return &Done{
|
||||
doner: updater,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Done) Do() string {
|
||||
err := d.doner.Process()
|
||||
if err != nil {
|
||||
return format.FormatError(err)
|
||||
}
|
||||
|
||||
return "message sent\n"
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package process
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.ewintr.nl/gte/internal/storage"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUpdateTask = errors.New("could not update task")
|
||||
)
|
||||
|
||||
// Update dispatches an updated version of a task
|
||||
type Update struct {
|
||||
local storage.LocalRepository
|
||||
disp *storage.Dispatcher
|
||||
taskId string
|
||||
updates UpdateFields
|
||||
}
|
||||
|
||||
type UpdateFields map[string]string
|
||||
|
||||
func NewUpdate(local storage.LocalRepository, disp *storage.Dispatcher, taskId string, updates UpdateFields) *Update {
|
||||
return &Update{
|
||||
local: local,
|
||||
disp: disp,
|
||||
taskId: taskId,
|
||||
updates: updates,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Update) Process() error {
|
||||
task, err := u.local.FindById(u.taskId)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrUpdateTask, err)
|
||||
}
|
||||
|
||||
for k, v := range u.updates {
|
||||
switch k {
|
||||
case "done":
|
||||
if v == "true" {
|
||||
task.Done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := u.disp.Dispatch(task); err != nil {
|
||||
return fmt.Errorf("%w: %v", ErrUpdateTask, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package process_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.ewintr.nl/go-kit/test"
|
||||
"git.ewintr.nl/gte/internal/process"
|
||||
"git.ewintr.nl/gte/internal/storage"
|
||||
"git.ewintr.nl/gte/internal/task"
|
||||
"git.ewintr.nl/gte/pkg/msend"
|
||||
)
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
task1 := &task.Task{
|
||||
Id: "id-1",
|
||||
Project: "project1",
|
||||
Action: "action1",
|
||||
Folder: task.FOLDER_PLANNED,
|
||||
}
|
||||
local := storage.NewMemory()
|
||||
out := msend.NewMemory()
|
||||
disp := storage.NewDispatcher(out)
|
||||
allTasks := []*task.Task{task1}
|
||||
|
||||
t.Run("done", func(t *testing.T) {
|
||||
local.SetTasks(allTasks)
|
||||
updates := process.UpdateFields{
|
||||
"done": "true",
|
||||
}
|
||||
|
||||
update := process.NewUpdate(local, disp, task1.Id, updates)
|
||||
test.OK(t, update.Process())
|
||||
expTask := task1
|
||||
expTask.Done = true
|
||||
expMsg := &msend.Message{
|
||||
Subject: expTask.FormatSubject(),
|
||||
Body: expTask.FormatBody(),
|
||||
}
|
||||
test.Assert(t, len(out.Messages) == 1, "amount of messages was not one")
|
||||
test.Equals(t, expMsg, out.Messages[0])
|
||||
|
||||
})
|
||||
}
|
|
@ -1,14 +1,20 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"git.ewintr.nl/gte/internal/task"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrTaskNotFound = errors.New("task was not found")
|
||||
)
|
||||
|
||||
type LocalRepository interface {
|
||||
LatestSync() (time.Time, error)
|
||||
SetTasks(tasks []*task.Task) error
|
||||
FindAllInFolder(folder string) ([]*task.Task, error)
|
||||
FindAllInProject(project string) ([]*task.Task, error)
|
||||
FindById(id string) (*task.Task, error)
|
||||
}
|
||||
|
|
|
@ -56,3 +56,14 @@ func (m *Memory) FindAllInProject(project string) ([]*task.Task, error) {
|
|||
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
func (m *Memory) FindById(id string) (*task.Task, error) {
|
||||
for _, t := range m.tasks {
|
||||
if t.Id == id {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return &task.Task{}, ErrTaskNotFound
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ func TestMemory(t *testing.T) {
|
|||
folder1, folder2 := "folder1", "folder2"
|
||||
project1, project2 := "project1", "project2"
|
||||
task1 := &task.Task{
|
||||
Id: "id-1",
|
||||
Folder: folder1,
|
||||
Project: project1,
|
||||
Action: "action1",
|
||||
|
@ -22,6 +23,7 @@ func TestMemory(t *testing.T) {
|
|||
},
|
||||
}
|
||||
task2 := &task.Task{
|
||||
Id: "id-2",
|
||||
Folder: folder1,
|
||||
Project: project2,
|
||||
Action: "action2",
|
||||
|
@ -30,6 +32,7 @@ func TestMemory(t *testing.T) {
|
|||
},
|
||||
}
|
||||
task3 := &task.Task{
|
||||
Id: "id-3",
|
||||
Folder: folder2,
|
||||
Project: project1,
|
||||
Action: "action3",
|
||||
|
@ -75,4 +78,12 @@ func TestMemory(t *testing.T) {
|
|||
}
|
||||
test.Equals(t, exp, act)
|
||||
})
|
||||
|
||||
t.Run("findbyid", func(t *testing.T) {
|
||||
mem := storage.NewMemory()
|
||||
test.OK(t, mem.SetTasks(tasks))
|
||||
act, err := mem.FindById("id-2")
|
||||
test.OK(t, err)
|
||||
test.Equals(t, task2, act)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -122,6 +122,29 @@ WHERE project = ?`, project)
|
|||
return tasksFromRows(rows)
|
||||
}
|
||||
|
||||
func (s *Sqlite) FindById(id string) (*task.Task, error) {
|
||||
var folder, action, project, due, recur string
|
||||
var version int
|
||||
row := s.db.QueryRow(`
|
||||
SELECT version, folder, action, project, due, recur
|
||||
FROM task
|
||||
WHERE id = ?
|
||||
LIMIT 1`, id)
|
||||
if err := row.Scan(&version, &folder, &action, &project, &due, &recur); err != nil {
|
||||
return &task.Task{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
|
||||
}
|
||||
|
||||
return &task.Task{
|
||||
Id: id,
|
||||
Version: version,
|
||||
Folder: folder,
|
||||
Action: action,
|
||||
Project: project,
|
||||
Due: task.NewDateFromString(due),
|
||||
Recur: task.NewRecurrer(recur),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func tasksFromRows(rows *sql.Rows) ([]*task.Task, error) {
|
||||
tasks := []*task.Task{}
|
||||
|
||||
|
|
Loading…
Reference in New Issue