mirror of
https://github.com/Pull-Pal/pull-pal.git
synced 2025-01-02 15:36:51 -05:00
Add plain "list issues" command and reorganize
* Add configurable users to list issues from * Add configurable labels to require on issues * Add a CLI subcommand that lists issues according to the criteria and does nothing else * Update existing CLI REPL to list issues according to the new criteria * Clean up and reorganize config code a little * Add some basic types and function signature for listing comments on code change requests
This commit is contained in:
parent
b29f544c23
commit
9cc0f4a1b8
53
cmd/list-issues.go
Normal file
53
cmd/list-issues.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/mobyvb/pull-pal/pullpal"
|
||||||
|
"github.com/mobyvb/pull-pal/vc"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var listIssuesCmd = &cobra.Command{
|
||||||
|
Use: "list-issues",
|
||||||
|
Short: "Lists github issues meeting the configured criteria",
|
||||||
|
Long: "Lists github issues meeting the configured criteria",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cfg := getConfig()
|
||||||
|
fmt.Println("list issues called")
|
||||||
|
|
||||||
|
log := zap.L()
|
||||||
|
|
||||||
|
author := vc.Author{
|
||||||
|
Email: cfg.selfEmail,
|
||||||
|
Handle: cfg.selfHandle,
|
||||||
|
Token: cfg.githubToken,
|
||||||
|
}
|
||||||
|
repo := vc.Repository{
|
||||||
|
LocalPath: cfg.localRepoPath,
|
||||||
|
HostDomain: cfg.repoDomain,
|
||||||
|
Name: cfg.repoName,
|
||||||
|
Owner: vc.Author{
|
||||||
|
Handle: cfg.repoHandle,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p, err := pullpal.NewPullPal(cmd.Context(), log.Named("pullpal"), author, repo)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error creating new pull pal", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Successfully initialized pull pal")
|
||||||
|
|
||||||
|
issueList, err := p.ListIssues(cfg.usersToListenTo, cfg.requiredIssueLabels)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error listing issues", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(issueList)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(listIssuesCmd)
|
||||||
|
}
|
105
cmd/root.go
105
cmd/root.go
@ -8,11 +8,55 @@ import (
|
|||||||
"github.com/mobyvb/pull-pal/llm"
|
"github.com/mobyvb/pull-pal/llm"
|
||||||
"github.com/mobyvb/pull-pal/pullpal"
|
"github.com/mobyvb/pull-pal/pullpal"
|
||||||
"github.com/mobyvb/pull-pal/vc"
|
"github.com/mobyvb/pull-pal/vc"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// todo: some of this config definition/usage can be moved to other packages
|
||||||
|
type config struct {
|
||||||
|
// bot credentials + github info
|
||||||
|
selfHandle string
|
||||||
|
selfEmail string
|
||||||
|
githubToken string
|
||||||
|
|
||||||
|
// remote repo info
|
||||||
|
repoDomain string
|
||||||
|
repoHandle string
|
||||||
|
repoName string
|
||||||
|
|
||||||
|
// local paths
|
||||||
|
localRepoPath string
|
||||||
|
promptPath string
|
||||||
|
responsePath string
|
||||||
|
|
||||||
|
// program settings
|
||||||
|
promptToClipboard bool
|
||||||
|
usersToListenTo []string
|
||||||
|
requiredIssueLabels []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfig() config {
|
||||||
|
return config{
|
||||||
|
selfHandle: viper.GetString("handle"),
|
||||||
|
selfEmail: viper.GetString("email"),
|
||||||
|
githubToken: viper.GetString("github-token"),
|
||||||
|
|
||||||
|
repoDomain: viper.GetString("repo-domain"),
|
||||||
|
repoHandle: viper.GetString("repo-handle"),
|
||||||
|
repoName: viper.GetString("repo-name"),
|
||||||
|
|
||||||
|
localRepoPath: viper.GetString("local-repo-path"),
|
||||||
|
promptPath: viper.GetString("prompt-path"),
|
||||||
|
responsePath: viper.GetString("response-path"),
|
||||||
|
|
||||||
|
promptToClipboard: viper.GetBool("prompt-to-clipboard"),
|
||||||
|
usersToListenTo: viper.GetStringSlice("users-to-listen-to"),
|
||||||
|
requiredIssueLabels: viper.GetStringSlice("required-issue-labels"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "pull-pal",
|
Use: "pull-pal",
|
||||||
@ -26,16 +70,7 @@ It can be used to:
|
|||||||
// Uncomment the following line if your bare application
|
// Uncomment the following line if your bare application
|
||||||
// has an action associated with it:
|
// has an action associated with it:
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
selfHandle := viper.GetString("handle")
|
cfg := getConfig()
|
||||||
selfEmail := viper.GetString("email")
|
|
||||||
repoDomain := viper.GetString("repo-domain")
|
|
||||||
repoHandle := viper.GetString("repo-handle")
|
|
||||||
repoName := viper.GetString("repo-name")
|
|
||||||
githubToken := viper.GetString("github-token")
|
|
||||||
localRepoPath := viper.GetString("local-repo-path")
|
|
||||||
promptPath := viper.GetString("prompt-path")
|
|
||||||
promptToClipboard := viper.GetBool("prompt-to-clipboard")
|
|
||||||
responsePath := viper.GetString("response-path")
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
log, err := zap.NewProduction()
|
log, err := zap.NewProduction()
|
||||||
@ -47,16 +82,16 @@ It can be used to:
|
|||||||
log := zap.L()
|
log := zap.L()
|
||||||
|
|
||||||
author := vc.Author{
|
author := vc.Author{
|
||||||
Email: selfEmail,
|
Email: cfg.selfEmail,
|
||||||
Handle: selfHandle,
|
Handle: cfg.selfHandle,
|
||||||
Token: githubToken,
|
Token: cfg.githubToken,
|
||||||
}
|
}
|
||||||
repo := vc.Repository{
|
repo := vc.Repository{
|
||||||
LocalPath: localRepoPath,
|
LocalPath: cfg.localRepoPath,
|
||||||
HostDomain: repoDomain,
|
HostDomain: cfg.repoDomain,
|
||||||
Name: repoName,
|
Name: cfg.repoName,
|
||||||
Owner: vc.Author{
|
Owner: vc.Author{
|
||||||
Handle: repoHandle,
|
Handle: cfg.repoHandle,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
p, err := pullpal.NewPullPal(cmd.Context(), log.Named("pullpal"), author, repo)
|
p, err := pullpal.NewPullPal(cmd.Context(), log.Named("pullpal"), author, repo)
|
||||||
@ -77,8 +112,11 @@ It can be used to:
|
|||||||
|
|
||||||
var issue vc.Issue
|
var issue vc.Issue
|
||||||
var changeRequest llm.CodeChangeRequest
|
var changeRequest llm.CodeChangeRequest
|
||||||
if promptToClipboard {
|
if cfg.promptToClipboard {
|
||||||
issue, changeRequest, err = p.PickIssueToClipboard(promptPath)
|
issue, changeRequest, err = p.PickIssueToClipboard(vc.ListIssueOptions{
|
||||||
|
Handles: cfg.usersToListenTo,
|
||||||
|
Labels: cfg.requiredIssueLabels,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, pullpal.IssueNotFound) {
|
if !errors.Is(err, pullpal.IssueNotFound) {
|
||||||
fmt.Println("error selecting issue and/or generating prompt", err)
|
fmt.Println("error selecting issue and/or generating prompt", err)
|
||||||
@ -90,7 +128,10 @@ It can be used to:
|
|||||||
fmt.Printf("Picked issue and copied prompt to clipboard. Issue #%s\n", issue.ID)
|
fmt.Printf("Picked issue and copied prompt to clipboard. Issue #%s\n", issue.ID)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
issue, changeRequest, err = p.PickIssueToFile(promptPath)
|
issue, changeRequest, err = p.PickIssueToFile(vc.ListIssueOptions{
|
||||||
|
Handles: cfg.usersToListenTo,
|
||||||
|
Labels: cfg.requiredIssueLabels,
|
||||||
|
}, cfg.promptPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, pullpal.IssueNotFound) {
|
if !errors.Is(err, pullpal.IssueNotFound) {
|
||||||
fmt.Println("error selecting issue and/or generating prompt", err)
|
fmt.Println("error selecting issue and/or generating prompt", err)
|
||||||
@ -98,11 +139,11 @@ It can be used to:
|
|||||||
}
|
}
|
||||||
fmt.Println("No issues found. Proceeding to parse prompt")
|
fmt.Println("No issues found. Proceeding to parse prompt")
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Picked issue and copied prompt to clipboard. Issue #%s. Prompt location %s\n", issue.ID, promptPath)
|
fmt.Printf("Picked issue and copied prompt to clipboard. Issue #%s. Prompt location %s\n", issue.ID, cfg.promptPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("\nInsert LLM response into response file: %s", responsePath)
|
fmt.Printf("\nInsert LLM response into response file: %s", cfg.responsePath)
|
||||||
|
|
||||||
fmt.Println("Press 'enter' when ready to parse response. Enter 'skip' to skip response parsing. Enter 'exit' to exit.")
|
fmt.Println("Press 'enter' when ready to parse response. Enter 'skip' to skip response parsing. Enter 'exit' to exit.")
|
||||||
fmt.Scanln(&input)
|
fmt.Scanln(&input)
|
||||||
@ -114,7 +155,7 @@ It can be used to:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
prURL, err := p.ProcessResponseFromFile(changeRequest, responsePath)
|
prURL, err := p.ProcessResponseFromFile(changeRequest, cfg.responsePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("error parsing LLM response and/or making version control changes", err)
|
fmt.Println("error parsing LLM response and/or making version control changes", err)
|
||||||
return
|
return
|
||||||
@ -146,25 +187,35 @@ func init() {
|
|||||||
|
|
||||||
rootCmd.PersistentFlags().StringP("handle", "u", "HANDLE", "handle to use for version control actions")
|
rootCmd.PersistentFlags().StringP("handle", "u", "HANDLE", "handle to use for version control actions")
|
||||||
rootCmd.PersistentFlags().StringP("email", "e", "EMAIL", "email to use for version control actions")
|
rootCmd.PersistentFlags().StringP("email", "e", "EMAIL", "email to use for version control actions")
|
||||||
|
rootCmd.PersistentFlags().StringP("github-token", "t", "GITHUB TOKEN", "token for authenticating Github actions")
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringP("repo-domain", "d", "github.com", "domain for version control server")
|
rootCmd.PersistentFlags().StringP("repo-domain", "d", "github.com", "domain for version control server")
|
||||||
rootCmd.PersistentFlags().StringP("repo-handle", "o", "REPO-HANDLE", "handle of repository's owner on version control server")
|
rootCmd.PersistentFlags().StringP("repo-handle", "o", "REPO-HANDLE", "handle of repository's owner on version control server")
|
||||||
rootCmd.PersistentFlags().StringP("repo-name", "n", "REPO-NAME", "name of repository on version control server")
|
rootCmd.PersistentFlags().StringP("repo-name", "n", "REPO-NAME", "name of repository on version control server")
|
||||||
rootCmd.PersistentFlags().StringP("github-token", "t", "GITHUB TOKEN", "token for authenticating Github actions")
|
|
||||||
rootCmd.PersistentFlags().StringP("local-repo-path", "l", "/tmp/pullpalrepo/", "path where pull pal will check out a local copy of the repository")
|
rootCmd.PersistentFlags().StringP("local-repo-path", "l", "/tmp/pullpalrepo/", "path where pull pal will check out a local copy of the repository")
|
||||||
rootCmd.PersistentFlags().BoolP("prompt-to-clipboard", "c", false, "whether to copy LLM prompt to clipboard rather than using a file")
|
|
||||||
rootCmd.PersistentFlags().StringP("prompt-path", "p", "./path/to/prompt.txt", "path where pull pal will write the llm prompt")
|
rootCmd.PersistentFlags().StringP("prompt-path", "p", "./path/to/prompt.txt", "path where pull pal will write the llm prompt")
|
||||||
rootCmd.PersistentFlags().StringP("response-path", "r", "./path/to/response.txt", "path where pull pal will read the llm response from")
|
rootCmd.PersistentFlags().StringP("response-path", "r", "./path/to/response.txt", "path where pull pal will read the llm response from")
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().BoolP("prompt-to-clipboard", "c", false, "whether to copy LLM prompt to clipboard rather than using a file")
|
||||||
|
rootCmd.PersistentFlags().StringSliceP("users-to-listen-to", "a", []string{}, "a list of Github users that Pull Pal will respond to")
|
||||||
|
rootCmd.PersistentFlags().StringSliceP("required-issue-labels", "i", []string{}, "a list of labels that are required for Pull Pal to select an issue")
|
||||||
|
|
||||||
viper.BindPFlag("handle", rootCmd.PersistentFlags().Lookup("handle"))
|
viper.BindPFlag("handle", rootCmd.PersistentFlags().Lookup("handle"))
|
||||||
viper.BindPFlag("email", rootCmd.PersistentFlags().Lookup("email"))
|
viper.BindPFlag("email", rootCmd.PersistentFlags().Lookup("email"))
|
||||||
|
viper.BindPFlag("github-token", rootCmd.PersistentFlags().Lookup("github-token"))
|
||||||
|
|
||||||
viper.BindPFlag("repo-domain", rootCmd.PersistentFlags().Lookup("repo-domain"))
|
viper.BindPFlag("repo-domain", rootCmd.PersistentFlags().Lookup("repo-domain"))
|
||||||
viper.BindPFlag("repo-handle", rootCmd.PersistentFlags().Lookup("repo-handle"))
|
viper.BindPFlag("repo-handle", rootCmd.PersistentFlags().Lookup("repo-handle"))
|
||||||
viper.BindPFlag("repo-name", rootCmd.PersistentFlags().Lookup("repo-name"))
|
viper.BindPFlag("repo-name", rootCmd.PersistentFlags().Lookup("repo-name"))
|
||||||
viper.BindPFlag("github-token", rootCmd.PersistentFlags().Lookup("github-token"))
|
|
||||||
viper.BindPFlag("local-repo-path", rootCmd.PersistentFlags().Lookup("local-repo-path"))
|
viper.BindPFlag("local-repo-path", rootCmd.PersistentFlags().Lookup("local-repo-path"))
|
||||||
viper.BindPFlag("prompt-to-clipboard", rootCmd.PersistentFlags().Lookup("prompt-to-clipboard"))
|
|
||||||
viper.BindPFlag("prompt-path", rootCmd.PersistentFlags().Lookup("prompt-path"))
|
viper.BindPFlag("prompt-path", rootCmd.PersistentFlags().Lookup("prompt-path"))
|
||||||
viper.BindPFlag("response-path", rootCmd.PersistentFlags().Lookup("response-path"))
|
viper.BindPFlag("response-path", rootCmd.PersistentFlags().Lookup("response-path"))
|
||||||
|
|
||||||
|
viper.BindPFlag("prompt-to-clipboard", rootCmd.PersistentFlags().Lookup("prompt-to-clipboard"))
|
||||||
|
viper.BindPFlag("users-to-listen-to", rootCmd.PersistentFlags().Lookup("users-to-listen-to"))
|
||||||
|
viper.BindPFlag("required-issue-labels", rootCmd.PersistentFlags().Lookup("required-issue-labels"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
@ -44,8 +44,8 @@ func NewPullPal(ctx context.Context, log *zap.Logger, self vc.Author, repo vc.Re
|
|||||||
var IssueNotFound = errors.New("no issue found")
|
var IssueNotFound = errors.New("no issue found")
|
||||||
|
|
||||||
// PickIssueToFile is the same as PickIssue, but the changeRequest is converted to a string and written to a file.
|
// 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) {
|
func (p *PullPal) PickIssueToFile(listIssueOptions vc.ListIssueOptions, promptPath string) (issue vc.Issue, changeRequest llm.CodeChangeRequest, err error) {
|
||||||
issue, changeRequest, err = p.PickIssue()
|
issue, changeRequest, err = p.PickIssue(listIssueOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return issue, changeRequest, err
|
return issue, changeRequest, err
|
||||||
}
|
}
|
||||||
@ -60,8 +60,8 @@ func (p *PullPal) PickIssueToFile(promptPath string) (issue vc.Issue, changeRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PickIssueToClipboard is the same as PickIssue, but the changeRequest is converted to a string and copied to the clipboard.
|
// PickIssueToClipboard is the same as PickIssue, but the changeRequest is converted to a string and copied to the clipboard.
|
||||||
func (p *PullPal) PickIssueToClipboard(promptPath string) (issue vc.Issue, changeRequest llm.CodeChangeRequest, err error) {
|
func (p *PullPal) PickIssueToClipboard(listIssueOptions vc.ListIssueOptions) (issue vc.Issue, changeRequest llm.CodeChangeRequest, err error) {
|
||||||
issue, changeRequest, err = p.PickIssue()
|
issue, changeRequest, err = p.PickIssue(listIssueOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return issue, changeRequest, err
|
return issue, changeRequest, err
|
||||||
}
|
}
|
||||||
@ -76,9 +76,9 @@ func (p *PullPal) PickIssueToClipboard(promptPath string) (issue vc.Issue, chang
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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(listIssueOptions vc.ListIssueOptions) (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()
|
issues, err := p.vcClient.ListOpenIssues(listIssueOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return issue, changeRequest, err
|
return issue, changeRequest, err
|
||||||
}
|
}
|
||||||
@ -154,3 +154,16 @@ func (p *PullPal) ProcessResponse(codeChangeRequest llm.CodeChangeRequest, llmRe
|
|||||||
_, url, err = p.vcClient.OpenCodeChangeRequest(codeChangeRequest, codeChangeResponse)
|
_, url, err = p.vcClient.OpenCodeChangeRequest(codeChangeRequest, codeChangeResponse)
|
||||||
return url, err
|
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{
|
||||||
|
Handles: handles,
|
||||||
|
Labels: labels,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return issues, nil
|
||||||
|
}
|
||||||
|
40
vc/common.go
40
vc/common.go
@ -17,6 +17,40 @@ type Issue struct {
|
|||||||
Author Author
|
Author Author
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i Issue) String() string {
|
||||||
|
return fmt.Sprintf("Issue ID: %s\nAuthor: %s\nSubject: %s\nBody:\n%s\nURL: %s\n", i.ID, i.Author.Handle, i.Subject, i.Body, i.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListIssueOptions defines options for listing issues.
|
||||||
|
type ListIssueOptions struct {
|
||||||
|
// Labels defines the list of labels an issue must have in order to be listed
|
||||||
|
// The issue must have *every* label provided.
|
||||||
|
Labels []string
|
||||||
|
// Handles defines the list of usernames to list issues from
|
||||||
|
// The issue can be created by *any* user provided.
|
||||||
|
Handles []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment represents a comment on a code change request.
|
||||||
|
// TODO comments on issue?
|
||||||
|
type Comment struct {
|
||||||
|
// ChangeID is the local identifier for the code change request this comment was left on (e.g. Github PR number)
|
||||||
|
ChangeID string
|
||||||
|
// Line is the contents of the code on the line where this comment was left
|
||||||
|
Line string
|
||||||
|
Body string
|
||||||
|
Author Author
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListCommentOptions defines options for listing comments.
|
||||||
|
type ListCommentOptions struct {
|
||||||
|
// ChangeID is the local identifier for the code change request to list comments from (e.g. Github PR number)
|
||||||
|
ChangeID string
|
||||||
|
// Handles defines the list of usernames to list comments from
|
||||||
|
// The comment can be created by *any* user provided.
|
||||||
|
Handles []string
|
||||||
|
}
|
||||||
|
|
||||||
// Author represents a commit, issue, or code change request author on a version control server.
|
// Author represents a commit, issue, or code change request author on a version control server.
|
||||||
type Author struct {
|
type Author struct {
|
||||||
Email string
|
Email string
|
||||||
@ -45,8 +79,10 @@ 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 on the version control server.
|
// ListOpenIssues lists unresolved issues meeting the provided criteria on the version control server.
|
||||||
ListOpenIssues() ([]Issue, error)
|
ListOpenIssues(opts ListIssueOptions) ([]Issue, error)
|
||||||
|
// ListOpenComments lists unresolved comments meeting the provided criteria on the version control server.
|
||||||
|
ListOpenComments(opts ListCommentOptions) ([]Comment, error)
|
||||||
// OpenCodeChangeRequest opens a new "code change request" on the version control server (e.g. "pull request" in Github).
|
// OpenCodeChangeRequest opens a new "code change request" on the version control server (e.g. "pull request" in Github).
|
||||||
OpenCodeChangeRequest(req llm.CodeChangeRequest, res llm.CodeChangeResponse) (id, url string, err error)
|
OpenCodeChangeRequest(req llm.CodeChangeRequest, res llm.CodeChangeResponse) (id, url string, err error)
|
||||||
// UpdateCodeChangeRequest updates an existing code change request on the version control server.
|
// UpdateCodeChangeRequest updates an existing code change request on the version control server.
|
||||||
|
23
vc/github.go
23
vc/github.go
@ -166,17 +166,27 @@ func randomBranchName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListOpenIssues lists unresolved issues in the Github repository.
|
// ListOpenIssues lists unresolved issues in the Github repository.
|
||||||
func (gc *GithubClient) ListOpenIssues() ([]Issue, error) {
|
func (gc *GithubClient) ListOpenIssues(options ListIssueOptions) ([]Issue, error) {
|
||||||
// List and parse GitHub issues
|
// List and parse GitHub issues
|
||||||
issues, _, err := gc.client.Issues.ListByRepo(gc.ctx, gc.repo.Owner.Handle, gc.repo.Name, nil)
|
opt := &github.IssueListByRepoOptions{
|
||||||
|
Labels: options.Labels,
|
||||||
|
}
|
||||||
|
issues, _, err := gc.client.Issues.ListByRepo(gc.ctx, gc.repo.Owner.Handle, gc.repo.Name, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
toReturn := []Issue{}
|
toReturn := []Issue{}
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
// TODO make this filtering configurable from outside
|
issueUser := issue.GetUser().GetLogin()
|
||||||
if issue.GetUser().GetLogin() != gc.repo.Owner.Handle {
|
allowedUser := false
|
||||||
|
for _, u := range options.Handles {
|
||||||
|
if issueUser == u {
|
||||||
|
allowedUser = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !allowedUser {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +206,11 @@ func (gc *GithubClient) ListOpenIssues() ([]Issue, error) {
|
|||||||
return toReturn, nil
|
return toReturn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListOpenComments lists unresolved comments in the Github repository.
|
||||||
|
func (gc *GithubClient) ListOpenComments(options ListCommentOptions) ([]Comment, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetLocalFile gets the current representation of the file at the provided path from the local git repo.
|
// GetLocalFile gets the current representation of the file at the provided path from the local git repo.
|
||||||
func (gc *GithubClient) GetLocalFile(path string) (llm.File, error) {
|
func (gc *GithubClient) GetLocalFile(path string) (llm.File, error) {
|
||||||
fullPath := filepath.Join(gc.repo.LocalPath, path)
|
fullPath := filepath.Join(gc.repo.LocalPath, path)
|
||||||
|
Loading…
Reference in New Issue
Block a user