first commit
This commit is contained in:
91
internal/gitea/gitea.go
Normal file
91
internal/gitea/gitea.go
Normal file
@@ -0,0 +1,91 @@
|
||||
// Package gitea provides a minimal Gitea API client for fetching PR diffs
|
||||
// and posting review comments.
|
||||
package gitea
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
const maxDiffBytes = 100 * 1024 // 100 KB — well within deepseek-coder's context
|
||||
|
||||
// Client is a minimal Gitea API client.
|
||||
type Client struct {
|
||||
BaseURL string
|
||||
Token string
|
||||
http *http.Client
|
||||
}
|
||||
|
||||
// New creates a new Gitea client.
|
||||
func New(baseURL, token string) *Client {
|
||||
return &Client{
|
||||
BaseURL: baseURL,
|
||||
Token: token,
|
||||
http: &http.Client{Timeout: 30 * time.Second},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) newRequest(method, url string, body []byte) (*http.Request, error) {
|
||||
var req *http.Request
|
||||
var err error
|
||||
if body != nil {
|
||||
req, err = http.NewRequest(method, url, bytes.NewReader(body))
|
||||
} else {
|
||||
req, err = http.NewRequest(method, url, nil)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Authorization", "token "+c.Token)
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// FetchDiff returns the unified diff for a pull request.
|
||||
// It fetches the raw .diff endpoint and caps the result at maxDiffBytes.
|
||||
func (c *Client) FetchDiff(owner, repo string, number int) (string, error) {
|
||||
url := fmt.Sprintf("%s/%s/%s/pulls/%d.diff", c.BaseURL, owner, repo, number)
|
||||
req, err := c.newRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("gitea: fetch diff %s/%s#%d: %s", owner, repo, number, resp.Status)
|
||||
}
|
||||
b, err := io.ReadAll(io.LimitReader(resp.Body, maxDiffBytes))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// PostComment posts a comment on a pull request.
|
||||
// In Gitea, pull request comments are posted via the issues API using the PR number.
|
||||
func (c *Client) PostComment(owner, repo string, number int, body string) error {
|
||||
url := fmt.Sprintf("%s/api/v1/repos/%s/%s/issues/%d/comments", c.BaseURL, owner, repo, number)
|
||||
payload, _ := json.Marshal(map[string]string{"body": body})
|
||||
req, err := c.newRequest("POST", url, payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 300 {
|
||||
return fmt.Errorf("gitea: post comment %s/%s#%d: %s", owner, repo, number, resp.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user