Merge pull request 'feat(vcs): extract interfaces and types from gitea/ (Phase 1)' (#83) from review-bot-issue-78 into feature/github-support
Reviewed-on: #83 Reviewed-by: security-review-bot <10+security-review-bot@noreply.gitea.weiker.me> Reviewed-by: Aaron Weiker <aaron@weiker.org>
This commit was merged in pull request #83.
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
//go:build phase2
|
||||||
|
|
||||||
|
package vcs_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitea.weiker.me/rodin/review-bot/gitea"
|
||||||
|
"gitea.weiker.me/rodin/review-bot/vcs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Compile-time assertion: documents the gap between gitea.Client and vcs.Client.
|
||||||
|
// Guarded by the "phase2" build tag — enable once the Gitea adapter bridges these gaps:
|
||||||
|
//
|
||||||
|
// 1. PostReview signature mismatch:
|
||||||
|
// gitea.Client: PostReview(ctx, owner, repo, number, event, body string, comments []gitea.ReviewComment)
|
||||||
|
// vcs.Reviewer: PostReview(ctx, owner, repo, number, req vcs.ReviewRequest)
|
||||||
|
//
|
||||||
|
// 2. GetFileContent signature mismatch:
|
||||||
|
// gitea.Client: GetFileContent(ctx, owner, repo, filepath string) [no ref; uses default branch]
|
||||||
|
// vcs.FileReader: GetFileContent(ctx, owner, repo, path, ref string)
|
||||||
|
// (gitea.Client has GetFileContentRef for the ref variant)
|
||||||
|
//
|
||||||
|
// 3. ReviewComment type mismatch:
|
||||||
|
// gitea.ReviewComment uses NewPosition int64 (Gitea line-number convention)
|
||||||
|
// vcs.ReviewComment uses Position int (GitHub diff-position convention)
|
||||||
|
//
|
||||||
|
// The Gitea adapter (Phase 2) will wrap gitea.Client to bridge these gaps.
|
||||||
|
var _ vcs.Client = (*gitea.Client)(nil)
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// Package vcs defines the shared VCS client interface and supporting types.
|
||||||
|
// Platform adapters (gitea, github) implement these interfaces so the core
|
||||||
|
// review logic can work with any VCS platform without platform-specific code.
|
||||||
|
package vcs
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// PRReader can fetch pull request metadata, diffs, and changed files.
|
||||||
|
type PRReader interface {
|
||||||
|
GetPullRequest(ctx context.Context, owner, repo string, number int) (*PullRequest, error)
|
||||||
|
GetPullRequestDiff(ctx context.Context, owner, repo string, number int) (string, error)
|
||||||
|
GetPullRequestFiles(ctx context.Context, owner, repo string, number int) ([]ChangedFile, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileReader can fetch file contents and list directory entries.
|
||||||
|
type FileReader interface {
|
||||||
|
GetFileContent(ctx context.Context, owner, repo, path, ref string) (string, error)
|
||||||
|
ListContents(ctx context.Context, owner, repo, path string) ([]ContentEntry, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reviewer can post, list, and delete pull request reviews.
|
||||||
|
type Reviewer interface {
|
||||||
|
PostReview(ctx context.Context, owner, repo string, number int, req ReviewRequest) (*Review, error)
|
||||||
|
ListReviews(ctx context.Context, owner, repo string, number int) ([]Review, error)
|
||||||
|
DeleteReview(ctx context.Context, owner, repo string, number int, reviewID int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identity can report who the authenticated user is.
|
||||||
|
type Identity interface {
|
||||||
|
GetAuthenticatedUser(ctx context.Context) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client is the full VCS interface: PR reads, file reads, review management, and identity.
|
||||||
|
// Platform adapters (gitea, github) implement this interface.
|
||||||
|
type Client interface {
|
||||||
|
PRReader
|
||||||
|
FileReader
|
||||||
|
Reviewer
|
||||||
|
Identity
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package vcs
|
||||||
|
|
||||||
|
// ReviewEvent is the event type for a pull request review action.
|
||||||
|
// Adapters must translate these action constants to/from platform-native values.
|
||||||
|
// For example, Gitea uses "APPROVED" as both action and state, while GitHub
|
||||||
|
// uses "APPROVE" for the action and returns "approved" as the state.
|
||||||
|
type ReviewEvent string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ReviewEventApprove approves the pull request.
|
||||||
|
ReviewEventApprove ReviewEvent = "APPROVE"
|
||||||
|
// ReviewEventRequestChanges requests changes to the pull request.
|
||||||
|
ReviewEventRequestChanges ReviewEvent = "REQUEST_CHANGES"
|
||||||
|
// ReviewEventComment posts a review comment without approval or rejection.
|
||||||
|
ReviewEventComment ReviewEvent = "COMMENT"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HeadRef identifies the source branch and latest commit of a pull request.
|
||||||
|
type HeadRef struct {
|
||||||
|
SHA string `json:"sha"`
|
||||||
|
Ref string `json:"ref"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserInfo identifies a user by login name.
|
||||||
|
type UserInfo struct {
|
||||||
|
Login string `json:"login"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequest holds relevant PR metadata.
|
||||||
|
type PullRequest struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
Head HeadRef `json:"head"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangedFile represents a file modified in a PR.
|
||||||
|
type ChangedFile struct {
|
||||||
|
Filename string `json:"filename"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContentEntry represents a file or directory entry from the contents API.
|
||||||
|
type ContentEntry struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Type string `json:"type"` // "file" or "dir"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Review represents a pull request review.
|
||||||
|
type Review struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
User UserInfo `json:"user"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Stale bool `json:"stale"`
|
||||||
|
CommitID string `json:"commit_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReviewComment represents an inline comment in a review.
|
||||||
|
// All adapters use GitHub diff-position convention:
|
||||||
|
// - Position is a 1-indexed offset from the @@ hunk line in the unified diff.
|
||||||
|
// - CommitID identifies the commit the comment is anchored to.
|
||||||
|
// It is optional; omit (empty string) for review-level comments that are
|
||||||
|
// not attached to a specific commit.
|
||||||
|
//
|
||||||
|
// Adapters are responsible for translating to/from platform-native formats
|
||||||
|
// (e.g. Gitea uses line numbers; GitHub uses diff positions natively).
|
||||||
|
type ReviewComment struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Position int `json:"position"` // diff-position: 1-indexed offset from @@ hunk line
|
||||||
|
CommitID string `json:"commit_id"`
|
||||||
|
Body string `json:"body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReviewRequest is the payload for posting a review.
|
||||||
|
type ReviewRequest struct {
|
||||||
|
// Body is the top-level review comment.
|
||||||
|
Body string `json:"body"`
|
||||||
|
// Event is the review action (approve, request changes, or comment).
|
||||||
|
Event ReviewEvent `json:"event"`
|
||||||
|
Comments []ReviewComment `json:"comments,omitempty"`
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user