Add three new services covering labels, webhooks, and file content operations. LabelService handles repo and org labels without Resource embedding due to heterogeneous paths. WebhookService embeds Resource for standard CRUD on repo hooks plus action methods for test delivery and org hooks. ContentService provides file CRUD and raw file retrieval. Adds GetRaw method to Client for non-JSON responses. Co-Authored-By: Virgil <virgil@lethean.io> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
60 lines
2.1 KiB
Go
60 lines
2.1 KiB
Go
package forge
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"forge.lthn.ai/core/go-forge/types"
|
|
)
|
|
|
|
// ContentService handles file read/write operations via the Forgejo API.
|
|
// No Resource embedding — paths vary by operation.
|
|
type ContentService struct {
|
|
client *Client
|
|
}
|
|
|
|
func newContentService(c *Client) *ContentService {
|
|
return &ContentService{client: c}
|
|
}
|
|
|
|
// GetFile returns metadata and content for a file in a repository.
|
|
func (s *ContentService) GetFile(ctx context.Context, owner, repo, filepath string) (*types.ContentsResponse, error) {
|
|
path := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", owner, repo, filepath)
|
|
var out types.ContentsResponse
|
|
if err := s.client.Get(ctx, path, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
return &out, nil
|
|
}
|
|
|
|
// CreateFile creates a new file in a repository.
|
|
func (s *ContentService) CreateFile(ctx context.Context, owner, repo, filepath string, opts *types.CreateFileOptions) (*types.FileResponse, error) {
|
|
path := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", owner, repo, filepath)
|
|
var out types.FileResponse
|
|
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
return &out, nil
|
|
}
|
|
|
|
// UpdateFile updates an existing file in a repository.
|
|
func (s *ContentService) UpdateFile(ctx context.Context, owner, repo, filepath string, opts *types.UpdateFileOptions) (*types.FileResponse, error) {
|
|
path := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", owner, repo, filepath)
|
|
var out types.FileResponse
|
|
if err := s.client.Put(ctx, path, opts, &out); err != nil {
|
|
return nil, err
|
|
}
|
|
return &out, nil
|
|
}
|
|
|
|
// DeleteFile deletes a file from a repository. Uses DELETE with a JSON body.
|
|
func (s *ContentService) DeleteFile(ctx context.Context, owner, repo, filepath string, opts *types.DeleteFileOptions) error {
|
|
path := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", owner, repo, filepath)
|
|
return s.client.DeleteWithBody(ctx, path, opts)
|
|
}
|
|
|
|
// GetRawFile returns the raw file content as bytes.
|
|
func (s *ContentService) GetRawFile(ctx context.Context, owner, repo, filepath string) ([]byte, error) {
|
|
path := fmt.Sprintf("/api/v1/repos/%s/%s/raw/%s", owner, repo, filepath)
|
|
return s.client.GetRaw(ctx, path)
|
|
}
|