~ewintr/gte

22cad8287053912594f53854cdb02dd3cc17aa12 — Erik Winter 2 months ago 516f092
update asynchronous
M cmd/cli/command/done.go => cmd/cli/command/done.go +1 -4
@@ 6,7 6,6 @@ import (
	"git.ewintr.nl/gte/internal/process"
	"git.ewintr.nl/gte/internal/storage"
	"git.ewintr.nl/gte/internal/task"
	"git.ewintr.nl/gte/pkg/msend"
)

// Done updates a task to be marked done


@@ 19,8 18,6 @@ func NewDone(localId int, conf *configuration.Configuration) (*Done, error) {
	if err != nil {
		return &Done{}, err
	}

	disp := storage.NewDispatcher(msend.NewSSLSMTP(conf.SMTP()))
	localTask, err := local.FindByLocalId(localId)
	if err != nil {
		return &Done{}, err


@@ 31,7 28,7 @@ func NewDone(localId int, conf *configuration.Configuration) (*Done, error) {
		Fields:     []string{task.FIELD_DONE},
		Done:       true,
	}
	updater := process.NewUpdate(local, disp, localTask.Id, update)
	updater := process.NewUpdate(local, localTask.Id, update)

	return &Done{
		doner: updater,

M cmd/cli/command/update.go => cmd/cli/command/update.go +2 -4
@@ 9,7 9,6 @@ import (
	"git.ewintr.nl/gte/internal/process"
	"git.ewintr.nl/gte/internal/storage"
	"git.ewintr.nl/gte/internal/task"
	"git.ewintr.nl/gte/pkg/msend"
)

type Update struct {


@@ 22,7 21,6 @@ func NewUpdate(localId int, conf *configuration.Configuration, cmdArgs []string)
		return &Update{}, err
	}

	disp := storage.NewDispatcher(msend.NewSSLSMTP(conf.SMTP()))
	update, err := ParseTaskFieldArgs(cmdArgs)
	if err != nil {
		return &Update{}, err


@@ 33,7 31,7 @@ func NewUpdate(localId int, conf *configuration.Configuration, cmdArgs []string)
	}
	update.ForVersion = localTask.Version

	updater := process.NewUpdate(local, disp, localTask.Id, update)
	updater := process.NewUpdate(local, localTask.Id, update)

	return &Update{
		updater: updater,


@@ 45,7 43,7 @@ func (u *Update) Do() string {
		return format.FormatError(err)
	}

	return "message sent\n"
	return "local task updated\n"
}

func ParseTaskFieldArgs(args []string) (*task.LocalUpdate, error) {

M internal/process/update.go => internal/process/update.go +2 -9
@@ 12,18 12,16 @@ var (
	ErrUpdateTask = errors.New("could not update tsk")
)

// Update dispatches an updated version of a task
// Update updates a local task
type Update struct {
	local  storage.LocalRepository
	disp   *storage.Dispatcher
	taskId string
	update *task.LocalUpdate
}

func NewUpdate(local storage.LocalRepository, disp *storage.Dispatcher, taskId string, update *task.LocalUpdate) *Update {
func NewUpdate(local storage.LocalRepository, taskId string, update *task.LocalUpdate) *Update {
	return &Update{
		local:  local,
		disp:   disp,
		taskId: taskId,
		update: update,
	}


@@ 38,11 36,6 @@ func (u *Update) Process() error {
	if err := u.local.SetLocalUpdate(tsk); err != nil {
		return fmt.Errorf("%w: %v", ErrUpdateTask, err)
	}
	// create a new version and send it away
	tsk.ApplyUpdate()
	if err := u.disp.Dispatch(&tsk.Task); err != nil {
		return fmt.Errorf("%w: %v", ErrUpdateTask, err)
	}

	return nil
}

M internal/process/update_test.go => internal/process/update_test.go +16 -40
@@ 7,25 7,12 @@ import (
	"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",
		Version: 2,
		Project: "project1",
		Action:  "action1",
		Due:     task.NewDate(2021, 7, 29),
		Folder:  task.FOLDER_PLANNED,
	}
	local := storage.NewMemory()
	allTasks := []*task.Task{task1}

	for _, tc := range []struct {
		name    string
		updates *task.LocalUpdate
		exp     *task.Task
	}{
		{
			name: "done",


@@ 34,15 21,6 @@ func TestUpdate(t *testing.T) {
				Fields:     []string{task.FIELD_DONE},
				Done:       true,
			},
			exp: &task.Task{
				Id:      "id-1",
				Version: 2,
				Project: "project1",
				Action:  "action1",
				Due:     task.NewDate(2021, 7, 29),
				Folder:  task.FOLDER_PLANNED,
				Done:    true,
			},
		},
		{
			name: "fields",


@@ 53,29 31,27 @@ func TestUpdate(t *testing.T) {
				Action:     "action2",
				Due:        task.NewDate(2021, 8, 1),
			},
			exp: &task.Task{
				Id:      "id-1",
				Version: 2,
				Project: "project2",
				Action:  "action2",
				Due:     task.NewDate(2021, 8, 1),
				Folder:  task.FOLDER_PLANNED,
			},
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			test.OK(t, local.SetTasks(allTasks))
			out := msend.NewMemory()
			disp := storage.NewDispatcher(out)
			task1 := &task.Task{
				Id:      "id-1",
				Version: 2,
				Project: "project1",
				Action:  "action1",
				Due:     task.NewDate(2021, 7, 29),
				Folder:  task.FOLDER_PLANNED,
			}
			local := storage.NewMemory()
			allTasks := []*task.Task{task1}

			update := process.NewUpdate(local, disp, task1.Id, tc.updates)
			test.OK(t, local.SetTasks(allTasks))
			update := process.NewUpdate(local, task1.Id, tc.updates)
			test.OK(t, update.Process())
			expMsg := &msend.Message{
				Subject: tc.exp.FormatSubject(),
				Body:    tc.exp.FormatBody(),
			}
			test.Assert(t, len(out.Messages) == 1, "amount of messages was not one")
			test.Equals(t, expMsg, out.Messages[0])
			lt, err := local.FindById(task1.Id)
			test.OK(t, err)
			test.Equals(t, task.STATUS_UPDATED, lt.LocalStatus)
			test.Equals(t, tc.updates, lt.LocalUpdate)
		})
	}
}

M internal/task/localtask.go => internal/task/localtask.go +20 -15
@@ 132,23 132,23 @@ func (lu *LocalUpdate) Add(newUpdate *LocalUpdate) {
}

func (lu LocalUpdate) Value() (driver.Value, error) {
	var recurStr string
	if lu.Recur != nil {
		recurStr = lu.Recur.String()
	v := fmt.Sprintf("forversion: %d\n", lu.ForVersion)
	for _, f := range lu.Fields {
		switch f {
		case FIELD_ACTION:
			v += fmt.Sprintf("action: %s\n", lu.Action)
		case FIELD_PROJECT:
			v += fmt.Sprintf("project: %s\n", lu.Project)
		case FIELD_RECUR:
			v += fmt.Sprintf("recur: %s\n", lu.Recur.String())
		case FIELD_DUE:
			v += fmt.Sprintf("due: %s\n", lu.Due)
		case FIELD_DONE:
			v += fmt.Sprintf("done: %t\n", lu.Done)
		}
	}

	return fmt.Sprintf(`forversion: %d
action: %s
project: %s
recur: %s
due: %s
done: %t`,
		lu.ForVersion,
		lu.Action,
		lu.Project,
		recurStr,
		lu.Due.String(),
		lu.Done), nil
	return v, nil
}

func (lu *LocalUpdate) Scan(value interface{}) error {


@@ 172,15 172,20 @@ func (lu *LocalUpdate) Scan(value interface{}) error {
			newLu.ForVersion = d
		case "action":
			newLu.Action = v
			newLu.Fields = append(newLu.Fields, FIELD_ACTION)
		case "project":
			newLu.Project = v
			newLu.Fields = append(newLu.Fields, FIELD_PROJECT)
		case "recur":
			newLu.Recur = NewRecurrer(v)
			newLu.Fields = append(newLu.Fields, FIELD_RECUR)
		case "due":
			newLu.Due = NewDateFromString(v)
			newLu.Fields = append(newLu.Fields, FIELD_DUE)
		case "done":
			if v == "true" {
				newLu.Done = true
				newLu.Fields = append(newLu.Fields, FIELD_DONE)
			}
		}
	}