go-forge/CLAUDE.md
Snider 0a9564274d
All checks were successful
Security Scan / security (pull_request) Successful in 9s
Test / test (pull_request) Successful in 1m20s
refactor(module): migrate module path to dappco.re/go/core/forge
Update Go module path from forge.lthn.ai/core/go-forge to
dappco.re/go/core/forge. Migrate all import paths and dependency
references (go-io → dappco.re/go/core/io, go-log → dappco.re/go/core/log).
Update documentation (CLAUDE.md, README.md, docs/) to reflect new paths.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 01:51:29 +00:00

3.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

Full-coverage Go client for the Forgejo API (~450 endpoints). Uses a generic Resource[T,C,U] pattern for CRUD operations and types generated from swagger.v1.json.

Module: dappco.re/go/core/forge (Go 1.26, depends on go-io and go-log)

Build & Test

go test ./...                          # Run all tests
go test -v -run TestName ./...         # Run single test
go generate ./types/...                # Regenerate types from swagger spec
go run ./cmd/forgegen/ -spec testdata/swagger.v1.json -out types/  # Manual codegen

No linter or formatter is configured beyond standard go vet.

Architecture

The library is a flat package (package forge) with a layered design:

  1. client.go — Low-level HTTP client (Client). All requests go through doJSON(). Handles auth (token header), JSON marshalling, rate-limit tracking, and error parsing into *APIError. Also provides GetRaw/PostRaw for non-JSON responses.

  2. resource.go — Generic Resource[T, C, U] struct (T=response type, C=create options, U=update options). Provides List, ListAll, Iter, Get, Create, Update, Delete. Covers ~91% of endpoints.

  3. pagination.go — Generic ListPage[T], ListAll[T], ListIter[T] functions. Uses X-Total-Count header for pagination. ListIter returns iter.Seq2[T, error] for Go 1.26 range-over-func.

  4. params.goParams map type and ResolvePath() for substituting {placeholders} in API paths.

  5. config.go — Config resolution: flags > env (FORGE_URL, FORGE_TOKEN) > defaults (http://localhost:3000).

  6. forge.go — Top-level Forge struct aggregating all 18 service fields. Created via NewForge(url, token) or NewForgeFromConfig(flagURL, flagToken).

  7. Service files (repos.go, issues.go, etc.) — Each service struct embeds Resource[T,C,U] for standard CRUD, then adds hand-written action methods (e.g. Fork, Pin, MirrorSync). 18 services total: repos, issues, pulls, orgs, users, teams, admin, branches, releases, labels, webhooks, notifications, packages, actions, contents, wiki, commits, misc.

  8. types/ — Generated Go types from swagger.v1.json (229 types). The //go:generate directive lives in types/generate.go. Do not hand-edit generated type files — modify cmd/forgegen/ instead.

  9. cmd/forgegen/ — Code generator: parses swagger spec (parser.go), extracts types and CRUD pairs, generates Go files (generator.go).

Test Patterns

  • Tests use httptest.NewServer with inline handlers — no mocks or external services
  • Test naming uses _Good, _Bad, _Ugly suffixes (happy path, expected errors, edge cases/panics)
  • Service-level tests live in *_test.go files alongside each service

Coding Standards

  • All methods accept context.Context as first parameter
  • Errors wrapped as *APIError with StatusCode, Message, URL; use IsNotFound(), IsForbidden(), IsConflict() helpers
  • Internal errors use coreerr.E() from go-log (imported as coreerr "dappco.re/go/core/log"), never fmt.Errorf or errors.New
  • File I/O uses go-io (imported as coreio "dappco.re/go/core/io"), never os.ReadFile/os.WriteFile/os.MkdirAll
  • UK English in comments (organisation, colour, etc.)
  • Co-Authored-By: Virgil <virgil@lethean.io> in commits
  • Client uses functional options pattern (WithHTTPClient, WithUserAgent)

Adding a New Service

  1. Create newservice.go with a struct embedding Resource[T, C, U]
  2. Add action methods that call s.client.Get/Post/Patch/Put/Delete directly
  3. Wire it into Forge struct in forge.go and NewForge()
  4. Add tests in newservice_test.go

Forge Remote

git remote add forge ssh://git@forge.lthn.ai:2223/core/go-forge.git