feat: upgrade to core v0.8.0-alpha.1, replace banned stdlib imports
Replace fmt, errors, strings, path/filepath, encoding/json with Core primitives across 23 files. Keep encoding/json for streaming NewDecoder/NewEncoder, strings for Fields/FieldsFuncSeq. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
35792507ad
commit
1ffb4bee5a
27 changed files with 218 additions and 195 deletions
28
actions.go
28
actions.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -21,82 +21,82 @@ func newActionsService(c *Client) *ActionsService {
|
|||
|
||||
// ListRepoSecrets returns all secrets for a repository.
|
||||
func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string) ([]types.Secret, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/secrets", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/secrets", owner, repo)
|
||||
return ListAll[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepoSecrets returns an iterator over all secrets for a repository.
|
||||
func (s *ActionsService) IterRepoSecrets(ctx context.Context, owner, repo string) iter.Seq2[types.Secret, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/secrets", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/secrets", owner, repo)
|
||||
return ListIter[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// CreateRepoSecret creates or updates a secret in a repository.
|
||||
// Forgejo expects a PUT with {"data": "secret-value"} body.
|
||||
func (s *ActionsService) CreateRepoSecret(ctx context.Context, owner, repo, name string, data string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/secrets/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/secrets/%s", owner, repo, name)
|
||||
body := map[string]string{"data": data}
|
||||
return s.client.Put(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// DeleteRepoSecret removes a secret from a repository.
|
||||
func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/secrets/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/secrets/%s", owner, repo, name)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListRepoVariables returns all action variables for a repository.
|
||||
func (s *ActionsService) ListRepoVariables(ctx context.Context, owner, repo string) ([]types.ActionVariable, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/variables", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/variables", owner, repo)
|
||||
return ListAll[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepoVariables returns an iterator over all action variables for a repository.
|
||||
func (s *ActionsService) IterRepoVariables(ctx context.Context, owner, repo string) iter.Seq2[types.ActionVariable, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/variables", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/variables", owner, repo)
|
||||
return ListIter[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// CreateRepoVariable creates a new action variable in a repository.
|
||||
// Forgejo expects a POST with {"value": "var-value"} body.
|
||||
func (s *ActionsService) CreateRepoVariable(ctx context.Context, owner, repo, name, value string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/variables/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/variables/%s", owner, repo, name)
|
||||
body := types.CreateVariableOption{Value: value}
|
||||
return s.client.Post(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// DeleteRepoVariable removes an action variable from a repository.
|
||||
func (s *ActionsService) DeleteRepoVariable(ctx context.Context, owner, repo, name string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/variables/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/variables/%s", owner, repo, name)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListOrgSecrets returns all secrets for an organisation.
|
||||
func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string) ([]types.Secret, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/actions/secrets", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/actions/secrets", org)
|
||||
return ListAll[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgSecrets returns an iterator over all secrets for an organisation.
|
||||
func (s *ActionsService) IterOrgSecrets(ctx context.Context, org string) iter.Seq2[types.Secret, error] {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/actions/secrets", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/actions/secrets", org)
|
||||
return ListIter[types.Secret](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// ListOrgVariables returns all action variables for an organisation.
|
||||
func (s *ActionsService) ListOrgVariables(ctx context.Context, org string) ([]types.ActionVariable, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/actions/variables", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/actions/variables", org)
|
||||
return ListAll[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgVariables returns an iterator over all action variables for an organisation.
|
||||
func (s *ActionsService) IterOrgVariables(ctx context.Context, org string) iter.Seq2[types.ActionVariable, error] {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/actions/variables", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/actions/variables", org)
|
||||
return ListIter[types.ActionVariable](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// DispatchWorkflow triggers a workflow run.
|
||||
func (s *ActionsService) DispatchWorkflow(ctx context.Context, owner, repo, workflow string, opts map[string]any) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/actions/workflows/%s/dispatches", owner, repo, workflow)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/actions/workflows/%s/dispatches", owner, repo, workflow)
|
||||
return s.client.Post(ctx, path, opts, nil)
|
||||
}
|
||||
|
|
|
|||
14
branches.go
14
branches.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -23,19 +23,19 @@ func newBranchService(c *Client) *BranchService {
|
|||
|
||||
// ListBranchProtections returns all branch protections for a repository.
|
||||
func (s *BranchService) ListBranchProtections(ctx context.Context, owner, repo string) ([]types.BranchProtection, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/branch_protections", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/branch_protections", owner, repo)
|
||||
return ListAll[types.BranchProtection](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterBranchProtections returns an iterator over all branch protections for a repository.
|
||||
func (s *BranchService) IterBranchProtections(ctx context.Context, owner, repo string) iter.Seq2[types.BranchProtection, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/branch_protections", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/branch_protections", owner, repo)
|
||||
return ListIter[types.BranchProtection](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// GetBranchProtection returns a single branch protection by name.
|
||||
func (s *BranchService) GetBranchProtection(ctx context.Context, owner, repo, name string) (*types.BranchProtection, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/branch_protections/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/branch_protections/%s", owner, repo, name)
|
||||
var out types.BranchProtection
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -45,7 +45,7 @@ func (s *BranchService) GetBranchProtection(ctx context.Context, owner, repo, na
|
|||
|
||||
// CreateBranchProtection creates a new branch protection rule.
|
||||
func (s *BranchService) CreateBranchProtection(ctx context.Context, owner, repo string, opts *types.CreateBranchProtectionOption) (*types.BranchProtection, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/branch_protections", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/branch_protections", owner, repo)
|
||||
var out types.BranchProtection
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -55,7 +55,7 @@ func (s *BranchService) CreateBranchProtection(ctx context.Context, owner, repo
|
|||
|
||||
// EditBranchProtection updates an existing branch protection rule.
|
||||
func (s *BranchService) EditBranchProtection(ctx context.Context, owner, repo, name string, opts *types.EditBranchProtectionOption) (*types.BranchProtection, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/branch_protections/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/branch_protections/%s", owner, repo, name)
|
||||
var out types.BranchProtection
|
||||
if err := s.client.Patch(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -65,6 +65,6 @@ func (s *BranchService) EditBranchProtection(ctx context.Context, owner, repo, n
|
|||
|
||||
// DeleteBranchProtection deletes a branch protection rule.
|
||||
func (s *BranchService) DeleteBranchProtection(ctx context.Context, owner, repo, name string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/branch_protections/%s", owner, repo, name)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/branch_protections/%s", owner, repo, name)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
|
|
|||
32
client.go
32
client.go
|
|
@ -4,13 +4,11 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
||||
|
|
@ -22,25 +20,25 @@ type APIError struct {
|
|||
}
|
||||
|
||||
func (e *APIError) Error() string {
|
||||
return fmt.Sprintf("forge: %s %d: %s", e.URL, e.StatusCode, e.Message)
|
||||
return core.Sprintf("forge: %s %d: %s", e.URL, e.StatusCode, e.Message)
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the error is a 404 response.
|
||||
func IsNotFound(err error) bool {
|
||||
var apiErr *APIError
|
||||
return errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusNotFound
|
||||
return core.As(err, &apiErr) && apiErr.StatusCode == http.StatusNotFound
|
||||
}
|
||||
|
||||
// IsForbidden returns true if the error is a 403 response.
|
||||
func IsForbidden(err error) bool {
|
||||
var apiErr *APIError
|
||||
return errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusForbidden
|
||||
return core.As(err, &apiErr) && apiErr.StatusCode == http.StatusForbidden
|
||||
}
|
||||
|
||||
// IsConflict returns true if the error is a 409 response.
|
||||
func IsConflict(err error) bool {
|
||||
var apiErr *APIError
|
||||
return errors.As(err, &apiErr) && apiErr.StatusCode == http.StatusConflict
|
||||
return core.As(err, &apiErr) && apiErr.StatusCode == http.StatusConflict
|
||||
}
|
||||
|
||||
// Option configures the Client.
|
||||
|
|
@ -80,7 +78,7 @@ func (c *Client) RateLimit() RateLimit {
|
|||
// NewClient creates a new Forgejo API client.
|
||||
func NewClient(url, token string, opts ...Option) *Client {
|
||||
c := &Client{
|
||||
baseURL: strings.TrimRight(url, "/"),
|
||||
baseURL: core.TrimSuffix(url, "/"),
|
||||
token: token,
|
||||
httpClient: &http.Client{
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
|
|
@ -139,11 +137,11 @@ func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, er
|
|||
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
data, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, coreerr.E("Client.PostRaw", "forge: marshal body", err)
|
||||
r := core.JSONMarshal(body)
|
||||
if !r.OK {
|
||||
return nil, coreerr.E("Client.PostRaw", "forge: marshal body", nil)
|
||||
}
|
||||
bodyReader = bytes.NewReader(data)
|
||||
bodyReader = bytes.NewReader(r.Value.([]byte))
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bodyReader)
|
||||
|
|
@ -218,11 +216,11 @@ func (c *Client) doJSON(ctx context.Context, method, path string, body, out any)
|
|||
|
||||
var bodyReader io.Reader
|
||||
if body != nil {
|
||||
data, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, coreerr.E("Client.doJSON", "forge: marshal body", err)
|
||||
r := core.JSONMarshal(body)
|
||||
if !r.OK {
|
||||
return nil, coreerr.E("Client.doJSON", "forge: marshal body", nil)
|
||||
}
|
||||
bodyReader = bytes.NewReader(data)
|
||||
bodyReader = bytes.NewReader(r.Value.([]byte))
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
|
||||
|
|
@ -267,7 +265,7 @@ func (c *Client) parseError(resp *http.Response, path string) error {
|
|||
|
||||
// Read a bit of the body to see if we can get a message
|
||||
data, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))
|
||||
_ = json.Unmarshal(data, &errBody)
|
||||
core.JSONUnmarshal(data, &errBody)
|
||||
|
||||
msg := errBody.Message
|
||||
if msg == "" && len(data) > 0 {
|
||||
|
|
|
|||
|
|
@ -3,10 +3,11 @@ package forge
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
||||
func TestClient_Good_Get(t *testing.T) {
|
||||
|
|
@ -91,7 +92,7 @@ func TestClient_Bad_ServerError(t *testing.T) {
|
|||
t.Fatal("expected error")
|
||||
}
|
||||
var apiErr *APIError
|
||||
if !errors.As(err, &apiErr) {
|
||||
if !core.As(err, &apiErr) {
|
||||
t.Fatalf("expected APIError, got %T", err)
|
||||
}
|
||||
if apiErr.StatusCode != 500 {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"maps"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreio "dappco.re/go/core/io"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
|
@ -110,7 +110,7 @@ func classifyType(name string) string {
|
|||
bestKey := ""
|
||||
bestGroup := ""
|
||||
for key, group := range typeGrouping {
|
||||
if strings.HasPrefix(name, key) && len(key) > len(bestKey) {
|
||||
if core.HasPrefix(name, key) && len(key) > len(bestKey) {
|
||||
bestKey = key
|
||||
bestGroup = group
|
||||
}
|
||||
|
|
@ -122,10 +122,10 @@ func classifyType(name string) string {
|
|||
// Strip CRUD prefixes and Option suffix, then retry.
|
||||
base := name
|
||||
for _, prefix := range []string{"Create", "Edit", "Delete", "Update", "Add", "Submit", "Replace", "Set", "Transfer"} {
|
||||
base = strings.TrimPrefix(base, prefix)
|
||||
base = core.TrimPrefix(base, prefix)
|
||||
}
|
||||
base = strings.TrimSuffix(base, "Option")
|
||||
base = strings.TrimSuffix(base, "Options")
|
||||
base = core.TrimSuffix(base, "Option")
|
||||
base = core.TrimSuffix(base, "Options")
|
||||
|
||||
if base != name && base != "" {
|
||||
if group, ok := typeGrouping[base]; ok {
|
||||
|
|
@ -135,7 +135,7 @@ func classifyType(name string) string {
|
|||
bestKey = ""
|
||||
bestGroup = ""
|
||||
for key, group := range typeGrouping {
|
||||
if strings.HasPrefix(base, key) && len(key) > len(bestKey) {
|
||||
if core.HasPrefix(base, key) && len(key) > len(bestKey) {
|
||||
bestKey = key
|
||||
bestGroup = group
|
||||
}
|
||||
|
|
@ -151,7 +151,7 @@ func classifyType(name string) string {
|
|||
// sanitiseLine collapses a multi-line string into a single line,
|
||||
// replacing newlines and consecutive whitespace with a single space.
|
||||
func sanitiseLine(s string) string {
|
||||
return strings.Join(strings.Fields(s), " ")
|
||||
return core.Join(" ", strings.Fields(s)...)
|
||||
}
|
||||
|
||||
// enumConstName generates a Go constant name for an enum value.
|
||||
|
|
@ -219,7 +219,13 @@ func Generate(types map[string]*GoType, pairs []CRUDPair, outDir string) error {
|
|||
// Sort types within each group for deterministic output.
|
||||
for file := range groups {
|
||||
slices.SortFunc(groups[file], func(a, b *GoType) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
if a.Name < b.Name {
|
||||
return -1
|
||||
}
|
||||
if a.Name > b.Name {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +234,7 @@ func Generate(types map[string]*GoType, pairs []CRUDPair, outDir string) error {
|
|||
slices.Sort(fileNames)
|
||||
|
||||
for _, file := range fileNames {
|
||||
outPath := filepath.Join(outDir, file+".go")
|
||||
outPath := core.JoinPath(outDir, file+".go")
|
||||
if err := writeFile(outPath, groups[file]); err != nil {
|
||||
return coreerr.E("Generate", "write "+outPath, err)
|
||||
}
|
||||
|
|
@ -241,7 +247,7 @@ func Generate(types map[string]*GoType, pairs []CRUDPair, outDir string) error {
|
|||
func writeFile(path string, types []*GoType) error {
|
||||
needTime := slices.ContainsFunc(types, func(gt *GoType) bool {
|
||||
return slices.ContainsFunc(gt.Fields, func(f GoField) bool {
|
||||
return strings.Contains(f.GoType, "time.Time")
|
||||
return core.Contains(f.GoType, "time.Time")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ package main
|
|||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreio "dappco.re/go/core/io"
|
||||
)
|
||||
|
||||
|
|
@ -26,7 +25,7 @@ func TestGenerate_Good_CreatesFiles(t *testing.T) {
|
|||
entries, _ := os.ReadDir(outDir)
|
||||
goFiles := 0
|
||||
for _, e := range entries {
|
||||
if strings.HasSuffix(e.Name(), ".go") {
|
||||
if core.HasSuffix(e.Name(), ".go") {
|
||||
goFiles++
|
||||
}
|
||||
}
|
||||
|
|
@ -52,8 +51,8 @@ func TestGenerate_Good_ValidGoSyntax(t *testing.T) {
|
|||
entries, _ := os.ReadDir(outDir)
|
||||
var content string
|
||||
for _, e := range entries {
|
||||
if strings.HasSuffix(e.Name(), ".go") {
|
||||
content, err = coreio.Local.Read(filepath.Join(outDir, e.Name()))
|
||||
if core.HasSuffix(e.Name(), ".go") {
|
||||
content, err = coreio.Local.Read(core.JoinPath(outDir, e.Name()))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
|
@ -62,10 +61,10 @@ func TestGenerate_Good_ValidGoSyntax(t *testing.T) {
|
|||
if err != nil || content == "" {
|
||||
t.Fatal("could not read any generated file")
|
||||
}
|
||||
if !strings.Contains(content, "package types") {
|
||||
if !core.Contains(content, "package types") {
|
||||
t.Error("missing package declaration")
|
||||
}
|
||||
if !strings.Contains(content, "// Code generated") {
|
||||
if !core.Contains(content, "// Code generated") {
|
||||
t.Error("missing generated comment")
|
||||
}
|
||||
}
|
||||
|
|
@ -87,8 +86,8 @@ func TestGenerate_Good_RepositoryType(t *testing.T) {
|
|||
var content string
|
||||
entries, _ := os.ReadDir(outDir)
|
||||
for _, e := range entries {
|
||||
data, _ := coreio.Local.Read(filepath.Join(outDir, e.Name()))
|
||||
if strings.Contains(data, "type Repository struct") {
|
||||
data, _ := coreio.Local.Read(core.JoinPath(outDir, e.Name()))
|
||||
if core.Contains(data, "type Repository struct") {
|
||||
content = data
|
||||
break
|
||||
}
|
||||
|
|
@ -107,7 +106,7 @@ func TestGenerate_Good_RepositoryType(t *testing.T) {
|
|||
"`json:\"private,omitempty\"`",
|
||||
}
|
||||
for _, check := range checks {
|
||||
if !strings.Contains(content, check) {
|
||||
if !core.Contains(content, check) {
|
||||
t.Errorf("missing field with tag %s", check)
|
||||
}
|
||||
}
|
||||
|
|
@ -129,8 +128,8 @@ func TestGenerate_Good_TimeImport(t *testing.T) {
|
|||
|
||||
entries, _ := os.ReadDir(outDir)
|
||||
for _, e := range entries {
|
||||
content, _ := coreio.Local.Read(filepath.Join(outDir, e.Name()))
|
||||
if strings.Contains(content, "time.Time") && !strings.Contains(content, "\"time\"") {
|
||||
content, _ := coreio.Local.Read(core.JoinPath(outDir, e.Name()))
|
||||
if core.Contains(content, "time.Time") && !core.Contains(content, "\"time\"") {
|
||||
t.Errorf("file %s uses time.Time but doesn't import time", e.Name())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
|
@ -13,18 +14,18 @@ func main() {
|
|||
|
||||
spec, err := LoadSpec(*specPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
core.Print(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
types := ExtractTypes(spec)
|
||||
pairs := DetectCRUDPairs(spec)
|
||||
|
||||
fmt.Printf("Loaded %d types, %d CRUD pairs\n", len(types), len(pairs))
|
||||
fmt.Printf("Output dir: %s\n", *outDir)
|
||||
core.Print(os.Stdout, "Loaded %d types, %d CRUD pairs\n", len(types), len(pairs))
|
||||
core.Print(os.Stdout, "Output dir: %s\n", *outDir)
|
||||
|
||||
if err := Generate(types, pairs, *outDir); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
core.Print(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreio "dappco.re/go/core/io"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
|
@ -77,8 +76,9 @@ func LoadSpec(path string) (*Spec, error) {
|
|||
return nil, coreerr.E("LoadSpec", "read spec", err)
|
||||
}
|
||||
var spec Spec
|
||||
if err := json.Unmarshal([]byte(content), &spec); err != nil {
|
||||
return nil, coreerr.E("LoadSpec", "parse spec", err)
|
||||
r := core.JSONUnmarshal([]byte(content), &spec)
|
||||
if !r.OK {
|
||||
return nil, coreerr.E("LoadSpec", "parse spec", nil)
|
||||
}
|
||||
return &spec, nil
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ func ExtractTypes(spec *Spec) map[string]*GoType {
|
|||
if len(def.Enum) > 0 {
|
||||
gt.IsEnum = true
|
||||
for _, v := range def.Enum {
|
||||
gt.EnumValues = append(gt.EnumValues, fmt.Sprintf("%v", v))
|
||||
gt.EnumValues = append(gt.EnumValues, core.Sprintf("%v", v))
|
||||
}
|
||||
slices.Sort(gt.EnumValues)
|
||||
result[name] = gt
|
||||
|
|
@ -116,7 +116,13 @@ func ExtractTypes(spec *Spec) map[string]*GoType {
|
|||
gt.Fields = append(gt.Fields, gf)
|
||||
}
|
||||
slices.SortFunc(gt.Fields, func(a, b GoField) int {
|
||||
return strings.Compare(a.GoName, b.GoName)
|
||||
if a.GoName < b.GoName {
|
||||
return -1
|
||||
}
|
||||
if a.GoName > b.GoName {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
result[name] = gt
|
||||
}
|
||||
|
|
@ -128,11 +134,11 @@ func ExtractTypes(spec *Spec) map[string]*GoType {
|
|||
func DetectCRUDPairs(spec *Spec) []CRUDPair {
|
||||
var pairs []CRUDPair
|
||||
for name := range spec.Definitions {
|
||||
if !strings.HasPrefix(name, "Create") || !strings.HasSuffix(name, "Option") {
|
||||
if !core.HasPrefix(name, "Create") || !core.HasSuffix(name, "Option") {
|
||||
continue
|
||||
}
|
||||
inner := strings.TrimPrefix(name, "Create")
|
||||
inner = strings.TrimSuffix(inner, "Option")
|
||||
inner := core.TrimPrefix(name, "Create")
|
||||
inner = core.TrimSuffix(inner, "Option")
|
||||
editName := "Edit" + inner + "Option"
|
||||
pair := CRUDPair{Base: inner, Create: name}
|
||||
if _, ok := spec.Definitions[editName]; ok {
|
||||
|
|
@ -141,7 +147,13 @@ func DetectCRUDPairs(spec *Spec) []CRUDPair {
|
|||
pairs = append(pairs, pair)
|
||||
}
|
||||
slices.SortFunc(pairs, func(a, b CRUDPair) int {
|
||||
return strings.Compare(a.Base, b.Base)
|
||||
if a.Base < b.Base {
|
||||
return -1
|
||||
}
|
||||
if a.Base > b.Base {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
return pairs
|
||||
}
|
||||
|
|
@ -149,7 +161,7 @@ func DetectCRUDPairs(spec *Spec) []CRUDPair {
|
|||
// resolveGoType maps a swagger schema property to a Go type string.
|
||||
func resolveGoType(prop SchemaProperty) string {
|
||||
if prop.Ref != "" {
|
||||
parts := strings.Split(prop.Ref, "/")
|
||||
parts := core.Split(prop.Ref, "/")
|
||||
return "*" + parts[len(parts)-1]
|
||||
}
|
||||
switch prop.Type {
|
||||
|
|
@ -202,13 +214,13 @@ func pascalCase(s string) string {
|
|||
if len(p) == 0 {
|
||||
continue
|
||||
}
|
||||
upper := strings.ToUpper(p)
|
||||
upper := core.Upper(p)
|
||||
switch upper {
|
||||
case "ID", "URL", "HTML", "SSH", "HTTP", "HTTPS", "API", "URI", "GPG", "IP", "CSS", "JS":
|
||||
parts = append(parts, upper)
|
||||
default:
|
||||
parts = append(parts, strings.ToUpper(p[:1])+p[1:])
|
||||
parts = append(parts, core.Upper(p[:1])+p[1:])
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, "")
|
||||
return core.Join("", parts...)
|
||||
}
|
||||
|
|
|
|||
10
commits.go
10
commits.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ func (s *CommitService) Get(ctx context.Context, params Params) (*types.Commit,
|
|||
|
||||
// GetCombinedStatus returns the combined status for a given ref (branch, tag, or SHA).
|
||||
func (s *CommitService) GetCombinedStatus(ctx context.Context, owner, repo, ref string) (*types.CombinedStatus, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s", owner, repo, ref)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/statuses/%s", owner, repo, ref)
|
||||
var out types.CombinedStatus
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -61,7 +61,7 @@ func (s *CommitService) GetCombinedStatus(ctx context.Context, owner, repo, ref
|
|||
|
||||
// ListStatuses returns all commit statuses for a given ref.
|
||||
func (s *CommitService) ListStatuses(ctx context.Context, owner, repo, ref string) ([]types.CommitStatus, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/commits/%s/statuses", owner, repo, ref)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/commits/%s/statuses", owner, repo, ref)
|
||||
var out []types.CommitStatus
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -71,7 +71,7 @@ func (s *CommitService) ListStatuses(ctx context.Context, owner, repo, ref strin
|
|||
|
||||
// CreateStatus creates a new commit status for the given SHA.
|
||||
func (s *CommitService) CreateStatus(ctx context.Context, owner, repo, sha string, opts *types.CreateStatusOption) (*types.CommitStatus, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s", owner, repo, sha)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/statuses/%s", owner, repo, sha)
|
||||
var out types.CommitStatus
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -81,7 +81,7 @@ func (s *CommitService) CreateStatus(ctx context.Context, owner, repo, sha strin
|
|||
|
||||
// GetNote returns the git note for a given commit SHA.
|
||||
func (s *CommitService) GetNote(ctx context.Context, owner, repo, sha string) (*types.Note, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/git/notes/%s", owner, repo, sha)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/git/notes/%s", owner, repo, sha)
|
||||
var out types.Note
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
12
contents.go
12
contents.go
|
|
@ -2,8 +2,8 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ func newContentService(c *Client) *ContentService {
|
|||
|
||||
// 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)
|
||||
path := core.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
|
||||
|
|
@ -29,7 +29,7 @@ func (s *ContentService) GetFile(ctx context.Context, owner, repo, filepath stri
|
|||
|
||||
// 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)
|
||||
path := core.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
|
||||
|
|
@ -39,7 +39,7 @@ func (s *ContentService) CreateFile(ctx context.Context, owner, repo, filepath s
|
|||
|
||||
// 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)
|
||||
path := core.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
|
||||
|
|
@ -49,12 +49,12 @@ func (s *ContentService) UpdateFile(ctx context.Context, owner, repo, filepath s
|
|||
|
||||
// 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)
|
||||
path := core.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)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/raw/%s", owner, repo, filepath)
|
||||
return s.client.GetRaw(ctx, path)
|
||||
}
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -3,6 +3,7 @@ module dappco.re/go/core/forge
|
|||
go 1.26.0
|
||||
|
||||
require (
|
||||
dappco.re/go/core v0.8.0-alpha.1
|
||||
dappco.re/go/core/io v0.2.0
|
||||
dappco.re/go/core/log v0.1.0
|
||||
)
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -1,3 +1,5 @@
|
|||
dappco.re/go/core v0.8.0-alpha.1 h1:gj7+Scv+L63Z7wMxbJYHhaRFkHJo2u4MMPuUSv/Dhtk=
|
||||
dappco.re/go/core v0.8.0-alpha.1/go.mod h1:f2/tBZ3+3IqDrg2F5F598llv0nmb/4gJVCFzM5geE4A=
|
||||
dappco.re/go/core/io v0.2.0 h1:zuudgIiTsQQ5ipVt97saWdGLROovbEB/zdVyy9/l+I4=
|
||||
dappco.re/go/core/io v0.2.0/go.mod h1:1QnQV6X9LNgFKfm8SkOtR9LLaj3bDcsOIeJOOyjbL5E=
|
||||
dappco.re/go/core/log v0.1.0 h1:pa71Vq2TD2aoEUQWFKwNcaJ3GBY8HbaNGqtE688Unyc=
|
||||
|
|
|
|||
26
issues.go
26
issues.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -23,77 +23,77 @@ func newIssueService(c *Client) *IssueService {
|
|||
|
||||
// Pin pins an issue.
|
||||
func (s *IssueService) Pin(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", owner, repo, index)
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// Unpin unpins an issue.
|
||||
func (s *IssueService) Unpin(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", owner, repo, index)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// SetDeadline sets or updates the deadline on an issue.
|
||||
func (s *IssueService) SetDeadline(ctx context.Context, owner, repo string, index int64, deadline string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/deadline", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/deadline", owner, repo, index)
|
||||
body := map[string]string{"due_date": deadline}
|
||||
return s.client.Post(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// AddReaction adds a reaction to an issue.
|
||||
func (s *IssueService) AddReaction(ctx context.Context, owner, repo string, index int64, reaction string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions", owner, repo, index)
|
||||
body := map[string]string{"content": reaction}
|
||||
return s.client.Post(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// DeleteReaction removes a reaction from an issue.
|
||||
func (s *IssueService) DeleteReaction(ctx context.Context, owner, repo string, index int64, reaction string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions", owner, repo, index)
|
||||
body := map[string]string{"content": reaction}
|
||||
return s.client.DeleteWithBody(ctx, path, body)
|
||||
}
|
||||
|
||||
// StartStopwatch starts the stopwatch on an issue.
|
||||
func (s *IssueService) StartStopwatch(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/stopwatch/start", owner, repo, index)
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// StopStopwatch stops the stopwatch on an issue.
|
||||
func (s *IssueService) StopStopwatch(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/stopwatch/stop", owner, repo, index)
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// AddLabels adds labels to an issue.
|
||||
func (s *IssueService) AddLabels(ctx context.Context, owner, repo string, index int64, labelIDs []int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels", owner, repo, index)
|
||||
body := types.IssueLabelsOption{Labels: toAnySlice(labelIDs)}
|
||||
return s.client.Post(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// RemoveLabel removes a single label from an issue.
|
||||
func (s *IssueService) RemoveLabel(ctx context.Context, owner, repo string, index int64, labelID int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, labelID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels/%d", owner, repo, index, labelID)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListComments returns all comments on an issue.
|
||||
func (s *IssueService) ListComments(ctx context.Context, owner, repo string, index int64) ([]types.Comment, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, index)
|
||||
return ListAll[types.Comment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterComments returns an iterator over all comments on an issue.
|
||||
func (s *IssueService) IterComments(ctx context.Context, owner, repo string, index int64) iter.Seq2[types.Comment, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, index)
|
||||
return ListIter[types.Comment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// CreateComment creates a comment on an issue.
|
||||
func (s *IssueService) CreateComment(ctx context.Context, owner, repo string, index int64, body string) (*types.Comment, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", owner, repo, index)
|
||||
opts := types.CreateIssueCommentOption{Body: body}
|
||||
var out types.Comment
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
|
|
|
|||
20
labels.go
20
labels.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -20,19 +20,19 @@ func newLabelService(c *Client) *LabelService {
|
|||
|
||||
// ListRepoLabels returns all labels for a repository.
|
||||
func (s *LabelService) ListRepoLabels(ctx context.Context, owner, repo string) ([]types.Label, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/labels", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/labels", owner, repo)
|
||||
return ListAll[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepoLabels returns an iterator over all labels for a repository.
|
||||
func (s *LabelService) IterRepoLabels(ctx context.Context, owner, repo string) iter.Seq2[types.Label, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/labels", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/labels", owner, repo)
|
||||
return ListIter[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// GetRepoLabel returns a single label by ID.
|
||||
func (s *LabelService) GetRepoLabel(ctx context.Context, owner, repo string, id int64) (*types.Label, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner, repo, id)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner, repo, id)
|
||||
var out types.Label
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -42,7 +42,7 @@ func (s *LabelService) GetRepoLabel(ctx context.Context, owner, repo string, id
|
|||
|
||||
// CreateRepoLabel creates a new label in a repository.
|
||||
func (s *LabelService) CreateRepoLabel(ctx context.Context, owner, repo string, opts *types.CreateLabelOption) (*types.Label, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/labels", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/labels", owner, repo)
|
||||
var out types.Label
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -52,7 +52,7 @@ func (s *LabelService) CreateRepoLabel(ctx context.Context, owner, repo string,
|
|||
|
||||
// EditRepoLabel updates an existing label in a repository.
|
||||
func (s *LabelService) EditRepoLabel(ctx context.Context, owner, repo string, id int64, opts *types.EditLabelOption) (*types.Label, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner, repo, id)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner, repo, id)
|
||||
var out types.Label
|
||||
if err := s.client.Patch(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -62,25 +62,25 @@ func (s *LabelService) EditRepoLabel(ctx context.Context, owner, repo string, id
|
|||
|
||||
// DeleteRepoLabel deletes a label from a repository.
|
||||
func (s *LabelService) DeleteRepoLabel(ctx context.Context, owner, repo string, id int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner, repo, id)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner, repo, id)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListOrgLabels returns all labels for an organisation.
|
||||
func (s *LabelService) ListOrgLabels(ctx context.Context, org string) ([]types.Label, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/labels", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/labels", org)
|
||||
return ListAll[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgLabels returns an iterator over all labels for an organisation.
|
||||
func (s *LabelService) IterOrgLabels(ctx context.Context, org string) iter.Seq2[types.Label, error] {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/labels", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/labels", org)
|
||||
return ListIter[types.Label](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// CreateOrgLabel creates a new label in an organisation.
|
||||
func (s *LabelService) CreateOrgLabel(ctx context.Context, org string, opts *types.CreateLabelOption) (*types.Label, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/labels", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/labels", org)
|
||||
var out types.Label
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -18,13 +18,13 @@ func newMilestoneService(c *Client) *MilestoneService {
|
|||
|
||||
// ListAll returns all milestones for a repository.
|
||||
func (s *MilestoneService) ListAll(ctx context.Context, params Params) ([]types.Milestone, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/milestones", params["owner"], params["repo"])
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/milestones", params["owner"], params["repo"])
|
||||
return ListAll[types.Milestone](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Get returns a single milestone by ID.
|
||||
func (s *MilestoneService) Get(ctx context.Context, owner, repo string, id int64) (*types.Milestone, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d", owner, repo, id)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/milestones/%d", owner, repo, id)
|
||||
var out types.Milestone
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -34,7 +34,7 @@ func (s *MilestoneService) Get(ctx context.Context, owner, repo string, id int64
|
|||
|
||||
// Create creates a new milestone.
|
||||
func (s *MilestoneService) Create(ctx context.Context, owner, repo string, opts *types.CreateMilestoneOption) (*types.Milestone, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/milestones", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/milestones", owner, repo)
|
||||
var out types.Milestone
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
6
misc.go
6
misc.go
|
|
@ -2,8 +2,8 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ func (s *MiscService) ListLicenses(ctx context.Context) ([]types.LicensesTemplat
|
|||
|
||||
// GetLicense returns a single licence template by name.
|
||||
func (s *MiscService) GetLicense(ctx context.Context, name string) (*types.LicenseTemplateInfo, error) {
|
||||
path := fmt.Sprintf("/api/v1/licenses/%s", name)
|
||||
path := core.Sprintf("/api/v1/licenses/%s", name)
|
||||
var out types.LicenseTemplateInfo
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -60,7 +60,7 @@ func (s *MiscService) ListGitignoreTemplates(ctx context.Context) ([]string, err
|
|||
|
||||
// GetGitignoreTemplate returns a single gitignore template by name.
|
||||
func (s *MiscService) GetGitignoreTemplate(ctx context.Context, name string) (*types.GitignoreTemplateInfo, error) {
|
||||
path := fmt.Sprintf("/api/v1/gitignore/templates/%s", name)
|
||||
path := core.Sprintf("/api/v1/gitignore/templates/%s", name)
|
||||
var out types.GitignoreTemplateInfo
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -30,13 +30,13 @@ func (s *NotificationService) Iter(ctx context.Context) iter.Seq2[types.Notifica
|
|||
|
||||
// ListRepo returns all notifications for a specific repository.
|
||||
func (s *NotificationService) ListRepo(ctx context.Context, owner, repo string) ([]types.NotificationThread, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/notifications", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/notifications", owner, repo)
|
||||
return ListAll[types.NotificationThread](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepo returns an iterator over all notifications for a specific repository.
|
||||
func (s *NotificationService) IterRepo(ctx context.Context, owner, repo string) iter.Seq2[types.NotificationThread, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/notifications", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/notifications", owner, repo)
|
||||
return ListIter[types.NotificationThread](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ func (s *NotificationService) MarkRead(ctx context.Context) error {
|
|||
|
||||
// GetThread returns a single notification thread by ID.
|
||||
func (s *NotificationService) GetThread(ctx context.Context, id int64) (*types.NotificationThread, error) {
|
||||
path := fmt.Sprintf("/api/v1/notifications/threads/%d", id)
|
||||
path := core.Sprintf("/api/v1/notifications/threads/%d", id)
|
||||
var out types.NotificationThread
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -57,6 +57,6 @@ func (s *NotificationService) GetThread(ctx context.Context, id int64) (*types.N
|
|||
|
||||
// MarkThreadRead marks a single notification thread as read.
|
||||
func (s *NotificationService) MarkThreadRead(ctx context.Context, id int64) error {
|
||||
path := fmt.Sprintf("/api/v1/notifications/threads/%d", id)
|
||||
path := core.Sprintf("/api/v1/notifications/threads/%d", id)
|
||||
return s.client.Patch(ctx, path, nil, nil)
|
||||
}
|
||||
|
|
|
|||
14
orgs.go
14
orgs.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -23,37 +23,37 @@ func newOrgService(c *Client) *OrgService {
|
|||
|
||||
// ListMembers returns all members of an organisation.
|
||||
func (s *OrgService) ListMembers(ctx context.Context, org string) ([]types.User, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/members", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/members", org)
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterMembers returns an iterator over all members of an organisation.
|
||||
func (s *OrgService) IterMembers(ctx context.Context, org string) iter.Seq2[types.User, error] {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/members", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/members", org)
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// AddMember adds a user to an organisation.
|
||||
func (s *OrgService) AddMember(ctx context.Context, org, username string) error {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/members/%s", org, username)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/members/%s", org, username)
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// RemoveMember removes a user from an organisation.
|
||||
func (s *OrgService) RemoveMember(ctx context.Context, org, username string) error {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/members/%s", org, username)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/members/%s", org, username)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListUserOrgs returns all organisations for a user.
|
||||
func (s *OrgService) ListUserOrgs(ctx context.Context, username string) ([]types.Organization, error) {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/orgs", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/orgs", username)
|
||||
return ListAll[types.Organization](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterUserOrgs returns an iterator over all organisations for a user.
|
||||
func (s *OrgService) IterUserOrgs(ctx context.Context, username string) iter.Seq2[types.Organization, error] {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/orgs", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/orgs", username)
|
||||
return ListIter[types.Organization](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
|
|
|
|||
14
packages.go
14
packages.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -20,19 +20,19 @@ func newPackageService(c *Client) *PackageService {
|
|||
|
||||
// List returns all packages for a given owner.
|
||||
func (s *PackageService) List(ctx context.Context, owner string) ([]types.Package, error) {
|
||||
path := fmt.Sprintf("/api/v1/packages/%s", owner)
|
||||
path := core.Sprintf("/api/v1/packages/%s", owner)
|
||||
return ListAll[types.Package](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Iter returns an iterator over all packages for a given owner.
|
||||
func (s *PackageService) Iter(ctx context.Context, owner string) iter.Seq2[types.Package, error] {
|
||||
path := fmt.Sprintf("/api/v1/packages/%s", owner)
|
||||
path := core.Sprintf("/api/v1/packages/%s", owner)
|
||||
return ListIter[types.Package](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Get returns a single package by owner, type, name, and version.
|
||||
func (s *PackageService) Get(ctx context.Context, owner, pkgType, name, version string) (*types.Package, error) {
|
||||
path := fmt.Sprintf("/api/v1/packages/%s/%s/%s/%s", owner, pkgType, name, version)
|
||||
path := core.Sprintf("/api/v1/packages/%s/%s/%s/%s", owner, pkgType, name, version)
|
||||
var out types.Package
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -42,18 +42,18 @@ func (s *PackageService) Get(ctx context.Context, owner, pkgType, name, version
|
|||
|
||||
// Delete removes a package by owner, type, name, and version.
|
||||
func (s *PackageService) Delete(ctx context.Context, owner, pkgType, name, version string) error {
|
||||
path := fmt.Sprintf("/api/v1/packages/%s/%s/%s/%s", owner, pkgType, name, version)
|
||||
path := core.Sprintf("/api/v1/packages/%s/%s/%s/%s", owner, pkgType, name, version)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListFiles returns all files for a specific package version.
|
||||
func (s *PackageService) ListFiles(ctx context.Context, owner, pkgType, name, version string) ([]types.PackageFile, error) {
|
||||
path := fmt.Sprintf("/api/v1/packages/%s/%s/%s/%s/files", owner, pkgType, name, version)
|
||||
path := core.Sprintf("/api/v1/packages/%s/%s/%s/%s/files", owner, pkgType, name, version)
|
||||
return ListAll[types.PackageFile](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterFiles returns an iterator over all files for a specific package version.
|
||||
func (s *PackageService) IterFiles(ctx context.Context, owner, pkgType, name, version string) iter.Seq2[types.PackageFile, error] {
|
||||
path := fmt.Sprintf("/api/v1/packages/%s/%s/%s/%s/files", owner, pkgType, name, version)
|
||||
path := core.Sprintf("/api/v1/packages/%s/%s/%s/%s/files", owner, pkgType, name, version)
|
||||
return ListIter[types.PackageFile](ctx, s.client, path, nil)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ package forge
|
|||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
||||
// Params maps path variable names to values.
|
||||
|
|
@ -12,7 +13,7 @@ type Params map[string]string
|
|||
// ResolvePath substitutes {placeholders} in path with values from params.
|
||||
func ResolvePath(path string, params Params) string {
|
||||
for k, v := range params {
|
||||
path = strings.ReplaceAll(path, "{"+k+"}", url.PathEscape(v))
|
||||
path = core.Replace(path, "{"+k+"}", url.PathEscape(v))
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
|
|
|||
16
pulls.go
16
pulls.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -23,32 +23,32 @@ func newPullService(c *Client) *PullService {
|
|||
|
||||
// Merge merges a pull request. Method is one of "merge", "rebase", "rebase-merge", "squash", "fast-forward-only", "manually-merged".
|
||||
func (s *PullService) Merge(ctx context.Context, owner, repo string, index int64, method string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner, repo, index)
|
||||
body := map[string]string{"Do": method}
|
||||
return s.client.Post(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// Update updates a pull request branch with the base branch.
|
||||
func (s *PullService) Update(ctx context.Context, owner, repo string, index int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/update", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/update", owner, repo, index)
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// ListReviews returns all reviews on a pull request.
|
||||
func (s *PullService) ListReviews(ctx context.Context, owner, repo string, index int64) ([]types.PullReview, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", owner, repo, index)
|
||||
return ListAll[types.PullReview](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterReviews returns an iterator over all reviews on a pull request.
|
||||
func (s *PullService) IterReviews(ctx context.Context, owner, repo string, index int64) iter.Seq2[types.PullReview, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", owner, repo, index)
|
||||
return ListIter[types.PullReview](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// SubmitReview creates a new review on a pull request.
|
||||
func (s *PullService) SubmitReview(ctx context.Context, owner, repo string, index int64, review map[string]any) (*types.PullReview, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", owner, repo, index)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", owner, repo, index)
|
||||
var out types.PullReview
|
||||
if err := s.client.Post(ctx, path, review, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -58,13 +58,13 @@ func (s *PullService) SubmitReview(ctx context.Context, owner, repo string, inde
|
|||
|
||||
// DismissReview dismisses a pull request review.
|
||||
func (s *PullService) DismissReview(ctx context.Context, owner, repo string, index, reviewID int64, msg string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals", owner, repo, index, reviewID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals", owner, repo, index, reviewID)
|
||||
body := map[string]string{"message": msg}
|
||||
return s.client.Post(ctx, path, body, nil)
|
||||
}
|
||||
|
||||
// UndismissReview undismisses a pull request review.
|
||||
func (s *PullService) UndismissReview(ctx context.Context, owner, repo string, index, reviewID int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/undismissals", owner, repo, index, reviewID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/undismissals", owner, repo, index, reviewID)
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
|
|
|||
14
releases.go
14
releases.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ func newReleaseService(c *Client) *ReleaseService {
|
|||
|
||||
// GetByTag returns a release by its tag name.
|
||||
func (s *ReleaseService) GetByTag(ctx context.Context, owner, repo, tag string) (*types.Release, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner, repo, tag)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner, repo, tag)
|
||||
var out types.Release
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -33,25 +33,25 @@ func (s *ReleaseService) GetByTag(ctx context.Context, owner, repo, tag string)
|
|||
|
||||
// DeleteByTag deletes a release by its tag name.
|
||||
func (s *ReleaseService) DeleteByTag(ctx context.Context, owner, repo, tag string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner, repo, tag)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner, repo, tag)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListAssets returns all assets for a release.
|
||||
func (s *ReleaseService) ListAssets(ctx context.Context, owner, repo string, releaseID int64) ([]types.Attachment, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets", owner, repo, releaseID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets", owner, repo, releaseID)
|
||||
return ListAll[types.Attachment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterAssets returns an iterator over all assets for a release.
|
||||
func (s *ReleaseService) IterAssets(ctx context.Context, owner, repo string, releaseID int64) iter.Seq2[types.Attachment, error] {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets", owner, repo, releaseID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets", owner, repo, releaseID)
|
||||
return ListIter[types.Attachment](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// GetAsset returns a single asset for a release.
|
||||
func (s *ReleaseService) GetAsset(ctx context.Context, owner, repo string, releaseID, assetID int64) (*types.Attachment, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets/%d", owner, repo, releaseID, assetID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets/%d", owner, repo, releaseID, assetID)
|
||||
var out types.Attachment
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -61,6 +61,6 @@ func (s *ReleaseService) GetAsset(ctx context.Context, owner, repo string, relea
|
|||
|
||||
// DeleteAsset deletes a single asset from a release.
|
||||
func (s *ReleaseService) DeleteAsset(ctx context.Context, owner, repo string, releaseID, assetID int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets/%d", owner, repo, releaseID, assetID)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets/%d", owner, repo, releaseID, assetID)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
|
|
|||
12
resource.go
12
resource.go
|
|
@ -3,7 +3,8 @@ package forge
|
|||
import (
|
||||
"context"
|
||||
"iter"
|
||||
"strings"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
||||
// Resource provides generic CRUD operations for a Forgejo API resource.
|
||||
|
|
@ -21,10 +22,11 @@ func NewResource[T any, C any, U any](c *Client, path string) *Resource[T, C, U]
|
|||
collection := path
|
||||
// Strip last segment if it's a pure placeholder like /{index}
|
||||
// Don't strip if mixed like /repos or /{org}/repos
|
||||
if i := strings.LastIndex(path, "/"); i >= 0 {
|
||||
lastSeg := path[i+1:]
|
||||
if strings.HasPrefix(lastSeg, "{") && strings.HasSuffix(lastSeg, "}") {
|
||||
collection = path[:i]
|
||||
parts := core.Split(path, "/")
|
||||
if len(parts) > 0 {
|
||||
lastSeg := parts[len(parts)-1]
|
||||
if core.HasPrefix(lastSeg, "{") && core.HasSuffix(lastSeg, "}") {
|
||||
collection = path[:len(path)-len(lastSeg)-1]
|
||||
}
|
||||
}
|
||||
return &Resource[T, C, U]{client: c, path: path, collection: collection}
|
||||
|
|
|
|||
22
teams.go
22
teams.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -23,60 +23,60 @@ func newTeamService(c *Client) *TeamService {
|
|||
|
||||
// ListMembers returns all members of a team.
|
||||
func (s *TeamService) ListMembers(ctx context.Context, teamID int64) ([]types.User, error) {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/members", teamID)
|
||||
path := core.Sprintf("/api/v1/teams/%d/members", teamID)
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterMembers returns an iterator over all members of a team.
|
||||
func (s *TeamService) IterMembers(ctx context.Context, teamID int64) iter.Seq2[types.User, error] {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/members", teamID)
|
||||
path := core.Sprintf("/api/v1/teams/%d/members", teamID)
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// AddMember adds a user to a team.
|
||||
func (s *TeamService) AddMember(ctx context.Context, teamID int64, username string) error {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/members/%s", teamID, username)
|
||||
path := core.Sprintf("/api/v1/teams/%d/members/%s", teamID, username)
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// RemoveMember removes a user from a team.
|
||||
func (s *TeamService) RemoveMember(ctx context.Context, teamID int64, username string) error {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/members/%s", teamID, username)
|
||||
path := core.Sprintf("/api/v1/teams/%d/members/%s", teamID, username)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListRepos returns all repositories managed by a team.
|
||||
func (s *TeamService) ListRepos(ctx context.Context, teamID int64) ([]types.Repository, error) {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/repos", teamID)
|
||||
path := core.Sprintf("/api/v1/teams/%d/repos", teamID)
|
||||
return ListAll[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterRepos returns an iterator over all repositories managed by a team.
|
||||
func (s *TeamService) IterRepos(ctx context.Context, teamID int64) iter.Seq2[types.Repository, error] {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/repos", teamID)
|
||||
path := core.Sprintf("/api/v1/teams/%d/repos", teamID)
|
||||
return ListIter[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// AddRepo adds a repository to a team.
|
||||
func (s *TeamService) AddRepo(ctx context.Context, teamID int64, org, repo string) error {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/repos/%s/%s", teamID, org, repo)
|
||||
path := core.Sprintf("/api/v1/teams/%d/repos/%s/%s", teamID, org, repo)
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// RemoveRepo removes a repository from a team.
|
||||
func (s *TeamService) RemoveRepo(ctx context.Context, teamID int64, org, repo string) error {
|
||||
path := fmt.Sprintf("/api/v1/teams/%d/repos/%s/%s", teamID, org, repo)
|
||||
path := core.Sprintf("/api/v1/teams/%d/repos/%s/%s", teamID, org, repo)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListOrgTeams returns all teams in an organisation.
|
||||
func (s *TeamService) ListOrgTeams(ctx context.Context, org string) ([]types.Team, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/teams", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/teams", org)
|
||||
return ListAll[types.Team](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgTeams returns an iterator over all teams in an organisation.
|
||||
func (s *TeamService) IterOrgTeams(ctx context.Context, org string) iter.Seq2[types.Team, error] {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/teams", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/teams", org)
|
||||
return ListIter[types.Team](ctx, s.client, path, nil)
|
||||
}
|
||||
|
|
|
|||
22
users.go
22
users.go
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -32,60 +32,60 @@ func (s *UserService) GetCurrent(ctx context.Context) (*types.User, error) {
|
|||
|
||||
// ListFollowers returns all followers of a user.
|
||||
func (s *UserService) ListFollowers(ctx context.Context, username string) ([]types.User, error) {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/followers", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/followers", username)
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterFollowers returns an iterator over all followers of a user.
|
||||
func (s *UserService) IterFollowers(ctx context.Context, username string) iter.Seq2[types.User, error] {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/followers", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/followers", username)
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// ListFollowing returns all users that a user is following.
|
||||
func (s *UserService) ListFollowing(ctx context.Context, username string) ([]types.User, error) {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/following", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/following", username)
|
||||
return ListAll[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterFollowing returns an iterator over all users that a user is following.
|
||||
func (s *UserService) IterFollowing(ctx context.Context, username string) iter.Seq2[types.User, error] {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/following", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/following", username)
|
||||
return ListIter[types.User](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Follow follows a user as the authenticated user.
|
||||
func (s *UserService) Follow(ctx context.Context, username string) error {
|
||||
path := fmt.Sprintf("/api/v1/user/following/%s", username)
|
||||
path := core.Sprintf("/api/v1/user/following/%s", username)
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// Unfollow unfollows a user as the authenticated user.
|
||||
func (s *UserService) Unfollow(ctx context.Context, username string) error {
|
||||
path := fmt.Sprintf("/api/v1/user/following/%s", username)
|
||||
path := core.Sprintf("/api/v1/user/following/%s", username)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
||||
// ListStarred returns all repositories starred by a user.
|
||||
func (s *UserService) ListStarred(ctx context.Context, username string) ([]types.Repository, error) {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/starred", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/starred", username)
|
||||
return ListAll[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterStarred returns an iterator over all repositories starred by a user.
|
||||
func (s *UserService) IterStarred(ctx context.Context, username string) iter.Seq2[types.Repository, error] {
|
||||
path := fmt.Sprintf("/api/v1/users/%s/starred", username)
|
||||
path := core.Sprintf("/api/v1/users/%s/starred", username)
|
||||
return ListIter[types.Repository](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// Star stars a repository as the authenticated user.
|
||||
func (s *UserService) Star(ctx context.Context, owner, repo string) error {
|
||||
path := fmt.Sprintf("/api/v1/user/starred/%s/%s", owner, repo)
|
||||
path := core.Sprintf("/api/v1/user/starred/%s/%s", owner, repo)
|
||||
return s.client.Put(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// Unstar unstars a repository as the authenticated user.
|
||||
func (s *UserService) Unstar(ctx context.Context, owner, repo string) error {
|
||||
path := fmt.Sprintf("/api/v1/user/starred/%s/%s", owner, repo)
|
||||
path := core.Sprintf("/api/v1/user/starred/%s/%s", owner, repo)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -24,18 +24,18 @@ func newWebhookService(c *Client) *WebhookService {
|
|||
|
||||
// TestHook triggers a test delivery for a webhook.
|
||||
func (s *WebhookService) TestHook(ctx context.Context, owner, repo string, id int64) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/%d/tests", owner, repo, id)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/hooks/%d/tests", owner, repo, id)
|
||||
return s.client.Post(ctx, path, nil, nil)
|
||||
}
|
||||
|
||||
// ListOrgHooks returns all webhooks for an organisation.
|
||||
func (s *WebhookService) ListOrgHooks(ctx context.Context, org string) ([]types.Hook, error) {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/hooks", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/hooks", org)
|
||||
return ListAll[types.Hook](ctx, s.client, path, nil)
|
||||
}
|
||||
|
||||
// IterOrgHooks returns an iterator over all webhooks for an organisation.
|
||||
func (s *WebhookService) IterOrgHooks(ctx context.Context, org string) iter.Seq2[types.Hook, error] {
|
||||
path := fmt.Sprintf("/api/v1/orgs/%s/hooks", org)
|
||||
path := core.Sprintf("/api/v1/orgs/%s/hooks", org)
|
||||
return ListIter[types.Hook](ctx, s.client, path, nil)
|
||||
}
|
||||
|
|
|
|||
12
wiki.go
12
wiki.go
|
|
@ -2,8 +2,8 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"dappco.re/go/core/forge/types"
|
||||
)
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ func newWikiService(c *Client) *WikiService {
|
|||
|
||||
// ListPages returns all wiki page metadata for a repository.
|
||||
func (s *WikiService) ListPages(ctx context.Context, owner, repo string) ([]types.WikiPageMetaData, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/pages", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/wiki/pages", owner, repo)
|
||||
var out []types.WikiPageMetaData
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -29,7 +29,7 @@ func (s *WikiService) ListPages(ctx context.Context, owner, repo string) ([]type
|
|||
|
||||
// GetPage returns a single wiki page by name.
|
||||
func (s *WikiService) GetPage(ctx context.Context, owner, repo, pageName string) (*types.WikiPage, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/%s", owner, repo, pageName)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/wiki/page/%s", owner, repo, pageName)
|
||||
var out types.WikiPage
|
||||
if err := s.client.Get(ctx, path, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -39,7 +39,7 @@ func (s *WikiService) GetPage(ctx context.Context, owner, repo, pageName string)
|
|||
|
||||
// CreatePage creates a new wiki page.
|
||||
func (s *WikiService) CreatePage(ctx context.Context, owner, repo string, opts *types.CreateWikiPageOptions) (*types.WikiPage, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new", owner, repo)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/wiki/new", owner, repo)
|
||||
var out types.WikiPage
|
||||
if err := s.client.Post(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -49,7 +49,7 @@ func (s *WikiService) CreatePage(ctx context.Context, owner, repo string, opts *
|
|||
|
||||
// EditPage updates an existing wiki page.
|
||||
func (s *WikiService) EditPage(ctx context.Context, owner, repo, pageName string, opts *types.CreateWikiPageOptions) (*types.WikiPage, error) {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/%s", owner, repo, pageName)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/wiki/page/%s", owner, repo, pageName)
|
||||
var out types.WikiPage
|
||||
if err := s.client.Patch(ctx, path, opts, &out); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -59,6 +59,6 @@ func (s *WikiService) EditPage(ctx context.Context, owner, repo, pageName string
|
|||
|
||||
// DeletePage removes a wiki page.
|
||||
func (s *WikiService) DeletePage(ctx context.Context, owner, repo, pageName string) error {
|
||||
path := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/%s", owner, repo, pageName)
|
||||
path := core.Sprintf("/api/v1/repos/%s/%s/wiki/page/%s", owner, repo, pageName)
|
||||
return s.client.Delete(ctx, path)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue