mirror of
https://github.com/Pull-Pal/pull-pal.git
synced 2024-12-22 10:07:34 -05:00
wip start refactor
This commit is contained in:
parent
3a312b2b9b
commit
e4918fcb36
15
cmd/root.go
15
cmd/root.go
@ -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!")
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
84
vc/github.go
84
vc/github.go
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user