wip start refactor

This commit is contained in:
Moby von Briesen 2023-05-02 22:46:47 -04:00
parent 3a312b2b9b
commit e4918fcb36
4 changed files with 88 additions and 66 deletions

View File

@ -159,13 +159,16 @@ It can be used to:
continue continue
} }
prURL, err := p.ProcessResponseFromFile(changeRequest, cfg.responsePath) /*
if err != nil { prURL, err := p.ProcessResponseFromFile(changeRequest, cfg.responsePath)
fmt.Println("error parsing LLM response and/or making version control changes", err) if err != nil {
return fmt.Println("error parsing LLM response and/or making version control changes", err)
} return
}
fmt.Printf("Successfully opened a code change request. Link: %s\n", prURL) fmt.Printf("Successfully opened a code change request. Link: %s\n", prURL)
*/
_ = changeRequest
} }
fmt.Println("Done. Thank you!") fmt.Println("Done. Thank you!")

View File

@ -28,7 +28,7 @@ type PullPal struct {
log *zap.Logger log *zap.Logger
listIssueOptions vc.ListIssueOptions listIssueOptions vc.ListIssueOptions
vcClient vc.VCClient ghClient *vc.GithubClient
localGitClient *vc.LocalGitClient localGitClient *vc.LocalGitClient
openAIClient *llm.OpenAIClient openAIClient *llm.OpenAIClient
} }
@ -49,7 +49,7 @@ func NewPullPal(ctx context.Context, log *zap.Logger, listIssueOptions vc.ListIs
log: log, log: log,
listIssueOptions: listIssueOptions, listIssueOptions: listIssueOptions,
vcClient: ghClient, ghClient: ghClient,
localGitClient: localGitClient, localGitClient: localGitClient,
openAIClient: llm.NewOpenAIClient(log.Named("openaiClient"), openAIToken), openAIClient: llm.NewOpenAIClient(log.Named("openaiClient"), openAIToken),
}, nil }, nil
@ -60,7 +60,7 @@ func (p *PullPal) Run() error {
p.log.Info("Starting Pull Pal") p.log.Info("Starting Pull Pal")
// TODO gracefully handle context cancelation // TODO gracefully handle context cancelation
for { for {
issues, err := p.vcClient.ListOpenIssues(p.listIssueOptions) issues, err := p.ghClient.ListOpenIssues(p.listIssueOptions)
if err != nil { if err != nil {
p.log.Error("error listing issues", zap.Error(err)) p.log.Error("error listing issues", zap.Error(err))
continue continue
@ -89,7 +89,7 @@ func (p *PullPal) Run() error {
files := []llm.File{} files := []llm.File{}
for _, path := range fileList { for _, path := range fileList {
path = strings.TrimSpace(path) path = strings.TrimSpace(path)
nextFile, err := p.vcClient.GetLocalFile(path) nextFile, err := p.ghClient.GetLocalFile(path)
if err != nil { if err != nil {
p.log.Error("error getting file from vcclient", zap.Error(err)) p.log.Error("error getting file from vcclient", zap.Error(err))
continue continue
@ -115,13 +115,21 @@ func (p *PullPal) Run() error {
//codeChangeResponse := llm.ParseCodeChangeResponse(llmResponse) //codeChangeResponse := llm.ParseCodeChangeResponse(llmResponse)
// create commit with file changes // create commit with file changes
err = p.vcClient.StartCommit() newBranchName := fmt.Sprintf("fix-%s", changeRequest.IssueID)
err = p.localGitClient.SwitchBranch(newBranchName)
if err != nil {
p.log.Error("error switching branch", zap.Error(err))
continue
}
err = p.localGitClient.StartCommit()
//err = p.ghClient.StartCommit()
if err != nil { if err != nil {
p.log.Error("error starting commit", zap.Error(err)) p.log.Error("error starting commit", zap.Error(err))
continue continue
} }
for _, f := range changeResponse.Files { for _, f := range changeResponse.Files {
err = p.vcClient.ReplaceOrAddLocalFile(f) err = p.localGitClient.ReplaceOrAddLocalFile(f)
// err = p.ghClient.ReplaceOrAddLocalFile(f)
if err != nil { if err != nil {
p.log.Error("error replacing or adding file", zap.Error(err)) p.log.Error("error replacing or adding file", zap.Error(err))
continue continue
@ -129,14 +137,21 @@ func (p *PullPal) Run() error {
} }
commitMessage := changeRequest.Subject + "\n\n" + changeResponse.Notes + "\n\nResolves: #" + changeRequest.IssueID commitMessage := changeRequest.Subject + "\n\n" + changeResponse.Notes + "\n\nResolves: #" + changeRequest.IssueID
err = p.vcClient.FinishCommit(commitMessage) err = p.localGitClient.FinishCommit(commitMessage)
if err != nil {
p.log.Error("error finshing commit", zap.Error(err))
continue
}
err = p.localGitClient.PushBranch(newBranchName)
if err != nil { if err != nil {
p.log.Error("error finshing commit", zap.Error(err)) p.log.Error("error finshing commit", zap.Error(err))
continue continue
} }
// open code change request // 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 { if err != nil {
p.log.Error("error opening PR", zap.Error(err)) p.log.Error("error opening PR", zap.Error(err))
} }
@ -184,7 +199,7 @@ func (p *PullPal) PickIssueToClipboard() (issue vc.Issue, changeRequest llm.Code
// 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. // 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) { 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 // 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 { if err != nil {
return issue, changeRequest, err return issue, changeRequest, err
} }
@ -209,7 +224,7 @@ func (p *PullPal) PickIssue() (issue vc.Issue, changeRequest llm.CodeChangeReque
files := []llm.File{} files := []llm.File{}
for _, path := range fileList { for _, path := range fileList {
path = strings.TrimSpace(path) path = strings.TrimSpace(path)
nextFile, err := p.vcClient.GetLocalFile(path) nextFile, err := p.ghClient.GetLocalFile(path)
if err != nil { if err != nil {
return issue, changeRequest, err return issue, changeRequest, err
} }
@ -224,6 +239,7 @@ func (p *PullPal) PickIssue() (issue vc.Issue, changeRequest llm.CodeChangeReque
return issue, changeRequest, nil 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. // 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) { func (p *PullPal) ProcessResponseFromFile(codeChangeRequest llm.CodeChangeRequest, llmResponsePath string) (url string, err error) {
data, err := ioutil.ReadFile(llmResponsePath) data, err := ioutil.ReadFile(llmResponsePath)
@ -239,31 +255,32 @@ func (p *PullPal) ProcessResponse(codeChangeRequest llm.CodeChangeRequest, llmRe
codeChangeResponse := llm.ParseCodeChangeResponse(llmResponse) codeChangeResponse := llm.ParseCodeChangeResponse(llmResponse)
// 2. create commit with file changes // 2. create commit with file changes
err = p.vcClient.StartCommit() err = p.ghClient.StartCommit()
if err != nil { if err != nil {
return "", err return "", err
} }
for _, f := range codeChangeResponse.Files { for _, f := range codeChangeResponse.Files {
err = p.vcClient.ReplaceOrAddLocalFile(f) err = p.ghClient.ReplaceOrAddLocalFile(f)
if err != nil { if err != nil {
return "", err return "", err
} }
} }
commitMessage := codeChangeRequest.Subject + "\n\n" + codeChangeResponse.Notes + "\n\nResolves: #" + codeChangeRequest.IssueID commitMessage := codeChangeRequest.Subject + "\n\n" + codeChangeResponse.Notes + "\n\nResolves: #" + codeChangeRequest.IssueID
err = p.vcClient.FinishCommit(commitMessage) err = p.ghClient.FinishCommit(commitMessage)
if err != nil { if err != nil {
return "", err return "", err
} }
// 3. open code change request // 3. open code change request
_, url, err = p.vcClient.OpenCodeChangeRequest(codeChangeRequest, codeChangeResponse) _, url, err = p.ghClient.OpenCodeChangeRequest(codeChangeRequest, codeChangeResponse)
return url, err return url, err
} }
*/
// ListIssues gets a list of all issues meeting the provided criteria. // ListIssues gets a list of all issues meeting the provided criteria.
func (p *PullPal) ListIssues(handles, labels []string) ([]vc.Issue, error) { 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, Handles: handles,
Labels: labels, Labels: labels,
}) })
@ -276,7 +293,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. // 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) { 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, ChangeID: changeID,
Handles: handles, Handles: handles,
}) })
@ -302,7 +319,7 @@ func (p *PullPal) MakeLocalChange(issue vc.Issue) error {
files := []llm.File{} files := []llm.File{}
for _, path := range fileList { for _, path := range fileList {
path = strings.TrimSpace(path) path = strings.TrimSpace(path)
nextFile, err := p.vcClient.GetLocalFile(path) nextFile, err := p.ghClient.GetLocalFile(path)
if err != nil { if err != nil {
return err return err
} }

View File

@ -3,8 +3,6 @@ package vc
import ( import (
"fmt" "fmt"
"github.com/mobyvb/pull-pal/llm"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
) )
@ -84,6 +82,7 @@ func (repo Repository) HTTPS() string {
} }
// VCClient is an interface for version control server's client, e.g. a Github or Gerrit client. // VCClient is an interface for version control server's client, e.g. a Github or Gerrit client.
/*
type VCClient interface { type VCClient interface {
// ListOpenIssues lists unresolved issues meeting the provided criteria on the version control server. // ListOpenIssues lists unresolved issues meeting the provided criteria on the version control server.
ListOpenIssues(opts ListIssueOptions) ([]Issue, error) ListOpenIssues(opts ListIssueOptions) ([]Issue, error)
@ -103,3 +102,4 @@ type VCClient interface {
// FinishCommit completes a commit, after which a code change request can be opened or updated. // FinishCommit completes a commit, after which a code change request can be opened or updated.
FinishCommit(message string) error FinishCommit(message string) error
} }
*/

View File

@ -17,8 +17,6 @@ import (
"github.com/mobyvb/pull-pal/llm" "github.com/mobyvb/pull-pal/llm"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/plumbing/transport/http"
"github.com/google/go-github/github" "github.com/google/go-github/github"
@ -91,62 +89,66 @@ func NewGithubClient(ctx context.Context, log *zap.Logger, self Author, repo Rep
} }
// OpenCodeChangeRequest pushes to a new remote branch and opens a PR on Github. // OpenCodeChangeRequest pushes to a new remote branch and opens a PR on Github.
func (gc *GithubClient) OpenCodeChangeRequest(req llm.CodeChangeRequest, res llm.CodeChangeResponse) (id, url string, err error) { func (gc *GithubClient) OpenCodeChangeRequest(req llm.CodeChangeRequest, res llm.CodeChangeResponse, fromBranch, toBranch string) (id, url string, err error) {
// TODO handle gc.ctx canceled // TODO handle gc.ctx canceled
title := req.Subject title := req.Subject
if title == "" { if title == "" {
title = "update files" title = "update files"
} }
branchName := randomBranchName() /*
branchRefName := plumbing.NewBranchReferenceName(branchName) branchName := randomBranchName()
baseBranch := "main" branchRefName := plumbing.NewBranchReferenceName(branchName)
remoteName := "origin" baseBranch := "main"
remoteName := "origin"
*/
body := res.Notes body := res.Notes
body += fmt.Sprintf("\n\nResolves #%s", req.IssueID) body += fmt.Sprintf("\n\nResolves #%s", req.IssueID)
// Create new local branch // Create new local branch
headRef, err := gc.repo.localRepo.Head() /*
if err != nil { headRef, err := gc.repo.localRepo.Head()
return "", "", err if err != nil {
} return "", "", err
err = gc.repo.localRepo.CreateBranch(&config.Branch{ }
Name: branchName, err = gc.repo.localRepo.CreateBranch(&config.Branch{
Remote: remoteName, Name: branchName,
Merge: branchRefName, Remote: remoteName,
}) Merge: branchRefName,
if err != nil { })
return "", "", err if err != nil {
} return "", "", err
}
// Update the branch to point to the new commit // Update the branch to point to the new commit
err = gc.repo.localRepo.Storer.SetReference(plumbing.NewHashReference(branchRefName, headRef.Hash())) err = gc.repo.localRepo.Storer.SetReference(plumbing.NewHashReference(branchRefName, headRef.Hash()))
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
// Push the new branch to the remote repository // Push the new branch to the remote repository
remote, err := gc.repo.localRepo.Remote(remoteName) remote, err := gc.repo.localRepo.Remote(remoteName)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
err = remote.Push(&git.PushOptions{ err = remote.Push(&git.PushOptions{
RefSpecs: []config.RefSpec{config.RefSpec(fmt.Sprintf("%s:refs/heads/%s", branchRefName, branchName))}, RefSpecs: []config.RefSpec{config.RefSpec(fmt.Sprintf("%s:refs/heads/%s", branchRefName, branchName))},
Auth: &http.BasicAuth{ Auth: &http.BasicAuth{
Username: gc.self.Handle, Username: gc.self.Handle,
Password: gc.self.Token, Password: gc.self.Token,
}, },
}) })
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
*/
// Finally, open a pull request from the new branch. // Finally, open a pull request from the new branch.
pr, _, err := gc.client.PullRequests.Create(gc.ctx, gc.repo.Owner.Handle, gc.repo.Name, &github.NewPullRequest{ pr, _, err := gc.client.PullRequests.Create(gc.ctx, gc.repo.Owner.Handle, gc.repo.Name, &github.NewPullRequest{
Title: &title, Title: &title,
Head: &branchName, Head: &fromBranch,
Base: &baseBranch, Base: &toBranch,
Body: &body, Body: &body,
}) })
if err != nil { if err != nil {