From 6526e12cceff5eeab2cca47195ba2c1ea8b41d10 Mon Sep 17 00:00:00 2001 From: aeddi Date: Mon, 25 Nov 2024 12:12:25 +0900 Subject: [PATCH] docs: document GitHub object + consistency --- contribs/github-bot/bot.go | 40 +++++----- contribs/github-bot/comment.go | 74 +++++++++---------- contribs/github-bot/config.go | 16 ++-- contribs/github-bot/internal/client/client.go | 17 ++++- .../internal/conditions/assignee.go | 4 +- .../github-bot/internal/conditions/author.go | 4 +- .../github-bot/internal/conditions/boolean.go | 10 +-- .../github-bot/internal/conditions/branch.go | 4 +- .../internal/conditions/condition.go | 4 +- .../internal/conditions/constant.go | 4 +- .../github-bot/internal/conditions/file.go | 2 +- .../github-bot/internal/conditions/label.go | 2 +- contribs/github-bot/internal/logger/logger.go | 18 ++--- .../github-bot/internal/logger/terminal.go | 14 ++-- contribs/github-bot/internal/params/params.go | 6 +- contribs/github-bot/internal/params/prlist.go | 2 +- .../internal/requirements/assignee.go | 8 +- .../internal/requirements/author.go | 8 +- .../internal/requirements/boolean.go | 10 +-- .../internal/requirements/branch.go | 4 +- .../internal/requirements/constant.go | 4 +- .../github-bot/internal/requirements/label.go | 8 +- .../internal/requirements/maintainer.go | 2 +- .../internal/requirements/requirement.go | 2 +- .../internal/requirements/reviewer.go | 12 +-- 25 files changed, 147 insertions(+), 132 deletions(-) diff --git a/contribs/github-bot/bot.go b/contribs/github-bot/bot.go index 6264a0d8b61..1dda6b5e2dd 100644 --- a/contribs/github-bot/bot.go +++ b/contribs/github-bot/bot.go @@ -18,7 +18,7 @@ import ( ) func execBot(params *p.Params) error { - // Create context with timeout if specified in the parameters + // Create context with timeout if specified in the parameters. ctx := context.Background() if params.Timeout > 0 { var cancel context.CancelFunc @@ -26,30 +26,30 @@ func execBot(params *p.Params) error { defer cancel() } - // Init GitHub API client + // Init GitHub API client. gh, err := client.New(ctx, params) if err != nil { return fmt.Errorf("comment update handling failed: %w", err) } - // Get GitHub Actions context to retrieve comment update + // Get GitHub Actions context to retrieve comment update. actionCtx, err := githubactions.Context() if err != nil { gh.Logger.Debugf("Unable to retrieve GitHub Actions context: %v", err) return nil } - // Handle comment update, if any + // Handle comment update, if any. if err := handleCommentUpdate(gh, actionCtx); errors.Is(err, errTriggeredByBot) { - return nil // Ignore if this run was triggered by a previous run + return nil // Ignore if this run was triggered by a previous run. } else if err != nil { return fmt.Errorf("comment update handling failed: %w", err) } - // Retrieve a slice of pull requests to process + // Retrieve a slice of pull requests to process. var prs []*github.PullRequest - // If requested, retrieve all open pull requests + // If requested, retrieve all open pull requests. if params.PRAll { opts := &github.PullRequestListOptions{ State: "open", @@ -75,7 +75,7 @@ func execBot(params *p.Params) error { } } else { // Otherwise, retrieve only specified pull request(s) - // (flag or GitHub Action context) + // (flag or GitHub Action context). prs = make([]*github.PullRequest, len(params.PRNums)) for i, prNum := range params.PRNums { pr, _, err := gh.Client.PullRequests.Get(gh.Ctx, gh.Owner, gh.Repo, prNum) @@ -95,14 +95,14 @@ func execBot(params *p.Params) error { gh.Logger.Infof("%d pull requests to process: %v\n", len(prNums), prNums) } - // Process all pull requests in parallel + // Process all pull requests in parallel. autoRules, manualRules := config(gh) var wg sync.WaitGroup - // Used in dry-run mode to log cleanly from different goroutines + // Used in dry-run mode to log cleanly from different goroutines. logMutex := sync.Mutex{} - // Used in regular-run mode to return an error if one PR processing failed + // Used in regular-run mode to return an error if one PR processing failed. var failed atomic.Bool for _, pr := range prs { @@ -112,11 +112,11 @@ func execBot(params *p.Params) error { commentContent := CommentContent{} commentContent.allSatisfied = true - // Iterate over all automatic rules in config + // Iterate over all automatic rules in config. for _, autoRule := range autoRules { ifDetails := treeprint.NewWithRoot(fmt.Sprintf("%s Condition met", utils.Success)) - // Check if conditions of this rule are met by this PR + // Check if conditions of this rule are met by this PR. if !autoRule.ifC.IsMet(pr, ifDetails) { continue } @@ -124,7 +124,7 @@ func execBot(params *p.Params) error { c := AutoContent{Description: autoRule.description, Satisfied: false} thenDetails := treeprint.NewWithRoot(fmt.Sprintf("%s Requirement not satisfied", utils.Fail)) - // Check if requirements of this rule are satisfied by this PR + // Check if requirements of this rule are satisfied by this PR. if autoRule.thenR.IsSatisfied(pr, thenDetails) { thenDetails.SetValue(fmt.Sprintf("%s Requirement satisfied", utils.Success)) c.Satisfied = true @@ -137,22 +137,22 @@ func execBot(params *p.Params) error { commentContent.AutoRules = append(commentContent.AutoRules, c) } - // Retrieve manual check states + // Retrieve manual check states. checks := make(map[string]manualCheckDetails) if comment, err := gh.GetBotComment(pr.GetNumber()); err == nil { checks = getCommentManualChecks(comment.GetBody()) } - // Iterate over all manual rules in config + // Iterate over all manual rules in config. for _, manualRule := range manualRules { ifDetails := treeprint.NewWithRoot(fmt.Sprintf("%s Condition met", utils.Success)) - // Check if conditions of this rule are met by this PR + // Check if conditions of this rule are met by this PR. if !manualRule.ifC.IsMet(pr, ifDetails) { continue } - // Get check status from current comment, if any + // Get check status from current comment, if any. checkedBy := "" check, ok := checks[manualRule.description] if ok { @@ -174,7 +174,7 @@ func execBot(params *p.Params) error { } } - // Logs results or write them in bot PR comment + // Logs results or write them in bot PR comment. if gh.DryRun { logMutex.Lock() logResults(gh.Logger, pr.GetNumber(), commentContent) @@ -197,7 +197,7 @@ func execBot(params *p.Params) error { } // logResults is called in dry-run mode and outputs the status of each check -// and a conclusion +// and a conclusion. func logResults(logger logger.Logger, prNum int, commentContent CommentContent) { logger.Infof("Pull request #%d requirements", prNum) if len(commentContent.AutoRules) > 0 { diff --git a/contribs/github-bot/comment.go b/contribs/github-bot/comment.go index 7cd9aafe90a..7ed22a63b35 100644 --- a/contribs/github-bot/comment.go +++ b/contribs/github-bot/comment.go @@ -16,18 +16,18 @@ import ( var errTriggeredByBot = errors.New("event triggered by bot") -// Compile regex only once +// Compile regex only once. var ( - // Regex for capturing the entire line of a manual check + // Regex for capturing the entire line of a manual check. manualCheckLine = regexp.MustCompile(`(?m:^-\s\[([ xX])\]\s+(.+?)\s*(\(checked by @(\w+)\))?$)`) - // Regex for capturing only the checkboxes + // Regex for capturing only the checkboxes. checkboxes = regexp.MustCompile(`(?m:^- \[[ x]\])`) - // Regex used to capture markdown links + // Regex used to capture markdown links. markdownLink = regexp.MustCompile(`\[(.*)\]\(.*\)`) ) // These structures contain the necessary information to generate -// the bot's comment from the template file +// the bot's comment from the template file. type AutoContent struct { Description string Satisfied bool @@ -52,17 +52,17 @@ type manualCheckDetails struct { } // getCommentManualChecks parses the bot comment to get the checkbox status, -// the check description and the username who checked it +// the check description and the username who checked it. func getCommentManualChecks(commentBody string) map[string]manualCheckDetails { checks := make(map[string]manualCheckDetails) - // For each line that matches the "Manual check" regex + // For each line that matches the "Manual check" regex. for _, match := range manualCheckLine.FindAllStringSubmatch(commentBody, -1) { description := match[2] status := match[1] checkedBy := "" if len(match) > 4 { - checkedBy = strings.ToLower(match[4]) // if X captured, convert it to x + checkedBy = strings.ToLower(match[4]) // if X captured, convert it to x. } checks[description] = manualCheckDetails{status: status, checkedBy: checkedBy} @@ -71,7 +71,7 @@ func getCommentManualChecks(commentBody string) map[string]manualCheckDetails { return checks } -// Recursively search for nested values using the keys provided +// Recursively search for nested values using the keys provided. func indexMap(m map[string]any, keys ...string) any { if len(keys) == 0 { return m @@ -95,13 +95,13 @@ func indexMap(m map[string]any, keys ...string) any { // - the comment change is only a checkbox being checked or unckecked (or restore it) // - the actor / comment editor has permission to modify this checkbox (or restore it) func handleCommentUpdate(gh *client.GitHub, actionCtx *githubactions.GitHubContext) error { - // Ignore if it's not a comment related event + // Ignore if it's not a comment related event. if actionCtx.EventName != "issue_comment" { gh.Logger.Debugf("Event is not issue comment related (%s)", actionCtx.EventName) return nil } - // Ignore if the action type is not deleted or edited + // Ignore if the action type is not deleted or edited. actionType, ok := actionCtx.Event["action"].(string) if !ok { return errors.New("unable to get type on issue comment event") @@ -111,7 +111,7 @@ func handleCommentUpdate(gh *client.GitHub, actionCtx *githubactions.GitHubConte return nil } - // Return if comment was edited by bot (current authenticated user) + // Return if comment was edited by bot (current authenticated user). authUser, _, err := gh.Client.Users.Get(gh.Ctx, "") if err != nil { return fmt.Errorf("unable to get authenticated user: %w", err) @@ -122,55 +122,55 @@ func handleCommentUpdate(gh *client.GitHub, actionCtx *githubactions.GitHubConte return errTriggeredByBot } - // Get login of the author of the edited comment + // Get login of the author of the edited comment. login, ok := indexMap(actionCtx.Event, "comment", "user", "login").(string) if !ok { return errors.New("unable to get comment user login on issue comment event") } - // If the author is not the bot, return + // If the author is not the bot, return. if login != authUser.GetLogin() { return nil } - // Get comment updated body + // Get comment updated body. current, ok := indexMap(actionCtx.Event, "comment", "body").(string) if !ok { return errors.New("unable to get comment body on issue comment event") } - // Get comment previous body + // Get comment previous body. previous, ok := indexMap(actionCtx.Event, "changes", "body", "from").(string) if !ok { return errors.New("unable to get changes body content on issue comment event") } - // Get PR number from GitHub Actions context + // Get PR number from GitHub Actions context. prNum, ok := indexMap(actionCtx.Event, "issue", "number").(float64) if !ok || prNum <= 0 { return errors.New("unable to get issue number on issue comment event") } - // Check if change is only a checkbox being checked or unckecked + // Check if change is only a checkbox being checked or unckecked. if checkboxes.ReplaceAllString(current, "") != checkboxes.ReplaceAllString(previous, "") { - // If not, restore previous comment body + // If not, restore previous comment body. if !gh.DryRun { gh.SetBotComment(previous, int(prNum)) } return errors.New("bot comment edited outside of checkboxes") } - // Check if actor / comment editor has permission to modify changed boxes + // Check if actor / comment editor has permission to modify changed boxes. currentChecks := getCommentManualChecks(current) previousChecks := getCommentManualChecks(previous) edited := "" for key := range currentChecks { - // If there is no diff for this check, ignore it + // If there is no diff for this check, ignore it. if currentChecks[key].status == previousChecks[key].status { continue } - // Get teams allowed to edit this box from config + // Get teams allowed to edit this box from config. var teams []string found := false _, manualRules := config(gh) @@ -183,13 +183,13 @@ func handleCommentUpdate(gh *client.GitHub, actionCtx *githubactions.GitHubConte } // If rule were not found, return to reprocess the bot comment entirely - // (maybe bot config was updated since last run?) + // (maybe bot config was updated since last run?). if !found { gh.Logger.Debugf("Updated rule not found in config: %s", key) return nil } - // If teams specified in rule, check if actor is a member of one of them + // If teams specified in rule, check if actor is a member of one of them. if len(teams) > 0 { if gh.IsUserInTeams(actionCtx.Actor, teams) { if !gh.DryRun { @@ -199,21 +199,21 @@ func handleCommentUpdate(gh *client.GitHub, actionCtx *githubactions.GitHubConte } } - // This regex capture only the line of the current check + // This regex capture only the line of the current check. specificManualCheck := regexp.MustCompile(fmt.Sprintf(`(?m:^- \[%s\] %s.*$)`, currentChecks[key].status, key)) - // If the box is checked, append the username of the user who checked it + // If the box is checked, append the username of the user who checked it. if strings.TrimSpace(currentChecks[key].status) == "x" { replacement := fmt.Sprintf("- [%s] %s (checked by @%s)", currentChecks[key].status, key, actionCtx.Actor) edited = specificManualCheck.ReplaceAllString(current, replacement) } else { - // Else, remove the username of the user + // Else, remove the username of the user. replacement := fmt.Sprintf("- [%s] %s", currentChecks[key].status, key) edited = specificManualCheck.ReplaceAllString(current, replacement) } } - // Update comment with username + // Update comment with username. if edited != "" && !gh.DryRun { gh.SetBotComment(edited, int(prNum)) gh.Logger.Debugf("Comment manual checks updated successfully") @@ -223,23 +223,23 @@ func handleCommentUpdate(gh *client.GitHub, actionCtx *githubactions.GitHubConte } // generateComment generates a comment using the template file and the -// content passed as parameter +// content passed as parameter. func generateComment(content CommentContent) (string, error) { - // Custom function to strip markdown links + // Custom function to strip markdown links. funcMap := template.FuncMap{ "stripLinks": func(input string) string { return markdownLink.ReplaceAllString(input, "$1") }, } - // Bind markdown stripping function to template generator + // Bind markdown stripping function to template generator. const tmplFile = "comment.tmpl" tmpl, err := template.New(tmplFile).Funcs(funcMap).ParseFiles(tmplFile) if err != nil { return "", fmt.Errorf("unable to init template: %w", err) } - // Generate bot comment using template file + // Generate bot comment using template file. var commentBytes bytes.Buffer if err := tmpl.Execute(&commentBytes, content); err != nil { return "", fmt.Errorf("unable to execute template: %w", err) @@ -248,15 +248,15 @@ func generateComment(content CommentContent) (string, error) { return commentBytes.String(), nil } -// updatePullRequest updates or creates both the bot comment and the commit status +// updatePullRequest updates or creates both the bot comment and the commit status. func updatePullRequest(gh *client.GitHub, pr *github.PullRequest, content CommentContent) error { - // Generate comment text content + // Generate comment text content. commentText, err := generateComment(content) if err != nil { return fmt.Errorf("unable to generate comment on PR %d: %w", pr.GetNumber(), err) } - // Update comment on pull request + // Update comment on pull request. comment, err := gh.SetBotComment(commentText, pr.GetNumber()) if err != nil { return fmt.Errorf("unable to update comment on PR %d: %w", pr.GetNumber(), err) @@ -264,7 +264,7 @@ func updatePullRequest(gh *client.GitHub, pr *github.PullRequest, content Commen gh.Logger.Infof("Comment successfully updated on PR %d", pr.GetNumber()) } - // Prepare commit status content + // Prepare commit status content. var ( context = "Merge Requirements" targetURL = comment.GetHTMLURL() @@ -277,7 +277,7 @@ func updatePullRequest(gh *client.GitHub, pr *github.PullRequest, content Commen description = "All requirements are satisfied." } - // Update or create commit status + // Update or create commit status. if _, _, err := gh.Client.Repositories.CreateStatus( gh.Ctx, gh.Owner, diff --git a/contribs/github-bot/config.go b/contribs/github-bot/config.go index 8a2f2e3c12e..4504844e289 100644 --- a/contribs/github-bot/config.go +++ b/contribs/github-bot/config.go @@ -6,22 +6,22 @@ import ( r "github.com/gnolang/gno/contribs/github-bot/internal/requirements" ) -// Automatic check that will be performed by the bot +// Automatic check that will be performed by the bot. type automaticCheck struct { description string - ifC c.Condition // If the condition is met, the rule is displayed and the requirement is executed - thenR r.Requirement // If the requirement is satisfied, the check passes + ifC c.Condition // If the condition is met, the rule is displayed and the requirement is executed. + thenR r.Requirement // If the requirement is satisfied, the check passes. } -// Manual check that will be performed by users +// Manual check that will be performed by users. type manualCheck struct { description string - ifC c.Condition // If the condition is met, a checkbox will be displayed on bot comment - teams []string // Members of these teams can check the checkbox to make the check pass + ifC c.Condition // If the condition is met, a checkbox will be displayed on bot comment. + teams []string // Members of these teams can check the checkbox to make the check pass. } // This function returns the configuration of the bot consisting of automatic and manual checks -// in which the GitHub client is injected +// in which the GitHub client is injected. func config(gh *client.GitHub) ([]automaticCheck, []manualCheck) { auto := []automaticCheck{ { @@ -87,7 +87,7 @@ func config(gh *client.GitHub) ([]automaticCheck, []manualCheck) { }, } - // Check for duplicates in manual rule descriptions (needs to be unique for the bot operations) + // Check for duplicates in manual rule descriptions (needs to be unique for the bot operations). unique := make(map[string]struct{}) for _, rule := range manual { if _, exists := unique[rule.description]; exists { diff --git a/contribs/github-bot/internal/client/client.go b/contribs/github-bot/internal/client/client.go index 19f96339233..2aec5c8681f 100644 --- a/contribs/github-bot/internal/client/client.go +++ b/contribs/github-bot/internal/client/client.go @@ -12,11 +12,17 @@ import ( "github.com/google/go-github/v64/github" ) -// PageSize is the number of items to load for each iteration when fetching a list +// PageSize is the number of items to load for each iteration when fetching a list. const PageSize = 100 var ErrBotCommentNotFound = errors.New("bot comment not found") +// GitHub contains everything necessary to interact with the GitHub API, +// including the client, a context (which must be passed with each request), +// a logger, etc. This object will be passed to each condition or requirement +// that requires fetching additional information or modifying things on GitHub. +// The object also provides methods for performing more complex operations than +// a simple API call. type GitHub struct { Client *github.Client Ctx context.Context @@ -26,6 +32,7 @@ type GitHub struct { Repo string } +// GetBotComment retrieves the bot's (current user) comment on provided PR number. func (gh *GitHub) GetBotComment(prNum int) (*github.IssueComment, error) { // List existing comments const ( @@ -76,6 +83,8 @@ func (gh *GitHub) GetBotComment(prNum int) (*github.IssueComment, error) { return nil, errors.New("bot comment not found") } +// SetBotComment creates a bot's comment on the provided PR number +// or updates it if it already exists. func (gh *GitHub) SetBotComment(body string, prNum int) (*github.IssueComment, error) { // Create bot comment if it does not already exist comment, err := gh.GetBotComment(prNum) @@ -110,6 +119,7 @@ func (gh *GitHub) SetBotComment(body string, prNum int) (*github.IssueComment, e return editComment, nil } +// ListTeamMembers lists the members of the specified team. func (gh *GitHub) ListTeamMembers(team string) ([]*github.User, error) { var ( allMembers []*github.User @@ -142,6 +152,8 @@ func (gh *GitHub) ListTeamMembers(team string) ([]*github.User, error) { return allMembers, nil } +// IsUserInTeams checks if the specified user is a member of any of the +// provided teams. func (gh *GitHub) IsUserInTeams(user string, teams []string) bool { for _, team := range teams { teamMembers, err := gh.ListTeamMembers(team) @@ -160,6 +172,7 @@ func (gh *GitHub) IsUserInTeams(user string, teams []string) bool { return false } +// ListPRReviewers returns the list of reviewers for the specified PR number. func (gh *GitHub) ListPRReviewers(prNum int) (*github.Reviewers, error) { var ( allReviewers = &github.Reviewers{} @@ -192,6 +205,7 @@ func (gh *GitHub) ListPRReviewers(prNum int) (*github.Reviewers, error) { return allReviewers, nil } +// ListPRReviewers returns the list of reviews for the specified PR number. func (gh *GitHub) ListPRReviews(prNum int) ([]*github.PullRequestReview, error) { var ( allReviews []*github.PullRequestReview @@ -223,6 +237,7 @@ func (gh *GitHub) ListPRReviews(prNum int) ([]*github.PullRequestReview, error) return allReviews, nil } +// New initializes the API client, the logger, and creates an instance of GitHub. func New(ctx context.Context, params *p.Params) (*GitHub, error) { gh := &GitHub{ Ctx: ctx, diff --git a/contribs/github-bot/internal/conditions/assignee.go b/contribs/github-bot/internal/conditions/assignee.go index 9682e224f11..7024259909c 100644 --- a/contribs/github-bot/internal/conditions/assignee.go +++ b/contribs/github-bot/internal/conditions/assignee.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// Assignee Condition +// Assignee Condition. type assignee struct { user string } @@ -33,7 +33,7 @@ func Assignee(user string) Condition { return &assignee{user: user} } -// AssigneeInTeam Condition +// AssigneeInTeam Condition. type assigneeInTeam struct { gh *client.GitHub team string diff --git a/contribs/github-bot/internal/conditions/author.go b/contribs/github-bot/internal/conditions/author.go index e5079b9e4f4..9052f781bd5 100644 --- a/contribs/github-bot/internal/conditions/author.go +++ b/contribs/github-bot/internal/conditions/author.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// Author Condition +// Author Condition. type author struct { user string } @@ -29,7 +29,7 @@ func Author(user string) Condition { return &author{user: user} } -// AuthorInTeam Condition +// AuthorInTeam Condition. type authorInTeam struct { gh *client.GitHub team string diff --git a/contribs/github-bot/internal/conditions/boolean.go b/contribs/github-bot/internal/conditions/boolean.go index e030563709a..2fa3a25f7ac 100644 --- a/contribs/github-bot/internal/conditions/boolean.go +++ b/contribs/github-bot/internal/conditions/boolean.go @@ -9,7 +9,7 @@ import ( "github.com/xlab/treeprint" ) -// And Condition +// And Condition. type and struct { conditions []Condition } @@ -24,7 +24,7 @@ func (a *and) IsMet(pr *github.PullRequest, details treeprint.Tree) bool { if !condition.IsMet(pr, branch) { met = utils.Fail // We don't break here because we need to call IsMet on all conditions - // to populate the details tree + // to populate the details tree. } } @@ -41,7 +41,7 @@ func And(conditions ...Condition) Condition { return &and{conditions} } -// Or Condition +// Or Condition. type or struct { conditions []Condition } @@ -56,7 +56,7 @@ func (o *or) IsMet(pr *github.PullRequest, details treeprint.Tree) bool { if condition.IsMet(pr, branch) { met = utils.Success // We don't break here because we need to call IsMet on all conditions - // to populate the details tree + // to populate the details tree. } } @@ -73,7 +73,7 @@ func Or(conditions ...Condition) Condition { return &or{conditions} } -// Not Condition +// Not Condition. type not struct { cond Condition } diff --git a/contribs/github-bot/internal/conditions/branch.go b/contribs/github-bot/internal/conditions/branch.go index ef29e2d39cb..6977d633d98 100644 --- a/contribs/github-bot/internal/conditions/branch.go +++ b/contribs/github-bot/internal/conditions/branch.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// BaseBranch Condition +// BaseBranch Condition. type baseBranch struct { pattern *regexp.Regexp } @@ -29,7 +29,7 @@ func BaseBranch(pattern string) Condition { return &baseBranch{pattern: regexp.MustCompile(pattern)} } -// HeadBranch Condition +// HeadBranch Condition. type headBranch struct { pattern *regexp.Regexp } diff --git a/contribs/github-bot/internal/conditions/condition.go b/contribs/github-bot/internal/conditions/condition.go index afc436b8209..8c2fa5a2948 100644 --- a/contribs/github-bot/internal/conditions/condition.go +++ b/contribs/github-bot/internal/conditions/condition.go @@ -6,7 +6,7 @@ import ( ) type Condition interface { - // Check if the Condition is met and add the detail - // to the tree passed as a parameter + // Check if the Condition is met and add the details + // to the tree passed as a parameter. IsMet(pr *github.PullRequest, details treeprint.Tree) bool } diff --git a/contribs/github-bot/internal/conditions/constant.go b/contribs/github-bot/internal/conditions/constant.go index d00af13dca2..26bbe9e8110 100644 --- a/contribs/github-bot/internal/conditions/constant.go +++ b/contribs/github-bot/internal/conditions/constant.go @@ -7,7 +7,7 @@ import ( "github.com/xlab/treeprint" ) -// Always Condition +// Always Condition. type always struct{} var _ Condition = &always{} @@ -20,7 +20,7 @@ func Always() Condition { return &always{} } -// Never Condition +// Never Condition. type never struct{} var _ Condition = &never{} diff --git a/contribs/github-bot/internal/conditions/file.go b/contribs/github-bot/internal/conditions/file.go index c51a13c39cd..e3854a7734a 100644 --- a/contribs/github-bot/internal/conditions/file.go +++ b/contribs/github-bot/internal/conditions/file.go @@ -11,7 +11,7 @@ import ( "github.com/xlab/treeprint" ) -// FileChanged Condition +// FileChanged Condition. type fileChanged struct { gh *client.GitHub pattern *regexp.Regexp diff --git a/contribs/github-bot/internal/conditions/label.go b/contribs/github-bot/internal/conditions/label.go index de3844b9747..ace94ed436c 100644 --- a/contribs/github-bot/internal/conditions/label.go +++ b/contribs/github-bot/internal/conditions/label.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// Label Condition +// Label Condition. type label struct { pattern *regexp.Regexp } diff --git a/contribs/github-bot/internal/logger/logger.go b/contribs/github-bot/internal/logger/logger.go index 2139fe07584..570ca027e5c 100644 --- a/contribs/github-bot/internal/logger/logger.go +++ b/contribs/github-bot/internal/logger/logger.go @@ -4,28 +4,28 @@ import ( "os" ) -// All Logger methods follow the standard fmt.Printf convention +// All Logger methods follow the standard fmt.Printf convention. type Logger interface { - // Debugf prints a debug-level message + // Debugf prints a debug-level message. Debugf(msg string, args ...any) - // Noticef prints a notice-level message + // Noticef prints a notice-level message. Noticef(msg string, args ...any) - // Warningf prints a warning-level message + // Warningf prints a warning-level message. Warningf(msg string, args ...any) - // Errorf prints a error-level message + // Errorf prints a error-level message. Errorf(msg string, args ...any) - // Fatalf prints a error-level message and exits + // Fatalf prints a error-level message and exits. Fatalf(msg string, args ...any) - // Infof prints message to stdout without any level annotations + // Infof prints message to stdout without any level annotations. Infof(msg string, args ...any) } -// Returns a logger suitable for Github Actions or terminal output +// Returns a logger suitable for Github Actions or terminal output. func NewLogger(verbose bool) Logger { if _, isAction := os.LookupEnv("GITHUB_ACTION"); isAction { return newActionLogger() @@ -34,7 +34,7 @@ func NewLogger(verbose bool) Logger { return newTermLogger(verbose) } -// NewNoopLogger returns a logger that does not log anything +// NewNoopLogger returns a logger that does not log anything. func NewNoopLogger() Logger { return newNoopLogger() } diff --git a/contribs/github-bot/internal/logger/terminal.go b/contribs/github-bot/internal/logger/terminal.go index cc12022011a..d0e5671a3c8 100644 --- a/contribs/github-bot/internal/logger/terminal.go +++ b/contribs/github-bot/internal/logger/terminal.go @@ -10,37 +10,37 @@ type termLogger struct{} var _ Logger = &termLogger{} -// Debugf implements Logger +// Debugf implements Logger. func (s *termLogger) Debugf(msg string, args ...any) { msg = fmt.Sprintf("%s\n", msg) slog.Debug(fmt.Sprintf(msg, args...)) } -// Errorf implements Logger +// Errorf implements Logger. func (s *termLogger) Errorf(msg string, args ...any) { msg = fmt.Sprintf("%s\n", msg) slog.Error(fmt.Sprintf(msg, args...)) } -// Fatalf implements Logger +// Fatalf implements Logger. func (s *termLogger) Fatalf(msg string, args ...any) { s.Errorf(msg, args...) os.Exit(1) } -// Infof implements Logger +// Infof implements Logger. func (s *termLogger) Infof(msg string, args ...any) { msg = fmt.Sprintf("%s\n", msg) slog.Info(fmt.Sprintf(msg, args...)) } -// Noticef implements Logger +// Noticef implements Logger. func (s *termLogger) Noticef(msg string, args ...any) { - // Alias to info on terminal since notice level only exists on GitHub Actions + // Alias to info on terminal since notice level only exists on GitHub Actions. s.Infof(msg, args...) } -// Warningf implements Logger +// Warningf implements Logger. func (s *termLogger) Warningf(msg string, args ...any) { msg = fmt.Sprintf("%s\n", msg) slog.Warn(fmt.Sprintf(msg, args...)) diff --git a/contribs/github-bot/internal/params/params.go b/contribs/github-bot/internal/params/params.go index 8925d0905cf..3a76e0c7684 100644 --- a/contribs/github-bot/internal/params/params.go +++ b/contribs/github-bot/internal/params/params.go @@ -74,20 +74,20 @@ func (p *Params) RegisterFlags(fs *flag.FlagSet) { } func (p *Params) ValidateFlags() { - // Helper to display an error + usage message before exiting + // Helper to display an error + usage message before exiting. errorUsage := func(err string) { fmt.Fprintf(p.flagSet.Output(), "Error: %s\n\n", err) p.flagSet.Usage() os.Exit(1) } - // Check if flags are coherent + // Check if flags are coherent. if p.PRAll && len(p.PRNums) != 0 { errorUsage("You can specify only one of the '-pr-all' and '-pr-numbers' flags") } // If one of these values is empty, it must be retrieved - // from GitHub Actions context + // from GitHub Actions context. if p.Owner == "" || p.Repo == "" || (len(p.PRNums) == 0 && !p.PRAll) { actionCtx, err := githubactions.Context() if err != nil { diff --git a/contribs/github-bot/internal/params/prlist.go b/contribs/github-bot/internal/params/prlist.go index 028986dcbfd..5e51181452f 100644 --- a/contribs/github-bot/internal/params/prlist.go +++ b/contribs/github-bot/internal/params/prlist.go @@ -9,7 +9,7 @@ import ( type PRList []int -// PRList is both a TextMarshaler and a TextUnmarshaler +// PRList is both a TextMarshaler and a TextUnmarshaler. var ( _ encoding.TextMarshaler = PRList{} _ encoding.TextUnmarshaler = &PRList{} diff --git a/contribs/github-bot/internal/requirements/assignee.go b/contribs/github-bot/internal/requirements/assignee.go index c48a63c34db..9a2723ad18f 100644 --- a/contribs/github-bot/internal/requirements/assignee.go +++ b/contribs/github-bot/internal/requirements/assignee.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// Assignee Requirement +// Assignee Requirement. type assignee struct { gh *client.GitHub user string @@ -21,19 +21,19 @@ var _ Requirement = &assignee{} func (a *assignee) IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool { detail := fmt.Sprintf("This user is assigned to pull request: %s", a.user) - // Check if user was already assigned to PR + // Check if user was already assigned to PR. for _, assignee := range pr.Assignees { if a.user == assignee.GetLogin() { return utils.AddStatusNode(true, detail, details) } } - // If in a dry run, skip assigning the user + // If in a dry run, skip assigning the user. if a.gh.DryRun { return utils.AddStatusNode(false, detail, details) } - // If user not already assigned, assign it + // If user not already assigned, assign it. if _, _, err := a.gh.Client.Issues.AddAssignees( a.gh.Ctx, a.gh.Owner, diff --git a/contribs/github-bot/internal/requirements/author.go b/contribs/github-bot/internal/requirements/author.go index c60139ba192..eed2c510b97 100644 --- a/contribs/github-bot/internal/requirements/author.go +++ b/contribs/github-bot/internal/requirements/author.go @@ -8,9 +8,9 @@ import ( "github.com/xlab/treeprint" ) -// Author Requirement +// Author Requirement. type author struct { - c conditions.Condition // Alias Author requirement to identical condition + c conditions.Condition // Alias Author requirement to identical condition. } var _ Requirement = &author{} @@ -23,9 +23,9 @@ func Author(user string) Requirement { return &author{conditions.Author(user)} } -// AuthorInTeam Requirement +// AuthorInTeam Requirement. type authorInTeam struct { - c conditions.Condition // Alias AuthorInTeam requirement to identical condition + c conditions.Condition // Alias AuthorInTeam requirement to identical condition. } var _ Requirement = &authorInTeam{} diff --git a/contribs/github-bot/internal/requirements/boolean.go b/contribs/github-bot/internal/requirements/boolean.go index 1b6840f6aa9..6b441c92f80 100644 --- a/contribs/github-bot/internal/requirements/boolean.go +++ b/contribs/github-bot/internal/requirements/boolean.go @@ -9,7 +9,7 @@ import ( "github.com/xlab/treeprint" ) -// And Requirement +// And Requirement. type and struct { requirements []Requirement } @@ -24,7 +24,7 @@ func (a *and) IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool { if !requirement.IsSatisfied(pr, branch) { satisfied = utils.Fail // We don't break here because we need to call IsSatisfied on all - // requirements to populate the details tree + // requirements to populate the details tree. } } @@ -41,7 +41,7 @@ func And(requirements ...Requirement) Requirement { return &and{requirements} } -// Or Requirement +// Or Requirement. type or struct { requirements []Requirement } @@ -56,7 +56,7 @@ func (o *or) IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool { if requirement.IsSatisfied(pr, branch) { satisfied = utils.Success // We don't break here because we need to call IsSatisfied on all - // requirements to populate the details tree + // requirements to populate the details tree. } } @@ -73,7 +73,7 @@ func Or(requirements ...Requirement) Requirement { return &or{requirements} } -// Not Requirement +// Not Requirement. type not struct { req Requirement } diff --git a/contribs/github-bot/internal/requirements/branch.go b/contribs/github-bot/internal/requirements/branch.go index bd5a1e3ea89..65d00d06ae8 100644 --- a/contribs/github-bot/internal/requirements/branch.go +++ b/contribs/github-bot/internal/requirements/branch.go @@ -11,10 +11,10 @@ import ( ) // Pass this to UpToDateWith constructor to check the PR head branch -// against its base branch +// against its base branch. const PR_BASE = "PR_BASE" -// UpToDateWith Requirement +// UpToDateWith Requirement. type upToDateWith struct { gh *client.GitHub base string diff --git a/contribs/github-bot/internal/requirements/constant.go b/contribs/github-bot/internal/requirements/constant.go index 5ab33c2573a..cbe932da830 100644 --- a/contribs/github-bot/internal/requirements/constant.go +++ b/contribs/github-bot/internal/requirements/constant.go @@ -7,7 +7,7 @@ import ( "github.com/xlab/treeprint" ) -// Always Requirement +// Always Requirement. type always struct{} var _ Requirement = &always{} @@ -20,7 +20,7 @@ func Always() Requirement { return &always{} } -// Never Requirement +// Never Requirement. type never struct{} var _ Requirement = &never{} diff --git a/contribs/github-bot/internal/requirements/label.go b/contribs/github-bot/internal/requirements/label.go index 7963c47b0cd..d1ee475db92 100644 --- a/contribs/github-bot/internal/requirements/label.go +++ b/contribs/github-bot/internal/requirements/label.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// Label Requirement +// Label Requirement. type label struct { gh *client.GitHub name string @@ -21,19 +21,19 @@ var _ Requirement = &label{} func (l *label) IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool { detail := fmt.Sprintf("This label is applied to pull request: %s", l.name) - // Check if label was already applied to PR + // Check if label was already applied to PR. for _, label := range pr.Labels { if l.name == label.GetName() { return utils.AddStatusNode(true, detail, details) } } - // If in a dry run, skip applying the label + // If in a dry run, skip applying the label. if l.gh.DryRun { return utils.AddStatusNode(false, detail, details) } - // If label not already applied, apply it + // If label not already applied, apply it. if _, _, err := l.gh.Client.Issues.AddLabelsToIssue( l.gh.Ctx, l.gh.Owner, diff --git a/contribs/github-bot/internal/requirements/maintainer.go b/contribs/github-bot/internal/requirements/maintainer.go index 261f415f852..8e3f356bebf 100644 --- a/contribs/github-bot/internal/requirements/maintainer.go +++ b/contribs/github-bot/internal/requirements/maintainer.go @@ -7,7 +7,7 @@ import ( "github.com/xlab/treeprint" ) -// MaintainerCanModify Requirement +// MaintainerCanModify Requirement. type maintainerCanModify struct{} var _ Requirement = &maintainerCanModify{} diff --git a/contribs/github-bot/internal/requirements/requirement.go b/contribs/github-bot/internal/requirements/requirement.go index a83646c1428..296c4a1461d 100644 --- a/contribs/github-bot/internal/requirements/requirement.go +++ b/contribs/github-bot/internal/requirements/requirement.go @@ -7,6 +7,6 @@ import ( type Requirement interface { // Check if the Requirement is satisfied and add the detail - // to the tree passed as a parameter + // to the tree passed as a parameter. IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool } diff --git a/contribs/github-bot/internal/requirements/reviewer.go b/contribs/github-bot/internal/requirements/reviewer.go index 174c4b6208c..aa3914d4c4a 100644 --- a/contribs/github-bot/internal/requirements/reviewer.go +++ b/contribs/github-bot/internal/requirements/reviewer.go @@ -10,7 +10,7 @@ import ( "github.com/xlab/treeprint" ) -// Reviewer Requirement +// Reviewer Requirement. type reviewByUser struct { gh *client.GitHub user string @@ -21,7 +21,7 @@ var _ Requirement = &reviewByUser{} func (r *reviewByUser) IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool { detail := fmt.Sprintf("This user approved pull request: %s", r.user) - // If not a dry run, make the user a reviewer if he's not already + // If not a dry run, make the user a reviewer if he's not already. if !r.gh.DryRun { requested := false reviewers, err := r.gh.ListPRReviewers(pr.GetNumber()) @@ -55,7 +55,7 @@ func (r *reviewByUser) IsSatisfied(pr *github.PullRequest, details treeprint.Tre } } - // Check if user already approved this PR + // Check if user already approved this PR. reviews, err := r.gh.ListPRReviews(pr.GetNumber()) if err != nil { r.gh.Logger.Errorf("unable to check if user %s already approved this PR: %v", r.user, err) @@ -77,7 +77,7 @@ func ReviewByUser(gh *client.GitHub, user string) Requirement { return &reviewByUser{gh, user} } -// Reviewer Requirement +// Reviewer Requirement. type reviewByTeamMembers struct { gh *client.GitHub team string @@ -89,7 +89,7 @@ var _ Requirement = &reviewByTeamMembers{} func (r *reviewByTeamMembers) IsSatisfied(pr *github.PullRequest, details treeprint.Tree) bool { detail := fmt.Sprintf("At least %d user(s) of the team %s approved pull request", r.count, r.team) - // If not a dry run, make the user a reviewer if he's not already + // If not a dry run, make the user a reviewer if he's not already. if !r.gh.DryRun { requested := false reviewers, err := r.gh.ListPRReviewers(pr.GetNumber()) @@ -123,7 +123,7 @@ func (r *reviewByTeamMembers) IsSatisfied(pr *github.PullRequest, details treepr } } - // Check how many members of this team already approved this PR + // Check how many members of this team already approved this PR. approved := uint(0) reviews, err := r.gh.ListPRReviews(pr.GetNumber()) if err != nil {