refactor: replace os.ReadFile/WriteFile/MkdirAll and fmt.Errorf/errors.New with go-io/go-log
- Replace os.ReadFile with coreio.Local.Read in parser.go and generator_test.go - Replace os.WriteFile with coreio.Local.Write in generator.go - Replace os.MkdirAll with coreio.Local.EnsureDir in generator.go - Replace all fmt.Errorf and errors.New with coreerr.E() from go-log - Add forge.lthn.ai/core/go-io and forge.lthn.ai/core/go-log dependencies Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
30c57a5a51
commit
f84643140e
8 changed files with 61 additions and 38 deletions
24
client.go
24
client.go
|
|
@ -10,6 +10,8 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// APIError represents an error response from the Forgejo API.
|
||||
|
|
@ -139,14 +141,14 @@ func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, er
|
|||
if body != nil {
|
||||
data, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: marshal body: %w", err)
|
||||
return nil, coreerr.E("Client.PostRaw", "forge: marshal body", err)
|
||||
}
|
||||
bodyReader = bytes.NewReader(data)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bodyReader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: create request: %w", err)
|
||||
return nil, coreerr.E("Client.PostRaw", "forge: create request", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", "token "+c.token)
|
||||
|
|
@ -157,7 +159,7 @@ func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, er
|
|||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: request POST %s: %w", path, err)
|
||||
return nil, coreerr.E("Client.PostRaw", "forge: request POST "+path, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
|
@ -167,7 +169,7 @@ func (c *Client) PostRaw(ctx context.Context, path string, body any) ([]byte, er
|
|||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: read response body: %w", err)
|
||||
return nil, coreerr.E("Client.PostRaw", "forge: read response body", err)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
|
@ -180,7 +182,7 @@ func (c *Client) GetRaw(ctx context.Context, path string) ([]byte, error) {
|
|||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: create request: %w", err)
|
||||
return nil, coreerr.E("Client.GetRaw", "forge: create request", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", "token "+c.token)
|
||||
|
|
@ -190,7 +192,7 @@ func (c *Client) GetRaw(ctx context.Context, path string) ([]byte, error) {
|
|||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: request GET %s: %w", path, err)
|
||||
return nil, coreerr.E("Client.GetRaw", "forge: request GET "+path, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
|
@ -200,7 +202,7 @@ func (c *Client) GetRaw(ctx context.Context, path string) ([]byte, error) {
|
|||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: read response body: %w", err)
|
||||
return nil, coreerr.E("Client.GetRaw", "forge: read response body", err)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
|
|
@ -218,14 +220,14 @@ func (c *Client) doJSON(ctx context.Context, method, path string, body, out any)
|
|||
if body != nil {
|
||||
data, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: marshal body: %w", err)
|
||||
return nil, coreerr.E("Client.doJSON", "forge: marshal body", err)
|
||||
}
|
||||
bodyReader = bytes.NewReader(data)
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: create request: %w", err)
|
||||
return nil, coreerr.E("Client.doJSON", "forge: create request", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", "token "+c.token)
|
||||
|
|
@ -239,7 +241,7 @@ func (c *Client) doJSON(ctx context.Context, method, path string, body, out any)
|
|||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: request %s %s: %w", method, path, err)
|
||||
return nil, coreerr.E("Client.doJSON", "forge: request "+method+" "+path, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
|
|
@ -251,7 +253,7 @@ func (c *Client) doJSON(ctx context.Context, method, path string, body, out any)
|
|||
|
||||
if out != nil && resp.StatusCode != http.StatusNoContent {
|
||||
if err := json.NewDecoder(resp.Body).Decode(out); err != nil {
|
||||
return nil, fmt.Errorf("forge: decode response: %w", err)
|
||||
return nil, coreerr.E("Client.doJSON", "forge: decode response", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
coreio "forge.lthn.ai/core/go-io"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// typeGrouping maps type name prefixes to output file names.
|
||||
|
|
@ -204,8 +205,8 @@ type templateData struct {
|
|||
|
||||
// Generate writes Go source files for the extracted types, grouped by logical domain.
|
||||
func Generate(types map[string]*GoType, pairs []CRUDPair, outDir string) error {
|
||||
if err := os.MkdirAll(outDir, 0o755); err != nil {
|
||||
return fmt.Errorf("create output directory: %w", err)
|
||||
if err := coreio.Local.EnsureDir(outDir); err != nil {
|
||||
return coreerr.E("Generate", "create output directory", err)
|
||||
}
|
||||
|
||||
// Group types by output file.
|
||||
|
|
@ -229,7 +230,7 @@ func Generate(types map[string]*GoType, pairs []CRUDPair, outDir string) error {
|
|||
for _, file := range fileNames {
|
||||
outPath := filepath.Join(outDir, file+".go")
|
||||
if err := writeFile(outPath, groups[file]); err != nil {
|
||||
return fmt.Errorf("write %s: %w", outPath, err)
|
||||
return coreerr.E("Generate", "write "+outPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,11 +252,11 @@ func writeFile(path string, types []*GoType) error {
|
|||
|
||||
var buf bytes.Buffer
|
||||
if err := fileHeader.Execute(&buf, data); err != nil {
|
||||
return fmt.Errorf("execute template: %w", err)
|
||||
return coreerr.E("writeFile", "execute template", err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path, buf.Bytes(), 0o644); err != nil {
|
||||
return fmt.Errorf("write file: %w", err)
|
||||
if err := coreio.Local.Write(path, buf.String()); err != nil {
|
||||
return coreerr.E("writeFile", "write file", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
coreio "forge.lthn.ai/core/go-io"
|
||||
)
|
||||
|
||||
func TestGenerate_Good_CreatesFiles(t *testing.T) {
|
||||
|
|
@ -48,20 +50,18 @@ func TestGenerate_Good_ValidGoSyntax(t *testing.T) {
|
|||
}
|
||||
|
||||
entries, _ := os.ReadDir(outDir)
|
||||
var data []byte
|
||||
var content string
|
||||
for _, e := range entries {
|
||||
if strings.HasSuffix(e.Name(), ".go") {
|
||||
data, err = os.ReadFile(filepath.Join(outDir, e.Name()))
|
||||
content, err = coreio.Local.Read(filepath.Join(outDir, e.Name()))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil || data == nil {
|
||||
if err != nil || content == "" {
|
||||
t.Fatal("could not read any generated file")
|
||||
}
|
||||
|
||||
content := string(data)
|
||||
if !strings.Contains(content, "package types") {
|
||||
t.Error("missing package declaration")
|
||||
}
|
||||
|
|
@ -87,9 +87,9 @@ func TestGenerate_Good_RepositoryType(t *testing.T) {
|
|||
var content string
|
||||
entries, _ := os.ReadDir(outDir)
|
||||
for _, e := range entries {
|
||||
data, _ := os.ReadFile(filepath.Join(outDir, e.Name()))
|
||||
if strings.Contains(string(data), "type Repository struct") {
|
||||
content = string(data)
|
||||
data, _ := coreio.Local.Read(filepath.Join(outDir, e.Name()))
|
||||
if strings.Contains(data, "type Repository struct") {
|
||||
content = data
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -129,8 +129,7 @@ func TestGenerate_Good_TimeImport(t *testing.T) {
|
|||
|
||||
entries, _ := os.ReadDir(outDir)
|
||||
for _, e := range entries {
|
||||
data, _ := os.ReadFile(filepath.Join(outDir, e.Name()))
|
||||
content := string(data)
|
||||
content, _ := coreio.Local.Read(filepath.Join(outDir, e.Name()))
|
||||
if strings.Contains(content, "time.Time") && !strings.Contains(content, "\"time\"") {
|
||||
t.Errorf("file %s uses time.Time but doesn't import time", e.Name())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
coreio "forge.lthn.ai/core/go-io"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// Spec represents a Swagger 2.0 specification document.
|
||||
|
|
@ -70,13 +72,13 @@ type CRUDPair struct {
|
|||
|
||||
// LoadSpec reads and parses a Swagger 2.0 JSON file from the given path.
|
||||
func LoadSpec(path string) (*Spec, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
content, err := coreio.Local.Read(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read spec: %w", err)
|
||||
return nil, coreerr.E("LoadSpec", "read spec", err)
|
||||
}
|
||||
var spec Spec
|
||||
if err := json.Unmarshal(data, &spec); err != nil {
|
||||
return nil, fmt.Errorf("parse spec: %w", err)
|
||||
if err := json.Unmarshal([]byte(content), &spec); err != nil {
|
||||
return nil, coreerr.E("LoadSpec", "parse spec", err)
|
||||
}
|
||||
return &spec, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package forge
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -41,7 +42,7 @@ func NewForgeFromConfig(flagURL, flagToken string, opts ...Option) (*Forge, erro
|
|||
return nil, err
|
||||
}
|
||||
if token == "" {
|
||||
return nil, errors.New("forge: no API token configured (set FORGE_TOKEN or pass --token)")
|
||||
return nil, coreerr.E("NewForgeFromConfig", "forge: no API token configured (set FORGE_TOKEN or pass --token)", nil)
|
||||
}
|
||||
return NewForge(url, token, opts...), nil
|
||||
}
|
||||
|
|
|
|||
5
go.mod
5
go.mod
|
|
@ -1,3 +1,8 @@
|
|||
module forge.lthn.ai/core/go-forge
|
||||
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
forge.lthn.ai/core/go-io v0.1.2
|
||||
forge.lthn.ai/core/go-log v0.0.3
|
||||
)
|
||||
|
|
|
|||
12
go.sum
Normal file
12
go.sum
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
forge.lthn.ai/core/go-io v0.1.2 h1:q8hj2jtOFqAgHlBr5wsUAOXtaFkxy9gqGrQT/il0WYA=
|
||||
forge.lthn.ai/core/go-io v0.1.2/go.mod h1:PbNKW1Q25ywSOoQXeGdQHbV5aiIrTXvHIQ5uhplA//g=
|
||||
forge.lthn.ai/core/go-log v0.0.3 h1:Ip//c94QzvSCeFWI7WVDLBRxd1CmqLgs/UZ5iIAqnBc=
|
||||
forge.lthn.ai/core/go-log v0.0.3/go.mod h1:r14MXKOD3LF/sI8XUJQhRk/SZHBE7jAFVuCfgkXoZPw=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
@ -2,11 +2,12 @@ package forge
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
||||
// ListOptions controls pagination.
|
||||
|
|
@ -38,7 +39,7 @@ func ListPage[T any](ctx context.Context, c *Client, path string, query map[stri
|
|||
|
||||
u, err := url.Parse(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("forge: parse path: %w", err)
|
||||
return nil, coreerr.E("ListPage", "forge: parse path", err)
|
||||
}
|
||||
|
||||
q := u.Query()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue