Skip to content

Commit 7834385

Browse files
committed
Merge branch 'tm/ui-tests' of https://github.com/Happycoil/cwc into Happycoil-tm/ui-tests
2 parents b8907b6 + 65af04b commit 7834385

File tree

13 files changed

+339
-76
lines changed

13 files changed

+339
-76
lines changed

cmd/config.go

+11-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
"github.com/intility/cwc/pkg/config"
1212
"github.com/intility/cwc/pkg/errors"
13-
"github.com/intility/cwc/pkg/ui"
13+
cwcui "github.com/intility/cwc/pkg/ui"
1414
)
1515

1616
func createConfigCommand() *cobra.Command {
@@ -128,6 +128,8 @@ func processKeyValuePairs(cfg *config.Config, kvPairs []string) error {
128128
}
129129

130130
func setConfigValue(cfg *config.Config, key, value string) error {
131+
ui := cwcui.NewUI() //nolint:varnamelen
132+
131133
switch key {
132134
case "endpoint":
133135
cfg.Endpoint = value
@@ -150,7 +152,7 @@ func setConfigValue(cfg *config.Config, key, value string) error {
150152

151153
cfg.ExcludeGitDir = b
152154
default:
153-
ui.PrintMessage(fmt.Sprintf("Unknown config key: %s\n", key), ui.MessageTypeError)
155+
ui.PrintMessage(fmt.Sprintf("Unknown config key: %s\n", key), cwcui.MessageTypeError)
154156

155157
validKeys := []string{
156158
"endpoint",
@@ -160,7 +162,7 @@ func setConfigValue(cfg *config.Config, key, value string) error {
160162
"excludeGitDir",
161163
}
162164

163-
ui.PrintMessage("Valid keys are: "+strings.Join(validKeys, ", "), ui.MessageTypeInfo)
165+
ui.PrintMessage("Valid keys are: "+strings.Join(validKeys, ", "), cwcui.MessageTypeInfo)
164166

165167
return errors.SuppressedError{}
166168
}
@@ -183,6 +185,7 @@ func printConfig(cfg *config.Config) {
183185
}
184186

185187
func printTable(table [][]string) {
188+
ui := cwcui.NewUI() //nolint:varnamelen
186189
columnLengths := calculateColumnLengths(table)
187190

188191
var lineLength int
@@ -198,26 +201,26 @@ func printTable(table [][]string) {
198201
for lineIndex, line := range table {
199202
if lineIndex == 0 { // table header
200203
// lineLength-2 because of "+" as first and last charactr
201-
ui.PrintMessage(fmt.Sprintf("+%s+\n", strings.Repeat("-", singleLineLength)), ui.MessageTypeInfo)
204+
ui.PrintMessage(fmt.Sprintf("+%s+\n", strings.Repeat("-", singleLineLength)), cwcui.MessageTypeInfo)
202205
}
203206

204207
lineLoop:
205208
for rowIndex, val := range line {
206209
if val == "SEP" {
207210
// lineLength-2 because of "+" as first and last character
208-
ui.PrintMessage(fmt.Sprintf("+%s+\n", strings.Repeat("-", singleLineLength)), ui.MessageTypeInfo)
211+
ui.PrintMessage(fmt.Sprintf("+%s+\n", strings.Repeat("-", singleLineLength)), cwcui.MessageTypeInfo)
209212
break lineLoop
210213
}
211214

212-
ui.PrintMessage(fmt.Sprintf("| %-*s ", columnLengths[rowIndex], val), ui.MessageTypeInfo)
215+
ui.PrintMessage(fmt.Sprintf("| %-*s ", columnLengths[rowIndex], val), cwcui.MessageTypeInfo)
213216
if rowIndex == len(line)-1 {
214-
ui.PrintMessage("|\n", ui.MessageTypeInfo)
217+
ui.PrintMessage("|\n", cwcui.MessageTypeInfo)
215218
}
216219
}
217220

218221
if lineIndex == 0 || lineIndex == len(table)-1 { // table header or last line
219222
// lineLength-2 because of "+" as first and last character
220-
ui.PrintMessage(fmt.Sprintf("+%s+\n", strings.Repeat("-", singleLineLength)), ui.MessageTypeInfo)
223+
ui.PrintMessage(fmt.Sprintf("+%s+\n", strings.Repeat("-", singleLineLength)), cwcui.MessageTypeInfo)
221224
}
222225
}
223226
}

cmd/cwc.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"github.com/intility/cwc/pkg/prompting"
1414
"github.com/intility/cwc/pkg/systemcontext"
1515
"github.com/intility/cwc/pkg/templates"
16-
"github.com/intility/cwc/pkg/ui"
16+
cwcui "github.com/intility/cwc/pkg/ui"
1717
)
1818

1919
const (
@@ -182,7 +182,8 @@ func getPlatformSpecificConfigProvider() (config.Provider, error) { //nolint: ir
182182
}
183183

184184
func printContext(fileTree string, files []filetree.File) {
185-
ui.PrintMessage(fileTree, ui.MessageTypeInfo)
185+
ui := cwcui.NewUI()
186+
ui.PrintMessage(fileTree, cwcui.MessageTypeInfo)
186187

187188
for _, file := range files {
188189
printLargeFileWarning(file)
@@ -195,7 +196,8 @@ func printLargeFileWarning(file filetree.File) {
195196
"warning: %s is very large (%d bytes) and will degrade performance.\n",
196197
file.Path, len(file.Data))
197198

198-
ui.PrintMessage(largeFileMsg, ui.MessageTypeWarning)
199+
ui := cwcui.NewUI()
200+
ui.PrintMessage(largeFileMsg, cwcui.MessageTypeWarning)
199201
}
200202
}
201203

cmd/login.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
"github.com/intility/cwc/pkg/config"
99
"github.com/intility/cwc/pkg/errors"
10-
"github.com/intility/cwc/pkg/ui"
10+
cwcui "github.com/intility/cwc/pkg/ui"
1111
)
1212

1313
var (
@@ -17,6 +17,7 @@ var (
1717
)
1818

1919
func createLoginCmd() *cobra.Command {
20+
ui := cwcui.NewUI() //nolint:varnamelen
2021
cmd := &cobra.Command{
2122
Use: "login",
2223
Short: "Authenticate with Azure OpenAI",
@@ -26,17 +27,17 @@ func createLoginCmd() *cobra.Command {
2627
RunE: func(cmd *cobra.Command, args []string) error {
2728
// Prompt for other required authentication details (apiKey, endpoint, version, and deployment)
2829
if apiKeyFlag == "" {
29-
ui.PrintMessage("Enter the Azure OpenAI API Key: ", ui.MessageTypeInfo)
30+
ui.PrintMessage("Enter the Azure OpenAI API Key: ", cwcui.MessageTypeInfo)
3031
apiKeyFlag = config.SanitizeInput(ui.ReadUserInput())
3132
}
3233

3334
if endpointFlag == "" {
34-
ui.PrintMessage("Enter the Azure OpenAI API Endpoint: ", ui.MessageTypeInfo)
35+
ui.PrintMessage("Enter the Azure OpenAI API Endpoint: ", cwcui.MessageTypeInfo)
3536
endpointFlag = config.SanitizeInput(ui.ReadUserInput())
3637
}
3738

3839
if modelDeploymentFlag == "" {
39-
ui.PrintMessage("Enter the Azure OpenAI Model Deployment: ", ui.MessageTypeInfo)
40+
ui.PrintMessage("Enter the Azure OpenAI Model Deployment: ", cwcui.MessageTypeInfo)
4041
modelDeploymentFlag = config.SanitizeInput(ui.ReadUserInput())
4142
}
4243

@@ -48,7 +49,7 @@ func createLoginCmd() *cobra.Command {
4849
if err != nil {
4950
if validationErr, ok := errors.AsConfigValidationError(err); ok {
5051
for _, e := range validationErr.Errors {
51-
ui.PrintMessage(e+"\n", ui.MessageTypeError)
52+
ui.PrintMessage(e+"\n", cwcui.MessageTypeError)
5253
}
5354

5455
return nil // suppress the error
@@ -57,7 +58,7 @@ func createLoginCmd() *cobra.Command {
5758
return fmt.Errorf("error saving configuration: %w", err)
5859
}
5960

60-
ui.PrintMessage("config saved successfully\n", ui.MessageTypeSuccess)
61+
ui.PrintMessage("config saved successfully\n", cwcui.MessageTypeSuccess)
6162

6263
return nil
6364
},

cmd/templates.go

+25-23
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
"github.com/intility/cwc/pkg/config"
1010
"github.com/intility/cwc/pkg/templates"
11-
"github.com/intility/cwc/pkg/ui"
11+
cwcui "github.com/intility/cwc/pkg/ui"
1212
)
1313

1414
type Template struct {
@@ -18,47 +18,48 @@ type Template struct {
1818
}
1919

2020
func createTemplatesCmd() *cobra.Command {
21+
ui := cwcui.NewUI() //nolint:varnamelen
2122
cmd := &cobra.Command{
2223
Use: "templates",
2324
Short: "Lists available templates",
2425
RunE: func(cmd *cobra.Command, args []string) error {
2526
tmpls := locateTemplates()
2627

2728
if len(tmpls) == 0 {
28-
ui.PrintMessage("No templates found", ui.MessageTypeInfo)
29+
ui.PrintMessage("No templates found", cwcui.MessageTypeInfo)
2930
return nil
3031
}
3132

3233
if cfgDir, err := config.GetConfigDir(); err == nil {
33-
ui.PrintMessage("global", ui.MessageTypeWarning)
34+
ui.PrintMessage("global", cwcui.MessageTypeWarning)
3435
ui.PrintMessage(": the template is defined in "+
35-
filepath.Join(cfgDir, "templates.yaml")+"\n", ui.MessageTypeInfo)
36+
filepath.Join(cfgDir, "templates.yaml")+"\n", cwcui.MessageTypeInfo)
3637
}
3738

38-
ui.PrintMessage("local", ui.MessageTypeSuccess)
39-
ui.PrintMessage(": the template is defined in ./cwc/templates.yaml\n", ui.MessageTypeInfo)
39+
ui.PrintMessage("local", cwcui.MessageTypeSuccess)
40+
ui.PrintMessage(": the template is defined in ./cwc/templates.yaml\n", cwcui.MessageTypeInfo)
4041

41-
ui.PrintMessage("overridden", ui.MessageTypeError)
42-
ui.PrintMessage(": the local template is overriding a global template with the same name\n\n", ui.MessageTypeInfo)
42+
ui.PrintMessage("overridden", cwcui.MessageTypeError)
43+
ui.PrintMessage(": the local template is overriding a global template with the same name\n\n", cwcui.MessageTypeInfo)
4344

44-
ui.PrintMessage("Available templates:\n", ui.MessageTypeInfo)
45+
ui.PrintMessage("Available templates:\n", cwcui.MessageTypeInfo)
4546

4647
for _, template := range tmpls {
4748
if template.isOverridingGlobal {
4849
template.placement = "overridden"
4950
}
5051

51-
placementMessageType := ui.MessageTypeSuccess
52+
placementMessageType := cwcui.MessageTypeSuccess
5253
if template.placement == "global" {
53-
placementMessageType = ui.MessageTypeWarning
54+
placementMessageType = cwcui.MessageTypeWarning
5455
}
5556

5657
if template.isOverridingGlobal {
57-
placementMessageType = ui.MessageTypeError
58+
placementMessageType = cwcui.MessageTypeError
5859
}
5960

60-
ui.PrintMessage("- name: ", ui.MessageTypeInfo)
61-
ui.PrintMessage(template.template.Name, ui.MessageTypeInfo)
61+
ui.PrintMessage("- name: ", cwcui.MessageTypeInfo)
62+
ui.PrintMessage(template.template.Name, cwcui.MessageTypeInfo)
6263
ui.PrintMessage(" ("+template.placement+")\n", placementMessageType)
6364
printTemplateInfo(template.template)
6465
}
@@ -106,32 +107,33 @@ func locateTemplates() map[string]Template {
106107
}
107108

108109
func printTemplateInfo(template templates.Template) {
109-
ui.PrintMessage(" description: "+template.Description+"\n", ui.MessageTypeInfo)
110+
ui := cwcui.NewUI() //nolint:varnamelen
111+
ui.PrintMessage(" description: "+template.Description+"\n", cwcui.MessageTypeInfo)
110112

111113
dfp := "no"
112114
if template.DefaultPrompt != "" {
113115
dfp = "yes"
114116
}
115117

116-
ui.PrintMessage(" has_default_prompt: "+dfp+"\n", ui.MessageTypeInfo)
118+
ui.PrintMessage(" has_default_prompt: "+dfp+"\n", cwcui.MessageTypeInfo)
117119

118120
variablesCount := len(template.Variables)
119121

120-
ui.PrintMessage(" variables: "+strconv.Itoa(variablesCount)+"\n", ui.MessageTypeInfo)
122+
ui.PrintMessage(" variables: "+strconv.Itoa(variablesCount)+"\n", cwcui.MessageTypeInfo)
121123

122124
for _, variable := range template.Variables {
123-
ui.PrintMessage(" - name: ", ui.MessageTypeInfo)
124-
ui.PrintMessage(variable.Name, ui.MessageTypeInfo)
125-
ui.PrintMessage("\n", ui.MessageTypeInfo)
126-
ui.PrintMessage(" description: "+variable.Description+"\n", ui.MessageTypeInfo)
125+
ui.PrintMessage(" - name: ", cwcui.MessageTypeInfo)
126+
ui.PrintMessage(variable.Name, cwcui.MessageTypeInfo)
127+
ui.PrintMessage("\n", cwcui.MessageTypeInfo)
128+
ui.PrintMessage(" description: "+variable.Description+"\n", cwcui.MessageTypeInfo)
127129

128130
dv := "no"
129131
if variable.DefaultValue != "" {
130132
dv = "yes"
131133
}
132134

133-
ui.PrintMessage(" has_default_value: "+dv+"\n", ui.MessageTypeInfo)
135+
ui.PrintMessage(" has_default_value: "+dv+"\n", cwcui.MessageTypeInfo)
134136
}
135137

136-
ui.PrintMessage("\n", ui.MessageTypeInfo)
138+
ui.PrintMessage("\n", cwcui.MessageTypeInfo)
137139
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/intility/cwc
33
go 1.22
44

55
require (
6+
github.com/google/go-cmp v0.6.0
67
github.com/sashabaranov/go-openai v1.20.1
78
github.com/spf13/cobra v1.8.0
89
github.com/stretchr/testify v1.9.0

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
77
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
88
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
99
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
10+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
11+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1012
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
1113
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
1214
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

internal/interactive.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package internal
22

33
import (
44
"fmt"
5-
65
"github.com/sashabaranov/go-openai"
76

87
"github.com/intility/cwc/pkg/chat"
@@ -21,6 +20,7 @@ type InteractiveChatOptions struct {
2120
}
2221

2322
type InteractiveCmd struct {
23+
ui ui.UI
2424
clientProvider config.ClientProvider
2525
promptResolver prompting.PromptResolver
2626
smGenerator systemcontext.SystemMessageGenerator
@@ -34,6 +34,7 @@ func NewInteractiveCmd(
3434
chatOptions InteractiveChatOptions,
3535
) *InteractiveCmd {
3636
return &InteractiveCmd{
37+
ui: ui.NewUI(),
3738
promptResolver: promptResolver,
3839
clientProvider: clientProvider,
3940
chatOptions: chatOptions,
@@ -52,15 +53,15 @@ func (c *InteractiveCmd) Run() error {
5253
return fmt.Errorf("error creating system message: %w", err)
5354
}
5455

55-
ui.PrintMessage("Type '/exit' to end the chat.\n", ui.MessageTypeNotice)
56+
c.ui.PrintMessage("Type '/exit' to end the chat.\n", ui.MessageTypeNotice)
5657

5758
userPrompt := c.promptResolver.ResolvePrompt()
5859

5960
if userPrompt == "" {
60-
ui.PrintMessage("👤: ", ui.MessageTypeInfo)
61-
userPrompt = ui.ReadUserInput()
61+
c.ui.PrintMessage("👤: ", ui.MessageTypeInfo)
62+
userPrompt = c.ui.ReadUserInput()
6263
} else {
63-
ui.PrintMessage(fmt.Sprintf("👤: %s\n", userPrompt), ui.MessageTypeInfo)
64+
c.ui.PrintMessage(fmt.Sprintf("👤: %s\n", userPrompt), ui.MessageTypeInfo)
6465
}
6566

6667
if userPrompt == "/exit" {
@@ -78,9 +79,9 @@ func (c *InteractiveCmd) handleChat(client *openai.Client, systemMessage string,
7879

7980
for {
8081
conversation.WaitMyTurn()
81-
ui.PrintMessage("👤: ", ui.MessageTypeInfo)
82+
c.ui.PrintMessage("👤: ", ui.MessageTypeInfo)
8283

83-
userMessage := ui.ReadUserInput()
84+
userMessage := c.ui.ReadUserInput()
8485

8586
if userMessage == "/exit" {
8687
break
@@ -92,17 +93,17 @@ func (c *InteractiveCmd) handleChat(client *openai.Client, systemMessage string,
9293

9394
func (c *InteractiveCmd) printMessageChunk(chunk *chat.ConversationChunk) {
9495
if chunk.IsInitialChunk {
95-
ui.PrintMessage("🤖: ", ui.MessageTypeInfo)
96+
c.ui.PrintMessage("🤖: ", ui.MessageTypeInfo)
9697
return
9798
}
9899

99100
if chunk.IsErrorChunk {
100-
ui.PrintMessage(chunk.Content, ui.MessageTypeError)
101+
c.ui.PrintMessage(chunk.Content, ui.MessageTypeError)
101102
}
102103

103104
if chunk.IsFinalChunk {
104-
ui.PrintMessage("\n", ui.MessageTypeInfo)
105+
c.ui.PrintMessage("\n", ui.MessageTypeInfo)
105106
}
106107

107-
ui.PrintMessage(chunk.Content, ui.MessageTypeInfo)
108+
c.ui.PrintMessage(chunk.Content, ui.MessageTypeInfo)
108109
}

internal/noninteractive.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
)
1313

1414
type NonInteractiveCmd struct {
15+
ui ui.UI
1516
clientProvider config.ClientProvider
1617
promptResolver prompting.PromptResolver
1718
smGenerator systemcontext.SystemMessageGenerator
@@ -23,6 +24,7 @@ func NewNonInteractiveCmd(
2324
smGenerator systemcontext.SystemMessageGenerator,
2425
) *NonInteractiveCmd {
2526
return &NonInteractiveCmd{
27+
ui: ui.NewUI(),
2628
clientProvider: clientProvider,
2729
promptResolver: promptResolver,
2830
smGenerator: smGenerator,
@@ -55,5 +57,5 @@ func (c *NonInteractiveCmd) Run() error {
5557
}
5658

5759
func (c *NonInteractiveCmd) printChunk(chunk *chat.ConversationChunk) {
58-
ui.PrintMessage(chunk.Content, ui.MessageTypeInfo)
60+
c.ui.PrintMessage(chunk.Content, ui.MessageTypeInfo)
5961
}

0 commit comments

Comments
 (0)