fix(dx): audit and fix conventions, broken build, and test coverage
- CLAUDE.md: update error wrapping convention from fmt.Errorf to coreerr.E() - cmd/build: fix RegisterCommands API mismatch (cli v0.3.5 compat) - locales: self-register translations via i18n.RegisterLocales in init() - cmd/sdk: replace fmt.Printf with cli.Print for consistent output - cmd/build/cmd_pwa: replace os.Stat with coreio.Local.IsDir - pkg/build/builders: replace os.Stat with io.Local.IsFile for CLI checks - pkg/release/publishers/scoop: replace os.Stat with coreio.Local.IsDir - pkg/api: add tests for getBuilder, resolveDir, and medium initialisation Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
356e5315b9
commit
11050c1a31
9 changed files with 66 additions and 25 deletions
|
|
@ -60,7 +60,7 @@ All file operations use `io.Medium` from `forge.lthn.ai/core/go-io`. Production
|
|||
|
||||
- **UK English** in comments and strings (colour, organisation, notarisation)
|
||||
- **Strict types** — all parameters and return types explicitly typed
|
||||
- **Error wrapping** — `fmt.Errorf("package.Function: message: %w", err)`
|
||||
- **Error wrapping** — `coreerr.E("package.Function", "message", err)` via `coreerr "forge.lthn.ai/core/go-log"`
|
||||
- **testify** (`assert`/`require`) for assertions
|
||||
- **Test naming** — `_Good` (happy path), `_Bad` (expected errors), `_Ugly` (edge cases)
|
||||
- **Conventional commits** — `type(scope): description`
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ import (
|
|||
"embed"
|
||||
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-build/locales"
|
||||
_ "forge.lthn.ai/core/go-build/locales" // registers locale translations
|
||||
"forge.lthn.ai/core/go-i18n"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cli.RegisterCommands(AddBuildCommands, locales.FS)
|
||||
cli.RegisterCommands(AddBuildCommands)
|
||||
}
|
||||
|
||||
// Style aliases from shared package
|
||||
|
|
|
|||
|
|
@ -222,11 +222,7 @@ func downloadAsset(assetURL, destDir string) error {
|
|||
func runBuild(fromPath string) error {
|
||||
fmt.Printf("%s %s\n", i18n.T("cmd.build.from_path.starting"), fromPath)
|
||||
|
||||
info, err := os.Stat(fromPath)
|
||||
if err != nil {
|
||||
return coreerr.E("pwa.runBuild", i18n.T("cmd.build.from_path.error.invalid_path"), err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
if !coreio.Local.IsDir(fromPath) {
|
||||
return coreerr.E("pwa.runBuild", i18n.T("cmd.build.from_path.error.must_be_directory"), nil)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,10 @@
|
|||
package sdkcmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"forge.lthn.ai/core/go-build/pkg/sdk"
|
||||
"forge.lthn.ai/core/cli/pkg/cli"
|
||||
"forge.lthn.ai/core/go-build/pkg/sdk"
|
||||
"forge.lthn.ai/core/go-i18n"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
)
|
||||
|
|
@ -97,10 +96,10 @@ func runSDKDiff(basePath, specPath string) error {
|
|||
return coreerr.E("sdk.Diff", i18n.T("cmd.sdk.diff.error.base_required"), nil)
|
||||
}
|
||||
|
||||
fmt.Printf("%s %s\n", sdkHeaderStyle.Render(i18n.T("cmd.sdk.diff.label")), i18n.ProgressSubject("check", "breaking changes"))
|
||||
fmt.Printf(" %s %s\n", i18n.T("cmd.sdk.diff.base_label"), sdkDimStyle.Render(basePath))
|
||||
fmt.Printf(" %s %s\n", i18n.Label("current"), sdkDimStyle.Render(specPath))
|
||||
fmt.Println()
|
||||
cli.Print("%s %s\n", sdkHeaderStyle.Render(i18n.T("cmd.sdk.diff.label")), i18n.ProgressSubject("check", "breaking changes"))
|
||||
cli.Print(" %s %s\n", i18n.T("cmd.sdk.diff.base_label"), sdkDimStyle.Render(basePath))
|
||||
cli.Print(" %s %s\n", i18n.Label("current"), sdkDimStyle.Render(specPath))
|
||||
cli.Blank()
|
||||
|
||||
result, err := sdk.Diff(basePath, specPath)
|
||||
if err != nil {
|
||||
|
|
@ -108,14 +107,14 @@ func runSDKDiff(basePath, specPath string) error {
|
|||
}
|
||||
|
||||
if result.Breaking {
|
||||
fmt.Printf("%s %s\n", sdkErrorStyle.Render(i18n.T("cmd.sdk.diff.breaking")), result.Summary)
|
||||
cli.Print("%s %s\n", sdkErrorStyle.Render(i18n.T("cmd.sdk.diff.breaking")), result.Summary)
|
||||
for _, change := range result.Changes {
|
||||
fmt.Printf(" - %s\n", change)
|
||||
cli.Print(" - %s\n", change)
|
||||
}
|
||||
return cli.Exit(1, cli.Err("%s", result.Summary))
|
||||
}
|
||||
|
||||
fmt.Printf("%s %s\n", sdkSuccessStyle.Render(i18n.T("cmd.sdk.label.ok")), result.Summary)
|
||||
cli.Print("%s %s\n", sdkSuccessStyle.Render(i18n.T("cmd.sdk.label.ok")), result.Summary)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -127,15 +126,15 @@ func runSDKValidate(specPath string) error {
|
|||
|
||||
s := sdk.New(projectDir, &sdk.Config{Spec: specPath})
|
||||
|
||||
fmt.Printf("%s %s\n", sdkHeaderStyle.Render(i18n.T("cmd.sdk.label.sdk")), i18n.T("cmd.sdk.validate.validating"))
|
||||
cli.Print("%s %s\n", sdkHeaderStyle.Render(i18n.T("cmd.sdk.label.sdk")), i18n.T("cmd.sdk.validate.validating"))
|
||||
|
||||
detectedPath, err := s.DetectSpec()
|
||||
if err != nil {
|
||||
fmt.Printf("%s %v\n", sdkErrorStyle.Render(i18n.Label("error")), err)
|
||||
cli.Print("%s %v\n", sdkErrorStyle.Render(i18n.Label("error")), err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf(" %s %s\n", i18n.Label("spec"), sdkDimStyle.Render(detectedPath))
|
||||
fmt.Printf("%s %s\n", sdkSuccessStyle.Render(i18n.T("cmd.sdk.label.ok")), i18n.T("cmd.sdk.validate.valid"))
|
||||
cli.Print(" %s %s\n", i18n.Label("spec"), sdkDimStyle.Render(detectedPath))
|
||||
cli.Print("%s %s\n", sdkSuccessStyle.Render(i18n.T("cmd.sdk.label.ok")), i18n.T("cmd.sdk.validate.valid"))
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,15 @@
|
|||
// Package locales embeds translation files for this module.
|
||||
package locales
|
||||
|
||||
import "embed"
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"forge.lthn.ai/core/go-i18n"
|
||||
)
|
||||
|
||||
//go:embed *.json
|
||||
var FS embed.FS
|
||||
|
||||
func init() {
|
||||
i18n.RegisterLocales(FS, ".")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"forge.lthn.ai/core/go-build/pkg/build"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestBuildProvider_Good_Identity(t *testing.T) {
|
||||
|
|
@ -75,3 +78,38 @@ func TestBuildProvider_Good_NilHub(t *testing.T) {
|
|||
// emitEvent should not panic with nil hub
|
||||
p.emitEvent("build.started", map[string]any{"test": true})
|
||||
}
|
||||
|
||||
func TestGetBuilder_Good_SupportedTypes(t *testing.T) {
|
||||
b, err := getBuilder(build.ProjectTypeGo)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "go", b.Name())
|
||||
|
||||
b, err = getBuilder(build.ProjectTypeWails)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "wails", b.Name())
|
||||
}
|
||||
|
||||
func TestGetBuilder_Bad_UnsupportedType(t *testing.T) {
|
||||
_, err := getBuilder(build.ProjectType("unknown"))
|
||||
assert.ErrorIs(t, err, os.ErrNotExist)
|
||||
}
|
||||
|
||||
func TestBuildProvider_Good_ResolveDir(t *testing.T) {
|
||||
p := NewProvider("/tmp", nil)
|
||||
dir, err := p.resolveDir()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "/tmp", dir)
|
||||
}
|
||||
|
||||
func TestBuildProvider_Good_ResolveDirRelative(t *testing.T) {
|
||||
p := NewProvider(".", nil)
|
||||
dir, err := p.resolveDir()
|
||||
require.NoError(t, err)
|
||||
// Should return an absolute path
|
||||
assert.True(t, len(dir) > 1 && dir[0] == '/')
|
||||
}
|
||||
|
||||
func TestBuildProvider_Good_MediumSet(t *testing.T) {
|
||||
p := NewProvider(".", nil)
|
||||
assert.NotNil(t, p.medium, "medium should be set to io.Local")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ func (b *LinuxKitBuilder) validateLinuxKitCli() error {
|
|||
}
|
||||
|
||||
for _, p := range paths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
if io.Local.IsFile(p) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ func (b *TaskfileBuilder) validateTaskCli() error {
|
|||
}
|
||||
|
||||
for _, p := range paths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
if io.Local.IsFile(p) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ func (p *ScoopPublisher) commitToBucket(ctx context.Context, bucket string, data
|
|||
|
||||
// Ensure bucket directory exists
|
||||
bucketDir := filepath.Join(tmpDir, "bucket")
|
||||
if _, err := os.Stat(bucketDir); os.IsNotExist(err) {
|
||||
if !coreio.Local.IsDir(bucketDir) {
|
||||
bucketDir = tmpDir // Some repos put manifests in root
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue