mirror of
https://github.com/Pull-Pal/pull-pal.git
synced 2026-06-17 00:39:54 -04:00
cleanup/refactor (#1)
focus on fully automated as basic/default functionality. remove unnecessary commands except for local git debug. remove unnecessary interfaces and code. remove local git functionality from github client. probably some other stuff too
This commit is contained in:
committed by
GitHub
parent
3a312b2b9b
commit
cbec4c1be9
@@ -4,14 +4,13 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mobyvb/pull-pal/llm"
|
||||
"github.com/mobyvb/pull-pal/vc"
|
||||
|
||||
"github.com/atotto/clipboard"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
@@ -19,16 +18,16 @@ import (
|
||||
var IssueNotFound = errors.New("no issue found")
|
||||
|
||||
// PullPal is the service responsible for:
|
||||
// * Interacting with git server (e.g. reading issues and making PRs on Github)
|
||||
// * Generating LLM prompts
|
||||
// * Parsing LLM responses
|
||||
// * Interacting with LLM (e.g. with GPT via OpenAI API)
|
||||
// - Interacting with git server (e.g. reading issues and making PRs on Github)
|
||||
// - Generating LLM prompts
|
||||
// - Parsing LLM responses
|
||||
// - Interacting with LLM (e.g. with GPT via OpenAI API)
|
||||
type PullPal struct {
|
||||
ctx context.Context
|
||||
log *zap.Logger
|
||||
listIssueOptions vc.ListIssueOptions
|
||||
|
||||
vcClient vc.VCClient
|
||||
ghClient *vc.GithubClient
|
||||
localGitClient *vc.LocalGitClient
|
||||
openAIClient *llm.OpenAIClient
|
||||
}
|
||||
@@ -39,7 +38,7 @@ func NewPullPal(ctx context.Context, log *zap.Logger, listIssueOptions vc.ListIs
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
localGitClient, err := vc.NewLocalGitClient(self, repo)
|
||||
localGitClient, err := vc.NewLocalGitClient(log, self, repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -49,7 +48,7 @@ func NewPullPal(ctx context.Context, log *zap.Logger, listIssueOptions vc.ListIs
|
||||
log: log,
|
||||
listIssueOptions: listIssueOptions,
|
||||
|
||||
vcClient: ghClient,
|
||||
ghClient: ghClient,
|
||||
localGitClient: localGitClient,
|
||||
openAIClient: llm.NewOpenAIClient(log.Named("openaiClient"), openAIToken),
|
||||
}, nil
|
||||
@@ -60,20 +59,38 @@ func (p *PullPal) Run() error {
|
||||
p.log.Info("Starting Pull Pal")
|
||||
// TODO gracefully handle context cancelation
|
||||
for {
|
||||
issues, err := p.vcClient.ListOpenIssues(p.listIssueOptions)
|
||||
issues, err := p.ghClient.ListOpenIssues(p.listIssueOptions)
|
||||
if err != nil {
|
||||
p.log.Error("error listing issues", zap.Error(err))
|
||||
continue
|
||||
return err
|
||||
}
|
||||
|
||||
if len(issues) == 0 {
|
||||
// todo don't sleep
|
||||
p.log.Info("no issues found. sleeping for 5 mins")
|
||||
time.Sleep(5 * time.Minute)
|
||||
p.log.Info("no issues found. sleeping for 30 seconds")
|
||||
time.Sleep(30 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
issue := issues[0]
|
||||
issueNumber, err := strconv.Atoi(issue.ID)
|
||||
if err != nil {
|
||||
p.log.Error("error converting issue ID to int", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
err = p.ghClient.CommentOnIssue(issueNumber, "on it")
|
||||
if err != nil {
|
||||
p.log.Error("error commenting on issue", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
for _, label := range p.listIssueOptions.Labels {
|
||||
err = p.ghClient.RemoveLabelFromIssue(issueNumber, label)
|
||||
if err != nil {
|
||||
p.log.Error("error removing labels from issue", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// remove file list from issue body
|
||||
// TODO do this better and probably somewhere else
|
||||
@@ -89,7 +106,7 @@ func (p *PullPal) Run() error {
|
||||
files := []llm.File{}
|
||||
for _, path := range fileList {
|
||||
path = strings.TrimSpace(path)
|
||||
nextFile, err := p.vcClient.GetLocalFile(path)
|
||||
nextFile, err := p.localGitClient.GetLocalFile(path)
|
||||
if err != nil {
|
||||
p.log.Error("error getting file from vcclient", zap.Error(err))
|
||||
continue
|
||||
@@ -115,40 +132,63 @@ func (p *PullPal) Run() error {
|
||||
//codeChangeResponse := llm.ParseCodeChangeResponse(llmResponse)
|
||||
|
||||
// create commit with file changes
|
||||
err = p.vcClient.StartCommit()
|
||||
err = p.localGitClient.StartCommit()
|
||||
//err = p.ghClient.StartCommit()
|
||||
if err != nil {
|
||||
p.log.Error("error starting commit", zap.Error(err))
|
||||
continue
|
||||
return err
|
||||
}
|
||||
newBranchName := fmt.Sprintf("fix-%s", changeRequest.IssueID)
|
||||
/*
|
||||
err = p.localGitClient.SwitchBranch(newBranchName)
|
||||
if err != nil {
|
||||
p.log.Error("error switching branch", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
*/
|
||||
for _, f := range changeResponse.Files {
|
||||
err = p.vcClient.ReplaceOrAddLocalFile(f)
|
||||
p.log.Info("replacing or adding file", zap.String("path", f.Path), zap.String("contents", f.Contents))
|
||||
err = p.localGitClient.ReplaceOrAddLocalFile(f)
|
||||
// err = p.ghClient.ReplaceOrAddLocalFile(f)
|
||||
if err != nil {
|
||||
p.log.Error("error replacing or adding file", zap.Error(err))
|
||||
continue
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
commitMessage := changeRequest.Subject + "\n\n" + changeResponse.Notes + "\n\nResolves: #" + changeRequest.IssueID
|
||||
err = p.vcClient.FinishCommit(commitMessage)
|
||||
p.log.Info("about to create commit", zap.String("message", commitMessage))
|
||||
err = p.localGitClient.FinishCommit(commitMessage)
|
||||
if err != nil {
|
||||
p.log.Error("error finshing commit", zap.Error(err))
|
||||
continue
|
||||
p.log.Error("error finishing commit", zap.Error(err))
|
||||
// TODO figure out why sometimes finish commit returns "already up-to-date error"
|
||||
// return err
|
||||
}
|
||||
|
||||
err = p.localGitClient.PushBranch(newBranchName)
|
||||
if err != nil {
|
||||
p.log.Error("error pushing branch", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// open code change request
|
||||
_, url, err := p.vcClient.OpenCodeChangeRequest(changeRequest, changeResponse)
|
||||
// TODO don't hardcode main branch, make configurable
|
||||
_, url, err := p.ghClient.OpenCodeChangeRequest(changeRequest, changeResponse, newBranchName, "main")
|
||||
if err != nil {
|
||||
p.log.Error("error opening PR", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
p.log.Info("successfully created PR", zap.String("URL", url))
|
||||
|
||||
p.log.Info("going to sleep for five mins")
|
||||
time.Sleep(5 * time.Minute)
|
||||
p.log.Info("going to sleep for thirty seconds")
|
||||
time.Sleep(30 * time.Second)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// PickIssueToFile is the same as PickIssue, but the changeRequest is converted to a string and written to a file.
|
||||
func (p *PullPal) PickIssueToFile(promptPath string) (issue vc.Issue, changeRequest llm.CodeChangeRequest, err error) {
|
||||
issue, changeRequest, err = p.PickIssue()
|
||||
@@ -180,11 +220,12 @@ func (p *PullPal) PickIssueToClipboard() (issue vc.Issue, changeRequest llm.Code
|
||||
err = clipboard.WriteAll(prompt)
|
||||
return issue, changeRequest, err
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
// PickIssue selects an issue from the version control server and returns the selected issue, as well as the LLM prompt needed to fulfill the request.
|
||||
func (p *PullPal) PickIssue() (issue vc.Issue, changeRequest llm.CodeChangeRequest, err error) {
|
||||
// TODO I should be able to pass in settings for listing issues from here
|
||||
issues, err := p.vcClient.ListOpenIssues(p.listIssueOptions)
|
||||
issues, err := p.ghClient.ListOpenIssues(p.listIssueOptions)
|
||||
if err != nil {
|
||||
return issue, changeRequest, err
|
||||
}
|
||||
@@ -209,7 +250,7 @@ func (p *PullPal) PickIssue() (issue vc.Issue, changeRequest llm.CodeChangeReque
|
||||
files := []llm.File{}
|
||||
for _, path := range fileList {
|
||||
path = strings.TrimSpace(path)
|
||||
nextFile, err := p.vcClient.GetLocalFile(path)
|
||||
nextFile, err := p.ghClient.GetLocalFile(path)
|
||||
if err != nil {
|
||||
return issue, changeRequest, err
|
||||
}
|
||||
@@ -223,7 +264,8 @@ func (p *PullPal) PickIssue() (issue vc.Issue, changeRequest llm.CodeChangeReque
|
||||
|
||||
return issue, changeRequest, nil
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
// ProcessResponseFromFile is the same as ProcessResponse, but the response is inputted into a file rather than passed directly as an argument.
|
||||
func (p *PullPal) ProcessResponseFromFile(codeChangeRequest llm.CodeChangeRequest, llmResponsePath string) (url string, err error) {
|
||||
data, err := ioutil.ReadFile(llmResponsePath)
|
||||
@@ -239,31 +281,33 @@ func (p *PullPal) ProcessResponse(codeChangeRequest llm.CodeChangeRequest, llmRe
|
||||
codeChangeResponse := llm.ParseCodeChangeResponse(llmResponse)
|
||||
|
||||
// 2. create commit with file changes
|
||||
err = p.vcClient.StartCommit()
|
||||
err = p.ghClient.StartCommit()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, f := range codeChangeResponse.Files {
|
||||
err = p.vcClient.ReplaceOrAddLocalFile(f)
|
||||
err = p.ghClient.ReplaceOrAddLocalFile(f)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
commitMessage := codeChangeRequest.Subject + "\n\n" + codeChangeResponse.Notes + "\n\nResolves: #" + codeChangeRequest.IssueID
|
||||
err = p.vcClient.FinishCommit(commitMessage)
|
||||
err = p.ghClient.FinishCommit(commitMessage)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 3. open code change request
|
||||
_, url, err = p.vcClient.OpenCodeChangeRequest(codeChangeRequest, codeChangeResponse)
|
||||
_, url, err = p.ghClient.OpenCodeChangeRequest(codeChangeRequest, codeChangeResponse)
|
||||
return url, err
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// ListIssues gets a list of all issues meeting the provided criteria.
|
||||
func (p *PullPal) ListIssues(handles, labels []string) ([]vc.Issue, error) {
|
||||
issues, err := p.vcClient.ListOpenIssues(vc.ListIssueOptions{
|
||||
issues, err := p.ghClient.ListOpenIssues(vc.ListIssueOptions{
|
||||
Handles: handles,
|
||||
Labels: labels,
|
||||
})
|
||||
@@ -276,7 +320,7 @@ func (p *PullPal) ListIssues(handles, labels []string) ([]vc.Issue, error) {
|
||||
|
||||
// ListComments gets a list of all comments meeting the provided criteria on a PR.
|
||||
func (p *PullPal) ListComments(changeID string, handles []string) ([]vc.Comment, error) {
|
||||
comments, err := p.vcClient.ListOpenComments(vc.ListCommentOptions{
|
||||
comments, err := p.ghClient.ListOpenComments(vc.ListCommentOptions{
|
||||
ChangeID: changeID,
|
||||
Handles: handles,
|
||||
})
|
||||
@@ -302,7 +346,7 @@ func (p *PullPal) MakeLocalChange(issue vc.Issue) error {
|
||||
files := []llm.File{}
|
||||
for _, path := range fileList {
|
||||
path = strings.TrimSpace(path)
|
||||
nextFile, err := p.vcClient.GetLocalFile(path)
|
||||
nextFile, err := p.ghClient.GetLocalFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -326,3 +370,4 @@ func (p *PullPal) MakeLocalChange(issue vc.Issue) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
47
pullpal/debug.go
Normal file
47
pullpal/debug.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package pullpal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mobyvb/pull-pal/llm"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func (p *PullPal) DebugGit() error {
|
||||
p.log.Info("Starting Pull Pal git debug")
|
||||
|
||||
// create commit with file changes
|
||||
err := p.localGitClient.StartCommit()
|
||||
//err = p.ghClient.StartCommit()
|
||||
if err != nil {
|
||||
p.log.Error("error starting commit", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
newBranchName := fmt.Sprintf("debug-branch")
|
||||
|
||||
for _, f := range []string{"a", "b"} {
|
||||
err = p.localGitClient.ReplaceOrAddLocalFile(llm.File{
|
||||
Path: f,
|
||||
Contents: "hello",
|
||||
})
|
||||
if err != nil {
|
||||
p.log.Error("error replacing or adding file", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
commitMessage := "debug commit message"
|
||||
err = p.localGitClient.FinishCommit(commitMessage)
|
||||
if err != nil {
|
||||
p.log.Error("error finishing commit", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
err = p.localGitClient.PushBranch(newBranchName)
|
||||
if err != nil {
|
||||
p.log.Error("error pushing branch", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user