Skip to content

Commit 3e454e5

Browse files
authored
issue: 169 - shell auto complete using client and project names (#270)
* fix: "real factory" * feat: auto complete using client's name
1 parent 511bbf0 commit 3e454e5

File tree

19 files changed

+447
-140
lines changed

19 files changed

+447
-140
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Added
1515

1616
- new config `lang` to allow setting the number format to be used when printing
17+
- support to using client's name or id for autocompletion on bash
1718

1819
## [v0.52.0] - 2024-06-02
1920

cmd/gendocs/main.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ func execute() error {
5353
return "/en/commands/" + strings.ToLower(base) + "/"
5454
}
5555

56-
var f cmdutil.Factory
57-
cmd := cmd.NewCmdRoot(f)
56+
cmd := cmd.NewCmdRoot(cmdutil.NewFactory(cmdutil.Version{}))
5857

5958
fmt.Println("Generating Hugo command-line documentation in", docdir, "...")
6059
err := doc.GenMarkdownTreeCustom(cmd, docdir, prepender, linkHandler)

pkg/cmd/project/get/get.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func NewCmdGet(
2727
Use: "get",
2828
Args: cmdutil.RequiredNamedArgs("project"),
2929
ValidArgsFunction: cmdcompl.CombineSuggestionsToArgs(
30-
cmdcomplutil.NewProjectAutoComplete(f)),
30+
cmdcomplutil.NewProjectAutoComplete(f, f.Config())),
3131
Short: "Get a project on a Clockify workspace",
3232
Example: heredoc.Docf(`
3333
$ %[1]s 621948458cb9606d934ebb1c

pkg/cmd/project/get/get_test.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ func TestCmdGet(t *testing.T) {
3737
args: []string{"--format={}", "-q", "-j", "p1"},
3838
err: "flags can't be used together.*format.*json.*quiet",
3939
factory: func(t *testing.T) cmdutil.Factory {
40-
return mocks.NewMockFactory(t)
40+
f := mocks.NewMockFactory(t)
41+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
42+
43+
return f
4144
},
4245
},
4346
{
@@ -46,6 +49,8 @@ func TestCmdGet(t *testing.T) {
4649
args: []string{"p1"},
4750
factory: func(t *testing.T) cmdutil.Factory {
4851
f := mocks.NewMockFactory(t)
52+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
53+
4954
f.EXPECT().GetWorkspaceID().
5055
Return("", errors.New("workspace error"))
5156
return f
@@ -57,6 +62,8 @@ func TestCmdGet(t *testing.T) {
5762
args: []string{"p1"},
5863
factory: func(t *testing.T) cmdutil.Factory {
5964
f := mocks.NewMockFactory(t)
65+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
66+
6067
f.EXPECT().GetWorkspaceID().
6168
Return("w", nil)
6269
f.EXPECT().Client().Return(nil, errors.New("client error"))

pkg/cmd/task/add/add_test.go

+27-30
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ func TestCmdAdd(t *testing.T) {
2828
}
2929
}
3030

31+
dFactory := func(t *testing.T) cmdutil.Factory {
32+
f := mocks.NewMockFactory(t)
33+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
34+
return f
35+
}
36+
3137
tts := []struct {
3238
name string
3339
args []string
@@ -37,44 +43,34 @@ func TestCmdAdd(t *testing.T) {
3743
err string
3844
}{
3945
{
40-
name: "only one format",
41-
args: []string{"--format={}", "-q", "-j", "-n=OK", "-p=OK"},
42-
err: "flags can't be used together.*format.*json.*quiet",
43-
factory: func(t *testing.T) cmdutil.Factory {
44-
return mocks.NewMockFactory(t)
45-
},
46+
name: "only one format",
47+
args: []string{"--format={}", "-q", "-j", "-n=OK", "-p=OK"},
48+
err: "flags can't be used together.*format.*json.*quiet",
49+
factory: dFactory,
4650
},
4751
{
48-
name: "billable or not",
49-
args: []string{"--billable", "--not-billable", "-n=OK", "-p=OK"},
50-
err: "flags can't be used together.*billable.*not-billable",
51-
factory: func(t *testing.T) cmdutil.Factory {
52-
return mocks.NewMockFactory(t)
53-
},
52+
name: "billable or not",
53+
args: []string{"--billable", "--not-billable", "-n=OK", "-p=OK"},
54+
err: "flags can't be used together.*billable.*not-billable",
55+
factory: dFactory,
5456
},
5557
{
56-
name: "assignee or no assignee",
57-
args: []string{"--assignee=l", "--no-assignee", "-n=OK", "-p=OK"},
58-
err: "flags can't be used together.*assignee.*no-assignee",
59-
factory: func(t *testing.T) cmdutil.Factory {
60-
return mocks.NewMockFactory(t)
61-
},
58+
name: "assignee or no assignee",
59+
args: []string{"--assignee=l", "--no-assignee", "-n=OK", "-p=OK"},
60+
err: "flags can't be used together.*assignee.*no-assignee",
61+
factory: dFactory,
6262
},
6363
{
64-
name: "name required",
65-
args: []string{"-p=OK"},
66-
err: `"name" not set`,
67-
factory: func(t *testing.T) cmdutil.Factory {
68-
return mocks.NewMockFactory(t)
69-
},
64+
name: "name required",
65+
args: []string{"-p=OK"},
66+
err: `"name" not set`,
67+
factory: dFactory,
7068
},
7169
{
72-
name: "project required",
73-
args: []string{"-n=OK"},
74-
err: `"project" not set`,
75-
factory: func(t *testing.T) cmdutil.Factory {
76-
return mocks.NewMockFactory(t)
77-
},
70+
name: "project required",
71+
args: []string{"-n=OK"},
72+
err: `"project" not set`,
73+
factory: dFactory,
7874
},
7975
{
8076
name: "client error",
@@ -97,6 +93,7 @@ func TestCmdAdd(t *testing.T) {
9793
args: []string{"-n=a", "-p=b"},
9894
factory: func(t *testing.T) cmdutil.Factory {
9995
f := mocks.NewMockFactory(t)
96+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
10097
f.On("GetWorkspaceID").
10198
Return("", errors.New("workspace error"))
10299
return f

pkg/cmd/task/delete/delete_test.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,19 @@ func TestCmdDelete(t *testing.T) {
3131
args: []string{},
3232
err: "requires arg task",
3333
params: func(t *testing.T) (cmdutil.Factory, report) {
34-
return mocks.NewMockFactory(t), nil
34+
f := mocks.NewMockFactory(t)
35+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
36+
return f, nil
3537
},
3638
},
3739
{
3840
name: "project is required",
3941
err: "flag.*project.*not set",
4042
args: []string{"task-id"},
4143
params: func(t *testing.T) (cmdutil.Factory, report) {
42-
return mocks.NewMockFactory(t), nil
44+
f := mocks.NewMockFactory(t)
45+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
46+
return f, nil
4347
},
4448
},
4549
{
@@ -48,6 +52,7 @@ func TestCmdDelete(t *testing.T) {
4852
args: []string{"task-id", "-p", "p-1"},
4953
params: func(t *testing.T) (cmdutil.Factory, report) {
5054
f := mocks.NewMockFactory(t)
55+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
5156
f.On("GetWorkspaceID").Return("", errors.New("w error"))
5257
return f, nil
5358
},
@@ -58,6 +63,7 @@ func TestCmdDelete(t *testing.T) {
5863
args: []string{"task-id", "-p", "p-1"},
5964
params: func(t *testing.T) (cmdutil.Factory, report) {
6065
f := mocks.NewMockFactory(t)
66+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
6167
f.On("GetWorkspaceID").Return("w", nil)
6268
f.On("Client").Return(nil, errors.New("c error"))
6369
return f, nil

pkg/cmd/task/done/done_test.go

+32-36
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ func TestCmdDone(t *testing.T) {
2929
}
3030
}
3131

32+
dFactory := func(t *testing.T) cmdutil.Factory {
33+
f := mocks.NewMockFactory(t)
34+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
35+
return f
36+
}
37+
3238
tts := []struct {
3339
name string
3440
args []string
@@ -38,59 +44,48 @@ func TestCmdDone(t *testing.T) {
3844
err string
3945
}{
4046
{
41-
name: "task id required",
42-
args: []string{"-p=cli"},
43-
err: `requires arg task`,
44-
factory: func(t *testing.T) cmdutil.Factory {
45-
return mocks.NewMockFactory(t)
46-
},
47+
name: "task id required",
48+
args: []string{"-p=cli"},
49+
err: `requires arg task`,
50+
factory: dFactory,
4751
},
4852
{
49-
name: "project required",
50-
args: []string{"task"},
51-
err: `"project" not set`,
52-
factory: func(t *testing.T) cmdutil.Factory {
53-
return mocks.NewMockFactory(t)
54-
},
53+
name: "project required",
54+
args: []string{"task"},
55+
err: `"project" not set`,
56+
factory: dFactory,
5557
},
5658
{
57-
name: "project not empty",
58-
args: []string{"task", "-p= "},
59-
err: `project should not be empty`,
60-
factory: func(t *testing.T) cmdutil.Factory {
61-
return mocks.NewMockFactory(t)
62-
},
59+
name: "project not empty",
60+
args: []string{"task", "-p= "},
61+
err: `project should not be empty`,
62+
factory: dFactory,
6363
},
6464
{
65-
name: "task id not empty",
66-
args: []string{" ", "-p=cli"},
67-
err: `task id/name should not be empty`,
68-
factory: func(t *testing.T) cmdutil.Factory {
69-
return mocks.NewMockFactory(t)
70-
},
65+
name: "task id not empty",
66+
args: []string{" ", "-p=cli"},
67+
err: `task id/name should not be empty`,
68+
factory: dFactory,
7169
},
7270
{
73-
name: "task id not empty (nice try)",
74-
args: []string{"not-empty", " ", "-p=cli"},
75-
err: `task id/name should not be empty`,
76-
factory: func(t *testing.T) cmdutil.Factory {
77-
return mocks.NewMockFactory(t)
78-
},
71+
name: "task id not empty (nice try)",
72+
args: []string{"not-empty", " ", "-p=cli"},
73+
err: `task id/name should not be empty`,
74+
factory: dFactory,
7975
},
8076
{
81-
name: "only one format",
82-
args: []string{"--format={}", "-q", "-j", "-p=OK", "done"},
83-
err: "flags can't be used together.*format.*json.*quiet",
84-
factory: func(t *testing.T) cmdutil.Factory {
85-
return mocks.NewMockFactory(t)
86-
},
77+
name: "only one format",
78+
args: []string{"--format={}", "-q", "-j", "-p=OK", "done"},
79+
err: "flags can't be used together.*format.*json.*quiet",
80+
factory: dFactory,
8781
},
8882
{
8983
name: "client error",
9084
err: "client error",
9185
args: []string{"done", "-p=b"},
9286
factory: func(t *testing.T) cmdutil.Factory {
9387
f := mocks.NewMockFactory(t)
88+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
9489
f.On("GetWorkspaceID").
9590
Return("w", nil)
9691

@@ -104,6 +99,7 @@ func TestCmdDone(t *testing.T) {
10499
args: []string{"done", "-p=b"},
105100
factory: func(t *testing.T) cmdutil.Factory {
106101
f := mocks.NewMockFactory(t)
102+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
107103
f.On("GetWorkspaceID").
108104
Return("", errors.New("workspace error"))
109105
return f

pkg/cmd/task/edit/edit_test.go

+30-36
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ func TestCmdEdit(t *testing.T) {
2828
return nil
2929
}
3030
}
31+
dFactory := func(t *testing.T) cmdutil.Factory {
32+
f := mocks.NewMockFactory(t)
33+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
34+
return f
35+
}
3136

3237
tts := []struct {
3338
name string
@@ -38,52 +43,40 @@ func TestCmdEdit(t *testing.T) {
3843
err string
3944
}{
4045
{
41-
name: "task id required",
42-
args: []string{"-p=cli"},
43-
err: `requires arg task`,
44-
factory: func(t *testing.T) cmdutil.Factory {
45-
return mocks.NewMockFactory(t)
46-
},
46+
name: "task id required",
47+
args: []string{"-p=cli"},
48+
err: `requires arg task`,
49+
factory: dFactory,
4750
},
4851
{
49-
name: "project required",
50-
args: []string{"task"},
51-
err: `"project" not set`,
52-
factory: func(t *testing.T) cmdutil.Factory {
53-
return mocks.NewMockFactory(t)
54-
},
52+
name: "project required",
53+
args: []string{"task"},
54+
err: `"project" not set`,
55+
factory: dFactory,
5556
},
5657
{
57-
name: "task id not empty",
58-
args: []string{" ", "-p=cli"},
59-
err: `task id should not be empty`,
60-
factory: func(t *testing.T) cmdutil.Factory {
61-
return mocks.NewMockFactory(t)
62-
},
58+
name: "task id not empty",
59+
args: []string{" ", "-p=cli"},
60+
err: `task id should not be empty`,
61+
factory: dFactory,
6362
},
6463
{
65-
name: "only one format",
66-
args: []string{"--format={}", "-q", "-j", "-p=OK", "edit"},
67-
err: "flags can't be used together.*format.*json.*quiet",
68-
factory: func(t *testing.T) cmdutil.Factory {
69-
return mocks.NewMockFactory(t)
70-
},
64+
name: "only one format",
65+
args: []string{"--format={}", "-q", "-j", "-p=OK", "edit"},
66+
err: "flags can't be used together.*format.*json.*quiet",
67+
factory: dFactory,
7168
},
7269
{
73-
name: "billable or not",
74-
args: []string{"--billable", "--not-billable", "edit", "-p=OK"},
75-
err: "flags can't be used together.*billable.*not-billable",
76-
factory: func(t *testing.T) cmdutil.Factory {
77-
return mocks.NewMockFactory(t)
78-
},
70+
name: "billable or not",
71+
args: []string{"--billable", "--not-billable", "edit", "-p=OK"},
72+
err: "flags can't be used together.*billable.*not-billable",
73+
factory: dFactory,
7974
},
8075
{
81-
name: "assignee or no assignee",
82-
args: []string{"--assignee=l", "--no-assignee", "edit", "-p=OK"},
83-
err: "flags can't be used together.*assignee.*no-assignee",
84-
factory: func(t *testing.T) cmdutil.Factory {
85-
return mocks.NewMockFactory(t)
86-
},
76+
name: "assignee or no assignee",
77+
args: []string{"--assignee=l", "--no-assignee", "edit", "-p=OK"},
78+
err: "flags can't be used together.*assignee.*no-assignee",
79+
factory: dFactory,
8780
},
8881
{
8982
name: "client error",
@@ -106,6 +99,7 @@ func TestCmdEdit(t *testing.T) {
10699
args: []string{"edit", "-p=b"},
107100
factory: func(t *testing.T) cmdutil.Factory {
108101
f := mocks.NewMockFactory(t)
102+
f.EXPECT().Config().Return(&mocks.SimpleConfig{})
109103
f.On("GetWorkspaceID").
110104
Return("", errors.New("workspace error"))
111105
return f

0 commit comments

Comments
 (0)