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)
|
return NewTomorrow(conf)
|
||||||
case "new":
|
case "new":
|
||||||
return NewNew(conf, cmdArgs)
|
return NewNew(conf, cmdArgs)
|
||||||
|
case "done":
|
||||||
|
return NewDone(conf, cmdArgs)
|
||||||
default:
|
default:
|
||||||
return NewEmpty()
|
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
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.ewintr.nl/gte/internal/task"
|
"git.ewintr.nl/gte/internal/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrTaskNotFound = errors.New("task was not found")
|
||||||
|
)
|
||||||
|
|
||||||
type LocalRepository interface {
|
type LocalRepository interface {
|
||||||
LatestSync() (time.Time, error)
|
LatestSync() (time.Time, error)
|
||||||
SetTasks(tasks []*task.Task) error
|
SetTasks(tasks []*task.Task) error
|
||||||
FindAllInFolder(folder string) ([]*task.Task, error)
|
FindAllInFolder(folder string) ([]*task.Task, error)
|
||||||
FindAllInProject(project 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
|
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"
|
folder1, folder2 := "folder1", "folder2"
|
||||||
project1, project2 := "project1", "project2"
|
project1, project2 := "project1", "project2"
|
||||||
task1 := &task.Task{
|
task1 := &task.Task{
|
||||||
|
Id: "id-1",
|
||||||
Folder: folder1,
|
Folder: folder1,
|
||||||
Project: project1,
|
Project: project1,
|
||||||
Action: "action1",
|
Action: "action1",
|
||||||
|
@ -22,6 +23,7 @@ func TestMemory(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
task2 := &task.Task{
|
task2 := &task.Task{
|
||||||
|
Id: "id-2",
|
||||||
Folder: folder1,
|
Folder: folder1,
|
||||||
Project: project2,
|
Project: project2,
|
||||||
Action: "action2",
|
Action: "action2",
|
||||||
|
@ -30,6 +32,7 @@ func TestMemory(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
task3 := &task.Task{
|
task3 := &task.Task{
|
||||||
|
Id: "id-3",
|
||||||
Folder: folder2,
|
Folder: folder2,
|
||||||
Project: project1,
|
Project: project1,
|
||||||
Action: "action3",
|
Action: "action3",
|
||||||
|
@ -75,4 +78,12 @@ func TestMemory(t *testing.T) {
|
||||||
}
|
}
|
||||||
test.Equals(t, exp, act)
|
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)
|
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) {
|
func tasksFromRows(rows *sql.Rows) ([]*task.Task, error) {
|
||||||
tasks := []*task.Task{}
|
tasks := []*task.Task{}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue