feat(cmd): wire --provider and --base-url flags into CLI (Phase 5) #106

Merged
aweiker merged 17 commits from review-bot-issue-82 into feature/github-support 2026-05-13 17:16:28 +00:00
2 changed files with 9 additions and 6 deletions
Showing only changes of commit c4af35cd78 - Show all commits
+8 -3
View File
10
@@ -170,7 +170,8 @@ func main() {
} }
Review

[MINOR] Default case in the VCS provider switch uses panic("unreachable..."). Repository conventions state "never panic"; prefer logging and exiting with a non-zero status to enforce unreachable conditions.

**[MINOR]** Default case in the VCS provider switch uses panic("unreachable..."). Repository conventions state "never panic"; prefer logging and exiting with a non-zero status to enforce unreachable conditions.
client = github.NewClient(*reviewerToken, ghBaseURL) client = github.NewClient(*reviewerToken, ghBaseURL)
default: default:
panic("unreachable: unhandled provider " + *provider) fmt.Fprintf(os.Stderr, "Error: unhandled provider %q\n", *provider)
os.Exit(1)
} }
Review

[MINOR] The panic("unreachable: ...") in the default case of the VCS client switch violates the project convention "Return errors; never panic" (from CONVENTIONS.md). Although the validation at line 104 does make this branch genuinely unreachable at runtime, the convention is unconditional. A cleaner alternative is slog.Error(...); os.Exit(1) — consistent with every other fatal error path in this file — or the validation could be made to work through a single code path. The panic is acceptable as a defensive measure (and correctly named 'unreachable'), but it deviates from stated conventions.

**[MINOR]** The `panic("unreachable: ...")` in the `default` case of the VCS client switch violates the project convention "Return errors; never panic" (from CONVENTIONS.md). Although the validation at line 104 does make this branch genuinely unreachable at runtime, the convention is unconditional. A cleaner alternative is `slog.Error(...); os.Exit(1)` — consistent with every other fatal error path in this file — or the validation could be made to work through a single code path. The `panic` is acceptable as a defensive measure (and correctly named 'unreachable'), but it deviates from stated conventions.
slog.Info("VCS client initialized", "provider", *provider) slog.Info("VCS client initialized", "provider", *provider)
3
@@ -523,7 +524,8 @@ func verdictToEvent(verdict string) vcs.ReviewEvent {
// For GitHub: dismisses old reviews. // For GitHub: dismisses old reviews.
// For Gitea: edits the review body and resolves inline comments. // For Gitea: edits the review body and resolves inline comments.
func supersedeOldReviews(ctx context.Context, client vcs.Client, provider, vcsURL, owner, repoName string, prNumber int, oldReviews []vcs.Review, newReviewID int64, sentinel string) error { func supersedeOldReviews(ctx context.Context, client vcs.Client, provider, vcsURL, owner, repoName string, prNumber int, oldReviews []vcs.Review, newReviewID int64, sentinel string) error {
if provider == "github" { switch provider {
case "github":
for _, old := range oldReviews { for _, old := range oldReviews {
if err := client.DismissReview(ctx, owner, repoName, prNumber, old.ID, "Superseded by new review"); err != nil { if err := client.DismissReview(ctx, owner, repoName, prNumber, old.ID, "Superseded by new review"); err != nil {
slog.Warn("failed to dismiss review", "id", old.ID, "error", err) slog.Warn("failed to dismiss review", "id", old.ID, "error", err)
@@ -532,9 +534,12 @@ func supersedeOldReviews(ctx context.Context, client vcs.Client, provider, vcsUR
} }
} }
return nil return nil
case "gitea":
// Gitea: EditComment + ResolveComment flow
default:
return fmt.Errorf("supersedeOldReviews: unsupported provider %q", provider)
} }
// Gitea: existing EditComment + ResolveComment flow
giteaAdapter, ok := client.(*gitea.Adapter) giteaAdapter, ok := client.(*gitea.Adapter)
if !ok { if !ok {
return fmt.Errorf("expected gitea.Adapter for gitea provider, got %T", client) return fmt.Errorf("expected gitea.Adapter for gitea provider, got %T", client)
1
+1 -3
View File
@@ -42,7 +42,6 @@ type reviewCommentCreate struct {
// dismissReviewRequest is the GitHub API request body for dismissing a review. // dismissReviewRequest is the GitHub API request body for dismissing a review.
type dismissReviewRequest struct { type dismissReviewRequest struct {
Message string `json:"message"` Message string `json:"message"`
Event string `json:"event"`
} }
// userResponse is the GitHub API response for the authenticated user. // userResponse is the GitHub API response for the authenticated user.
@@ -60,7 +59,7 @@ func translateReviewEvent(event vcs.ReviewEvent) string {
case vcs.ReviewEventComment: case vcs.ReviewEventComment:
return "COMMENT" return "COMMENT"
default: default:
return string(event) return "COMMENT"
} }
} }
@@ -161,7 +160,6 @@ func (c *Client) DismissReview(ctx context.Context, owner, repo string, number i
payload := dismissReviewRequest{ payload := dismissReviewRequest{
Message: message, Message: message,
Event: "DISMISS",
} }
_, err := c.doJSONRequest(ctx, http.MethodPut, reqURL, payload) _, err := c.doJSONRequest(ctx, http.MethodPut, reqURL, payload)