Skip to content

Commit 12e2934

Browse files
committed
Remove repeated code, make API consistent across functions
1 parent fbd3d1a commit 12e2934

File tree

10 files changed

+133
-63
lines changed

10 files changed

+133
-63
lines changed

ai/calc_tokens.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package ai
2+
3+
import "github.com/pandodao/tokenizer-go"
4+
5+
func CalcTokens(inputs ...string) (int, error) {
6+
total := int(0)
7+
for _, input := range inputs {
8+
tokens, err := tokenizer.CalToken(input)
9+
if err != nil {
10+
return -1, err
11+
}
12+
total += tokens
13+
}
14+
15+
return total, nil
16+
}

ai/markdown.go

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
11
package ai
22

33
import (
4-
"errors"
54
"fmt"
6-
"os"
75
"strings"
8-
"unicode/utf8"
96

107
gopenai "github.com/CasualCodersProjects/gopenai"
118
ai_types "github.com/CasualCodersProjects/gopenai/types"
129
"github.com/chand1012/ottodocs/constants"
13-
"github.com/pandodao/tokenizer-go"
1410
)
1511

16-
func Markdown(filePath, chatPrompt, APIKey string) (string, error) {
12+
func Markdown(filePath, contents, chatPrompt, APIKey string) (string, error) {
1713
openai := gopenai.NewOpenAI(&gopenai.OpenAIOpts{
1814
APIKey: APIKey,
1915
})
2016

21-
// load the file
22-
contents, err := os.ReadFile(filePath)
23-
if err != nil {
24-
return "", err
25-
}
26-
27-
if !utf8.Valid(contents) {
28-
return "", errors.New("the file is not valid UTF-8")
29-
}
30-
31-
question := chatPrompt + "\n\n" + strings.TrimRight(string(contents), " \n")
17+
question := chatPrompt + "\n\n" + strings.TrimRight(contents, " \n")
3218

3319
messages := []ai_types.ChatMessage{
3420
{
@@ -41,7 +27,10 @@ func Markdown(filePath, chatPrompt, APIKey string) (string, error) {
4127
},
4228
}
4329

44-
tokens := tokenizer.MustCalToken(messages[0].Content) + tokenizer.MustCalToken(messages[1].Content)
30+
tokens, err := CalcTokens(messages[0].Content, messages[1].Content)
31+
if err != nil {
32+
return "", fmt.Errorf("could not calculate tokens: %s", err)
33+
}
4534

4635
maxTokens := constants.OPENAI_MAX_TOKENS - tokens
4736

ai/question.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
gopenai "github.com/CasualCodersProjects/gopenai"
88
ai_types "github.com/CasualCodersProjects/gopenai/types"
99
"github.com/chand1012/ottodocs/constants"
10-
"github.com/pandodao/tokenizer-go"
1110
)
1211

1312
func Question(filePath, fileContent, chatPrompt, APIKey string) (string, error) {
@@ -28,7 +27,10 @@ func Question(filePath, fileContent, chatPrompt, APIKey string) (string, error)
2827
},
2928
}
3029

31-
tokens := tokenizer.MustCalToken(messages[0].Content) + tokenizer.MustCalToken(messages[1].Content)
30+
tokens, err := CalcTokens(messages[0].Content, messages[1].Content)
31+
if err != nil {
32+
return "", fmt.Errorf("could not calculate tokens: %s", err)
33+
}
3234

3335
maxTokens := constants.OPENAI_MAX_TOKENS - tokens
3436

ai/single_file.go

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
package ai
22

33
import (
4-
"errors"
54
"fmt"
6-
"os"
75
"path/filepath"
86
"strconv"
97
"strings"
10-
"unicode/utf8"
118

129
gopenai "github.com/CasualCodersProjects/gopenai"
1310
ai_types "github.com/CasualCodersProjects/gopenai/types"
14-
"github.com/pandodao/tokenizer-go"
1511

1612
"github.com/chand1012/ottodocs/constants"
1713
"github.com/chand1012/ottodocs/utils/textfile"
@@ -38,30 +34,20 @@ func extractLineNumber(line string) (int, error) {
3834
}
3935

4036
// Document a file using the OpenAI ChatGPT API. Takes a file path, a prompt, and an API key as arguments.
41-
func SingleFile(filePath, chatPrompt, APIKey string) (string, error) {
37+
func SingleFile(filePath, contents, chatPrompt, APIKey string) (string, error) {
4238

4339
openai := gopenai.NewOpenAI(&gopenai.OpenAIOpts{
4440
APIKey: APIKey,
4541
})
4642

47-
// load the file
48-
contents, err := os.ReadFile(filePath)
49-
if err != nil {
50-
return "", err
51-
}
52-
53-
if !utf8.Valid(contents) {
54-
return "", errors.New("the file is not valid UTF-8")
55-
}
56-
5743
fileEnding := filepath.Ext(filePath)
5844

5945
commentOperator, ok := constants.CommentOperators[fileEnding]
6046
if !ok {
6147
return "", fmt.Errorf("the file type %s is not supported", fileEnding)
6248
}
6349

64-
question := chatPrompt + "\n\n" + strings.TrimRight(string(contents), " \n")
50+
question := chatPrompt + "\n\n" + strings.TrimRight(contents, " \n")
6551

6652
messages := []ai_types.ChatMessage{
6753
{
@@ -74,7 +60,10 @@ func SingleFile(filePath, chatPrompt, APIKey string) (string, error) {
7460
},
7561
}
7662

77-
tokens := tokenizer.MustCalToken(messages[0].Content) + tokenizer.MustCalToken(messages[1].Content)
63+
tokens, err := CalcTokens(messages[0].Content, messages[1].Content)
64+
if err != nil {
65+
return "", fmt.Errorf("could not calculate tokens: %s", err)
66+
}
7867

7968
maxTokens := constants.OPENAI_MAX_TOKENS - tokens
8069

cmd/ask.go

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
2+
Copyright © 2023 Chandler <chandler@chand1012.dev>
33
*/
44
package cmd
55

@@ -10,7 +10,6 @@ import (
1010
"strings"
1111

1212
"github.com/blevesearch/bleve/v2"
13-
"github.com/chand1012/git2gpt/prompt"
1413
"github.com/spf13/cobra"
1514

1615
"github.com/chand1012/ottodocs/ai"
@@ -22,7 +21,8 @@ import (
2221
var askCmd = &cobra.Command{
2322
Use: "ask",
2423
Short: "Ask a question about a file or repo",
25-
Long: `Uses a vector search to find the most similar questions and answers`,
24+
Long: `Uses full text search to find relevant code and ask questions about said code.
25+
Requires a path to a repository or file as a positional argument.`,
2626
Args: cobra.PositionalArgs(func(cmd *cobra.Command, args []string) error {
2727
if len(args) < 1 {
2828
return fmt.Errorf("requires a path to a repository or file")
@@ -47,15 +47,6 @@ var askCmd = &cobra.Command{
4747
chatPrompt = strings.TrimRight(chatPrompt, " \n")
4848
}
4949

50-
// if .index.bleve exists, delete it
51-
if _, err := os.Stat(filepath.Join(args[0], ".index.bleve")); err == nil {
52-
err = os.RemoveAll(filepath.Join(args[0], ".index.bleve"))
53-
if err != nil {
54-
log.Errorf("Error deleting index: %s", err)
55-
os.Exit(1)
56-
}
57-
}
58-
5950
info, err := os.Stat(repoPath)
6051
if err != nil {
6152
log.Errorf("Error getting file info: %s", err)
@@ -78,13 +69,12 @@ var askCmd = &cobra.Command{
7869
os.Exit(1)
7970
}
8071
// index the repo
81-
ignoreList := prompt.GenerateIgnoreList(repoPath, ignoreFilePath, !ignoreGitignore)
82-
ignoreList = append(ignoreList, filepath.Join(repoPath, ".gptignore"))
83-
repo, err := prompt.ProcessGitRepo(repoPath, ignoreList)
72+
repo, err := utils.GetRepo(repoPath, ignoreFilePath, ignoreGitignore)
8473
if err != nil {
8574
log.Errorf("Error processing repo: %s", err)
8675
os.Exit(1)
8776
}
77+
8878
// index the files
8979
for _, file := range repo.Files {
9080
err = index.Index(file.Path, file)
@@ -139,21 +129,29 @@ var askCmd = &cobra.Command{
139129

140130
fmt.Println("Asking question about " + fileName + "...")
141131

142-
// load the file
143-
content, err := os.ReadFile(fileName)
132+
content, err := utils.LoadFile(fileName)
144133
if err != nil {
145-
log.Errorf("Error reading file: %s", err)
134+
log.Errorf("Error loading file: %s", err)
146135
os.Exit(1)
147136
}
148137

149-
resp, err := ai.Question(fileName, string(content), chatPrompt, conf.APIKey)
138+
resp, err := ai.Question(fileName, content, chatPrompt, conf.APIKey)
150139

151140
if err != nil {
152141
log.Errorf("Error asking question: %s", err)
153142
os.Exit(1)
154143
}
155144

156145
fmt.Println(resp)
146+
147+
// if .index.bleve exists, delete it
148+
if _, err := os.Stat(filepath.Join(args[0], ".index.bleve")); err == nil {
149+
err = os.RemoveAll(filepath.Join(args[0], ".index.bleve"))
150+
if err != nil {
151+
log.Errorf("Error deleting index: %s", err)
152+
os.Exit(1)
153+
}
154+
}
157155
},
158156
}
159157

cmd/doc.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/chand1012/ottodocs/ai"
1313
"github.com/chand1012/ottodocs/config"
14+
"github.com/chand1012/ottodocs/utils"
1415
)
1516

1617
// docCmd represents the doc command
@@ -39,10 +40,16 @@ var docCmd = &cobra.Command{
3940

4041
var contents string
4142

43+
fileContents, err := utils.LoadFile(filePath)
44+
if err != nil {
45+
log.Errorf("Error: %s", err)
46+
os.Exit(1)
47+
}
48+
4249
if inlineMode || !markdownMode {
43-
contents, err = ai.SingleFile(filePath, chatPrompt, conf.APIKey)
50+
contents, err = ai.SingleFile(filePath, fileContents, chatPrompt, conf.APIKey)
4451
} else {
45-
contents, err = ai.Markdown(filePath, chatPrompt, conf.APIKey)
52+
contents, err = ai.Markdown(filePath, fileContents, chatPrompt, conf.APIKey)
4653
}
4754

4855
if err != nil {

cmd/docs.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import (
88
"os"
99
"path/filepath"
1010

11-
"github.com/chand1012/git2gpt/prompt"
1211
"github.com/chand1012/ottodocs/ai"
1312
"github.com/chand1012/ottodocs/config"
13+
"github.com/chand1012/ottodocs/utils"
1414
"github.com/spf13/cobra"
1515
)
1616

@@ -61,9 +61,7 @@ search for files in the directory and document them.
6161
os.Exit(1)
6262
}
6363

64-
ignoreList := prompt.GenerateIgnoreList(repoPath, ignoreFilePath, !ignoreGitignore)
65-
ignoreList = append(ignoreList, filepath.Join(repoPath, ".gptignore"))
66-
repo, err := prompt.ProcessGitRepo(repoPath, ignoreList)
64+
repo, err := utils.GetRepo(repoPath, ignoreFilePath, ignoreGitignore)
6765
if err != nil {
6866
log.Errorf("Error: %s", err)
6967
os.Exit(1)
@@ -82,10 +80,16 @@ search for files in the directory and document them.
8280
chatPrompt = "Write documentation for the following code snippet. The file name is" + file.Path + ":"
8381
}
8482

83+
fileContents, err := utils.LoadFile(path)
84+
if err != nil {
85+
log.Warnf("Error loading file %s: %s", path, err)
86+
continue
87+
}
88+
8589
if inlineMode || !markdownMode {
86-
contents, err = ai.SingleFile(path, chatPrompt, conf.APIKey)
90+
contents, err = ai.SingleFile(path, fileContents, chatPrompt, conf.APIKey)
8791
} else {
88-
contents, err = ai.Markdown(path, chatPrompt, conf.APIKey)
92+
contents, err = ai.Markdown(path, fileContents, chatPrompt, conf.APIKey)
8993
}
9094

9195
if err != nil {

docs/otto_ask.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## otto ask
2+
3+
Ask a question about a file or repo
4+
5+
### Synopsis
6+
7+
Uses full text search to find relevant code and ask questions about said code.
8+
Requires a path to a repository or file as a positional argument.
9+
10+
```
11+
otto ask [flags]
12+
```
13+
14+
### Options
15+
16+
```
17+
-h, --help help for ask
18+
-n, --ignore string path to .gptignore file
19+
-g, --ignore-gitignore ignore .gitignore file
20+
-q, --question string The question to ask
21+
```
22+
23+
### SEE ALSO
24+
25+
* [otto](otto.md) - Document your code with ease

utils/get_repo.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package utils
2+
3+
import (
4+
"path/filepath"
5+
6+
"github.com/chand1012/git2gpt/prompt"
7+
)
8+
9+
// GetRepo returns a GitRepo object for the given repoPath
10+
func GetRepo(repoPath, ignoreFilePath string, ignoreGitIgnore bool) (*prompt.GitRepo, error) {
11+
ignoreList := prompt.GenerateIgnoreList(repoPath, ignoreFilePath, !ignoreGitIgnore)
12+
ignoreList = append(ignoreList, filepath.Join(repoPath, ".gptignore"))
13+
repo, err := prompt.ProcessGitRepo(repoPath, ignoreList)
14+
if err != nil {
15+
return nil, err
16+
}
17+
return repo, nil
18+
}

utils/load_file.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package utils
2+
3+
import (
4+
"errors"
5+
"os"
6+
"unicode/utf8"
7+
)
8+
9+
// Loads a file and return an error if its not valid UTF-8
10+
func LoadFile(filePath string) (string, error) {
11+
// load the file
12+
contents, err := os.ReadFile(filePath)
13+
if err != nil {
14+
return "", err
15+
}
16+
17+
if !utf8.Valid(contents) {
18+
return "", errors.New("the file is not valid UTF-8")
19+
}
20+
21+
return string(contents), nil
22+
}

0 commit comments

Comments
 (0)