Skip to content

Commit dc9fc2d

Browse files
committed
refactor: consolidate task selection logic into cmdutils package
1 parent 3c18cc6 commit dc9fc2d

File tree

4 files changed

+81
-147
lines changed

4 files changed

+81
-147
lines changed

pkg/cmd/time/create/create.go

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,24 @@ import (
77

88
"github.com/spf13/cobra"
99
"github.com/timwehrle/asana/internal/api/asana"
10-
"github.com/timwehrle/asana/internal/config"
11-
"github.com/timwehrle/asana/internal/prompter"
10+
"github.com/timwehrle/asana/pkg/cmdutils"
1211
"github.com/timwehrle/asana/pkg/convert"
1312
"github.com/timwehrle/asana/pkg/factory"
1413
"github.com/timwehrle/asana/pkg/format"
15-
"github.com/timwehrle/asana/pkg/iostreams"
1614
)
1715

1816
type CreateOptions struct {
19-
IO *iostreams.IOStreams
20-
Prompter prompter.Prompter
21-
22-
Config func() (*config.Config, error)
23-
Client func() (*asana.Client, error)
17+
cmdutils.BaseOptions
2418
}
2519

2620
func NewCmdCreate(f factory.Factory, runF func(*CreateOptions) error) *cobra.Command {
2721
opts := &CreateOptions{
28-
IO: f.IOStreams,
29-
Prompter: f.Prompter,
30-
Config: f.Config,
31-
Client: f.Client,
22+
BaseOptions: cmdutils.BaseOptions{
23+
IO: f.IOStreams,
24+
Prompter: f.Prompter,
25+
Config: f.Config,
26+
Client: f.Client,
27+
},
3228
}
3329

3430
cmd := &cobra.Command{
@@ -56,7 +52,7 @@ func runCreate(opts *CreateOptions) error {
5652
return err
5753
}
5854

59-
task, err := selectTask(opts, client)
55+
task, err := cmdutils.SelectTask(&opts.BaseOptions, client)
6056
if err != nil {
6157
return err
6258
}
@@ -109,39 +105,3 @@ func promptDate(opts *CreateOptions) (*asana.Date, error) {
109105

110106
return convert.ToDate(input, time.DateOnly)
111107
}
112-
113-
func selectTask(opts *CreateOptions, c *asana.Client) (*asana.Task, error) {
114-
cfg, err := opts.Config()
115-
if err != nil {
116-
return nil, fmt.Errorf("failed to get config: %w", err)
117-
}
118-
119-
tasks, _, err := c.QueryTasks(&asana.TaskQuery{
120-
Assignee: "me",
121-
Workspace: cfg.Workspace.ID,
122-
CompletedSince: "now",
123-
}, &asana.Options{
124-
Fields: []string{"name", "due_on"},
125-
})
126-
if err != nil {
127-
return nil, fmt.Errorf("failed to query tasks: %w", err)
128-
}
129-
130-
if len(tasks) == 0 {
131-
opts.IO.Println("No tasks found.")
132-
return nil, nil
133-
}
134-
135-
taskNames := format.Tasks(tasks)
136-
index, err := opts.Prompter.Select("Select the task to see the time of:", taskNames)
137-
if err != nil {
138-
return nil, fmt.Errorf("failed to select task: %w", err)
139-
}
140-
141-
selectedTask := tasks[index]
142-
if err := selectedTask.Fetch(c); err != nil {
143-
return nil, fmt.Errorf("failed to fetch task details: %w", err)
144-
}
145-
146-
return selectedTask, nil
147-
}

pkg/cmd/time/delete/delete.go

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,23 @@ import (
55

66
"github.com/spf13/cobra"
77
"github.com/timwehrle/asana/internal/api/asana"
8-
"github.com/timwehrle/asana/internal/config"
9-
"github.com/timwehrle/asana/internal/prompter"
8+
"github.com/timwehrle/asana/pkg/cmdutils"
109
"github.com/timwehrle/asana/pkg/factory"
1110
"github.com/timwehrle/asana/pkg/format"
12-
"github.com/timwehrle/asana/pkg/iostreams"
1311
)
1412

1513
type DeleteOptions struct {
16-
IO *iostreams.IOStreams
17-
Prompter prompter.Prompter
18-
19-
Config func() (*config.Config, error)
20-
Client func() (*asana.Client, error)
14+
cmdutils.BaseOptions
2115
}
2216

2317
func NewCmdDelete(f factory.Factory, runF func(*DeleteOptions) error) *cobra.Command {
2418
opts := &DeleteOptions{
25-
IO: f.IOStreams,
26-
Prompter: f.Prompter,
27-
Config: f.Config,
28-
Client: f.Client,
19+
BaseOptions: cmdutils.BaseOptions{
20+
IO: f.IOStreams,
21+
Prompter: f.Prompter,
22+
Config: f.Config,
23+
Client: f.Client,
24+
},
2925
}
3026

3127
cmd := &cobra.Command{
@@ -52,7 +48,7 @@ func runDelete(opts *DeleteOptions) error {
5248
return err
5349
}
5450

55-
task, err := selectTask(opts, client)
51+
task, err := cmdutils.SelectTask(&opts.BaseOptions, client)
5652
if err != nil {
5753
return err
5854
}
@@ -87,39 +83,3 @@ func runDelete(opts *DeleteOptions) error {
8783

8884
return nil
8985
}
90-
91-
func selectTask(opts *DeleteOptions, c *asana.Client) (*asana.Task, error) {
92-
cfg, err := opts.Config()
93-
if err != nil {
94-
return nil, fmt.Errorf("failed to get config: %w", err)
95-
}
96-
97-
tasks, _, err := c.QueryTasks(&asana.TaskQuery{
98-
Assignee: "me",
99-
Workspace: cfg.Workspace.ID,
100-
CompletedSince: "now",
101-
}, &asana.Options{
102-
Fields: []string{"name", "due_on"},
103-
})
104-
if err != nil {
105-
return nil, fmt.Errorf("failed to query tasks: %w", err)
106-
}
107-
108-
if len(tasks) == 0 {
109-
opts.IO.Println("No tasks found.")
110-
return nil, nil
111-
}
112-
113-
taskNames := format.Tasks(tasks)
114-
index, err := opts.Prompter.Select("Select a task to view tracked time:", taskNames)
115-
if err != nil {
116-
return nil, fmt.Errorf("failed to select task: %w", err)
117-
}
118-
119-
selectedTask := tasks[index]
120-
if err := selectedTask.Fetch(c); err != nil {
121-
return nil, fmt.Errorf("failed to fetch task details: %w", err)
122-
}
123-
124-
return selectedTask, nil
125-
}

pkg/cmd/time/status/status.go

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,23 @@ import (
88
"github.com/MakeNowJust/heredoc"
99
"github.com/spf13/cobra"
1010
"github.com/timwehrle/asana/internal/api/asana"
11-
"github.com/timwehrle/asana/internal/config"
12-
"github.com/timwehrle/asana/internal/prompter"
11+
"github.com/timwehrle/asana/pkg/cmdutils"
1312
"github.com/timwehrle/asana/pkg/factory"
1413
"github.com/timwehrle/asana/pkg/format"
15-
"github.com/timwehrle/asana/pkg/iostreams"
1614
)
1715

1816
type StatusOptions struct {
19-
IO *iostreams.IOStreams
20-
Prompter prompter.Prompter
21-
22-
Config func() (*config.Config, error)
23-
Client func() (*asana.Client, error)
17+
cmdutils.BaseOptions
2418
}
2519

2620
func NewCmdStatus(f factory.Factory, runF func(*StatusOptions) error) *cobra.Command {
2721
opts := &StatusOptions{
28-
IO: f.IOStreams,
29-
Prompter: f.Prompter,
30-
Config: f.Config,
31-
Client: f.Client,
22+
BaseOptions: cmdutils.BaseOptions{
23+
IO: f.IOStreams,
24+
Prompter: f.Prompter,
25+
Config: f.Config,
26+
Client: f.Client,
27+
},
3228
}
3329

3430
cmd := &cobra.Command{
@@ -68,7 +64,7 @@ func runStatus(opts *StatusOptions) error {
6864
return err
6965
}
7066

71-
task, err := selectTask(opts, client)
67+
task, err := cmdutils.SelectTask(&opts.BaseOptions, client)
7268
if err != nil {
7369
return err
7470
}
@@ -142,39 +138,3 @@ func groupEntries(entries []*asana.TimeTrackingEntry) ([]GroupedEntries, int, er
142138

143139
return groups, total, nil
144140
}
145-
146-
func selectTask(opts *StatusOptions, c *asana.Client) (*asana.Task, error) {
147-
cfg, err := opts.Config()
148-
if err != nil {
149-
return nil, fmt.Errorf("failed to get config: %w", err)
150-
}
151-
152-
tasks, _, err := c.QueryTasks(&asana.TaskQuery{
153-
Assignee: "me",
154-
Workspace: cfg.Workspace.ID,
155-
CompletedSince: "now",
156-
}, &asana.Options{
157-
Fields: []string{"name", "due_on"},
158-
})
159-
if err != nil {
160-
return nil, fmt.Errorf("failed to query tasks: %w", err)
161-
}
162-
163-
if len(tasks) == 0 {
164-
opts.IO.Println("No tasks found.")
165-
return nil, nil
166-
}
167-
168-
taskNames := format.Tasks(tasks)
169-
index, err := opts.Prompter.Select("Select a task to view tracked time:", taskNames)
170-
if err != nil {
171-
return nil, fmt.Errorf("failed to select task: %w", err)
172-
}
173-
174-
selectedTask := tasks[index]
175-
if err := selectedTask.Fetch(c); err != nil {
176-
return nil, fmt.Errorf("failed to fetch task details: %w", err)
177-
}
178-
179-
return selectedTask, nil
180-
}

pkg/cmdutils/select_task.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package cmdutils
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/timwehrle/asana/internal/api/asana"
7+
"github.com/timwehrle/asana/internal/config"
8+
"github.com/timwehrle/asana/internal/prompter"
9+
"github.com/timwehrle/asana/pkg/format"
10+
"github.com/timwehrle/asana/pkg/iostreams"
11+
)
12+
13+
type BaseOptions struct {
14+
IO *iostreams.IOStreams
15+
Prompter prompter.Prompter
16+
Config func() (*config.Config, error)
17+
Client func() (*asana.Client, error)
18+
}
19+
20+
func SelectTask(opts *BaseOptions, c *asana.Client) (*asana.Task, error) {
21+
cfg, err := opts.Config()
22+
if err != nil {
23+
return nil, fmt.Errorf("failed to get config: %w", err)
24+
}
25+
26+
tasks, _, err := c.QueryTasks(&asana.TaskQuery{
27+
Assignee: "me",
28+
Workspace: cfg.Workspace.ID,
29+
CompletedSince: "now",
30+
}, &asana.Options{
31+
Fields: []string{"name", "due_on"},
32+
})
33+
if err != nil {
34+
return nil, fmt.Errorf("failed to query tasks: %w", err)
35+
}
36+
37+
if len(tasks) == 0 {
38+
opts.IO.Println("No tasks found.")
39+
return nil, nil
40+
}
41+
42+
taskNames := format.Tasks(tasks)
43+
index, err := opts.Prompter.Select("Select a task to view tracked time:", taskNames)
44+
if err != nil {
45+
return nil, fmt.Errorf("failed to select task: %w", err)
46+
}
47+
48+
selectedTask := tasks[index]
49+
if err := selectedTask.Fetch(c); err != nil {
50+
return nil, fmt.Errorf("failed to fetch task details: %w", err)
51+
}
52+
53+
return selectedTask, nil
54+
}

0 commit comments

Comments
 (0)