diff --git a/ansible/executor.go b/ansible/executor.go index 08ea851..54a82ba 100644 --- a/ansible/executor.go +++ b/ansible/executor.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "regexp" + "slices" "strings" "sync" "text/template" @@ -920,20 +921,16 @@ func (e *Executor) matchesTags(taskTags []string) bool { // Check skip tags for _, skip := range e.SkipTags { - for _, tt := range taskTags { - if skip == tt { - return false - } + if slices.Contains(taskTags, skip) { + return false } } // Check include tags if len(e.Tags) > 0 { for _, tag := range e.Tags { - for _, tt := range taskTags { - if tag == tt || tag == "all" { - return true - } + if tag == "all" || slices.Contains(taskTags, tag) { + return true } } return false diff --git a/ansible/modules.go b/ansible/modules.go index 6082aaa..9a3c722 100644 --- a/ansible/modules.go +++ b/ansible/modules.go @@ -3,6 +3,7 @@ package ansible import ( "context" "encoding/base64" + "errors" "fmt" "os" "path/filepath" @@ -178,7 +179,7 @@ func (e *Executor) moduleShell(ctx context.Context, client *SSHClient, args map[ cmd = getStringArg(args, "cmd", "") } if cmd == "" { - return nil, fmt.Errorf("shell: no command specified") + return nil, errors.New("shell: no command specified") } // Handle chdir @@ -206,7 +207,7 @@ func (e *Executor) moduleCommand(ctx context.Context, client *SSHClient, args ma cmd = getStringArg(args, "cmd", "") } if cmd == "" { - return nil, fmt.Errorf("command: no command specified") + return nil, errors.New("command: no command specified") } // Handle chdir @@ -231,7 +232,7 @@ func (e *Executor) moduleCommand(ctx context.Context, client *SSHClient, args ma func (e *Executor) moduleRaw(ctx context.Context, client *SSHClient, args map[string]any) (*TaskResult, error) { cmd := getStringArg(args, "_raw_params", "") if cmd == "" { - return nil, fmt.Errorf("raw: no command specified") + return nil, errors.New("raw: no command specified") } stdout, stderr, rc, err := client.Run(ctx, cmd) @@ -250,7 +251,7 @@ func (e *Executor) moduleRaw(ctx context.Context, client *SSHClient, args map[st func (e *Executor) moduleScript(ctx context.Context, client *SSHClient, args map[string]any) (*TaskResult, error) { script := getStringArg(args, "_raw_params", "") if script == "" { - return nil, fmt.Errorf("script: no script specified") + return nil, errors.New("script: no script specified") } // Read local script @@ -278,7 +279,7 @@ func (e *Executor) moduleScript(ctx context.Context, client *SSHClient, args map func (e *Executor) moduleCopy(ctx context.Context, client *SSHClient, args map[string]any, host string, task *Task) (*TaskResult, error) { dest := getStringArg(args, "dest", "") if dest == "" { - return nil, fmt.Errorf("copy: dest required") + return nil, errors.New("copy: dest required") } var content []byte @@ -292,7 +293,7 @@ func (e *Executor) moduleCopy(ctx context.Context, client *SSHClient, args map[s } else if c := getStringArg(args, "content", ""); c != "" { content = []byte(c) } else { - return nil, fmt.Errorf("copy: src or content required") + return nil, errors.New("copy: src or content required") } mode := os.FileMode(0644) @@ -322,7 +323,7 @@ func (e *Executor) moduleTemplate(ctx context.Context, client *SSHClient, args m src := getStringArg(args, "src", "") dest := getStringArg(args, "dest", "") if src == "" || dest == "" { - return nil, fmt.Errorf("template: src and dest required") + return nil, errors.New("template: src and dest required") } // Process template @@ -352,7 +353,7 @@ func (e *Executor) moduleFile(ctx context.Context, client *SSHClient, args map[s path = getStringArg(args, "dest", "") } if path == "" { - return nil, fmt.Errorf("file: path required") + return nil, errors.New("file: path required") } state := getStringArg(args, "state", "file") @@ -383,7 +384,7 @@ func (e *Executor) moduleFile(ctx context.Context, client *SSHClient, args map[s case "link": src := getStringArg(args, "src", "") if src == "" { - return nil, fmt.Errorf("file: src required for link state") + return nil, errors.New("file: src required for link state") } cmd := fmt.Sprintf("ln -sf %q %q", src, path) _, stderr, rc, err := client.Run(ctx, cmd) @@ -420,7 +421,7 @@ func (e *Executor) moduleLineinfile(ctx context.Context, client *SSHClient, args path = getStringArg(args, "dest", "") } if path == "" { - return nil, fmt.Errorf("lineinfile: path required") + return nil, errors.New("lineinfile: path required") } line := getStringArg(args, "line", "") @@ -460,7 +461,7 @@ func (e *Executor) moduleLineinfile(ctx context.Context, client *SSHClient, args func (e *Executor) moduleStat(ctx context.Context, client *SSHClient, args map[string]any) (*TaskResult, error) { path := getStringArg(args, "path", "") if path == "" { - return nil, fmt.Errorf("stat: path required") + return nil, errors.New("stat: path required") } stat, err := client.Stat(ctx, path) @@ -480,7 +481,7 @@ func (e *Executor) moduleSlurp(ctx context.Context, client *SSHClient, args map[ path = getStringArg(args, "src", "") } if path == "" { - return nil, fmt.Errorf("slurp: path required") + return nil, errors.New("slurp: path required") } content, err := client.Download(ctx, path) @@ -500,7 +501,7 @@ func (e *Executor) moduleFetch(ctx context.Context, client *SSHClient, args map[ src := getStringArg(args, "src", "") dest := getStringArg(args, "dest", "") if src == "" || dest == "" { - return nil, fmt.Errorf("fetch: src and dest required") + return nil, errors.New("fetch: src and dest required") } content, err := client.Download(ctx, src) @@ -524,7 +525,7 @@ func (e *Executor) moduleGetURL(ctx context.Context, client *SSHClient, args map url := getStringArg(args, "url", "") dest := getStringArg(args, "dest", "") if url == "" || dest == "" { - return nil, fmt.Errorf("get_url: url and dest required") + return nil, errors.New("get_url: url and dest required") } // Use curl or wget @@ -591,7 +592,7 @@ func (e *Executor) moduleAptKey(ctx context.Context, client *SSHClient, args map } if url == "" { - return nil, fmt.Errorf("apt_key: url required") + return nil, errors.New("apt_key: url required") } var cmd string @@ -615,7 +616,7 @@ func (e *Executor) moduleAptRepository(ctx context.Context, client *SSHClient, a state := getStringArg(args, "state", "present") if repo == "" { - return nil, fmt.Errorf("apt_repository: repo required") + return nil, errors.New("apt_repository: repo required") } if filename == "" { @@ -690,7 +691,7 @@ func (e *Executor) moduleService(ctx context.Context, client *SSHClient, args ma enabled := args["enabled"] if name == "" { - return nil, fmt.Errorf("service: name required") + return nil, errors.New("service: name required") } var cmds []string @@ -742,7 +743,7 @@ func (e *Executor) moduleUser(ctx context.Context, client *SSHClient, args map[s state := getStringArg(args, "state", "present") if name == "" { - return nil, fmt.Errorf("user: name required") + return nil, errors.New("user: name required") } if state == "absent" { @@ -799,7 +800,7 @@ func (e *Executor) moduleGroup(ctx context.Context, client *SSHClient, args map[ state := getStringArg(args, "state", "present") if name == "" { - return nil, fmt.Errorf("group: name required") + return nil, errors.New("group: name required") } if state == "absent" { @@ -834,7 +835,7 @@ func (e *Executor) moduleURI(ctx context.Context, client *SSHClient, args map[st method := getStringArg(args, "method", "GET") if url == "" { - return nil, fmt.Errorf("uri: url required") + return nil, errors.New("uri: url required") } var curlOpts []string @@ -912,7 +913,7 @@ func (e *Executor) moduleFail(args map[string]any) (*TaskResult, error) { func (e *Executor) moduleAssert(args map[string]any, host string) (*TaskResult, error) { that, ok := args["that"] if !ok { - return nil, fmt.Errorf("assert: 'that' required") + return nil, errors.New("assert: 'that' required") } conditions := normalizeConditions(that) @@ -1013,7 +1014,7 @@ func (e *Executor) moduleGit(ctx context.Context, client *SSHClient, args map[st version := getStringArg(args, "version", "HEAD") if repo == "" || dest == "" { - return nil, fmt.Errorf("git: repo and dest required") + return nil, errors.New("git: repo and dest required") } // Check if dest exists @@ -1042,7 +1043,7 @@ func (e *Executor) moduleUnarchive(ctx context.Context, client *SSHClient, args remote := getBoolArg(args, "remote_src", false) if src == "" || dest == "" { - return nil, fmt.Errorf("unarchive: src and dest required") + return nil, errors.New("unarchive: src and dest required") } // Create dest directory (best-effort) @@ -1117,7 +1118,7 @@ func getBoolArg(args map[string]any, key string, def bool) bool { func (e *Executor) moduleHostname(ctx context.Context, client *SSHClient, args map[string]any) (*TaskResult, error) { name := getStringArg(args, "name", "") if name == "" { - return nil, fmt.Errorf("hostname: name required") + return nil, errors.New("hostname: name required") } // Set hostname @@ -1139,7 +1140,7 @@ func (e *Executor) moduleSysctl(ctx context.Context, client *SSHClient, args map state := getStringArg(args, "state", "present") if name == "" { - return nil, fmt.Errorf("sysctl: name required") + return nil, errors.New("sysctl: name required") } if state == "absent" { @@ -1209,7 +1210,7 @@ func (e *Executor) moduleBlockinfile(ctx context.Context, client *SSHClient, arg path = getStringArg(args, "dest", "") } if path == "" { - return nil, fmt.Errorf("blockinfile: path required") + return nil, errors.New("blockinfile: path required") } block := getStringArg(args, "block", "") @@ -1357,7 +1358,7 @@ func (e *Executor) moduleAuthorizedKey(ctx context.Context, client *SSHClient, a state := getStringArg(args, "state", "present") if user == "" || key == "" { - return nil, fmt.Errorf("authorized_key: user and key required") + return nil, errors.New("authorized_key: user and key required") } // Get user's home directory @@ -1407,7 +1408,7 @@ func (e *Executor) moduleDockerCompose(ctx context.Context, client *SSHClient, a state := getStringArg(args, "state", "present") if projectSrc == "" { - return nil, fmt.Errorf("docker_compose: project_src required") + return nil, errors.New("docker_compose: project_src required") } var cmd string diff --git a/build/archive.go b/build/archive.go index aa54021..1b25e58 100644 --- a/build/archive.go +++ b/build/archive.go @@ -6,13 +6,14 @@ import ( "archive/zip" "bytes" "compress/gzip" + "errors" "fmt" "io" "path/filepath" "strings" - "github.com/Snider/Borg/pkg/compress" io_interface "forge.lthn.ai/core/go/pkg/io" + "github.com/Snider/Borg/pkg/compress" ) // ArchiveFormat specifies the compression format for archives. @@ -48,7 +49,7 @@ func ArchiveXZ(fs io_interface.Medium, artifact Artifact) (Artifact, error) { // Returns a new Artifact with Path pointing to the archive. func ArchiveWithFormat(fs io_interface.Medium, artifact Artifact, format ArchiveFormat) (Artifact, error) { if artifact.Path == "" { - return Artifact{}, fmt.Errorf("build.Archive: artifact path is empty") + return Artifact{}, errors.New("build.Archive: artifact path is empty") } // Verify the source file exists @@ -57,7 +58,7 @@ func ArchiveWithFormat(fs io_interface.Medium, artifact Artifact, format Archive return Artifact{}, fmt.Errorf("build.Archive: source file not found: %w", err) } if info.IsDir() { - return Artifact{}, fmt.Errorf("build.Archive: source path is a directory, expected file") + return Artifact{}, errors.New("build.Archive: source path is a directory, expected file") } // Determine archive type based on OS and format diff --git a/build/buildcmd/cmd_project.go b/build/buildcmd/cmd_project.go index 386f1e7..a4b63c1 100644 --- a/build/buildcmd/cmd_project.go +++ b/build/buildcmd/cmd_project.go @@ -48,7 +48,7 @@ func runProjectBuild(ctx context.Context, buildType string, ciMode bool, targets return fmt.Errorf("%s: %w", i18n.T("common.error.failed", map[string]any{"Action": "detect project type"}), err) } if projectType == "" { - return fmt.Errorf("%s", i18n.T("cmd.build.error.no_project_type", map[string]interface{}{"Dir": projectDir})) + return fmt.Errorf("%s", i18n.T("cmd.build.error.no_project_type", map[string]any{"Dir": projectDir})) } } @@ -139,7 +139,7 @@ func runProjectBuild(ctx context.Context, buildType string, ciMode bool, targets } if verbose && !ciMode { - fmt.Printf("%s %s\n", buildSuccessStyle.Render(i18n.T("common.label.success")), i18n.T("cmd.build.built_artifacts", map[string]interface{}{"Count": len(artifacts)})) + fmt.Printf("%s %s\n", buildSuccessStyle.Render(i18n.T("common.label.success")), i18n.T("cmd.build.built_artifacts", map[string]any{"Count": len(artifacts)})) fmt.Println() for _, artifact := range artifacts { relPath, err := filepath.Rel(projectDir, artifact.Path) @@ -260,7 +260,7 @@ func runProjectBuild(ctx context.Context, buildType string, ciMode bool, targets // Minimal output: just success with artifact count fmt.Printf("%s %s %s\n", buildSuccessStyle.Render(i18n.T("common.label.success")), - i18n.T("cmd.build.built_artifacts", map[string]interface{}{"Count": len(artifacts)}), + i18n.T("cmd.build.built_artifacts", map[string]any{"Count": len(artifacts)}), buildDimStyle.Render(fmt.Sprintf("(%s)", outputDir)), ) } @@ -342,7 +342,7 @@ func parseTargets(targetsFlag string) ([]build.Target, error) { osArch := strings.Split(part, "/") if len(osArch) != 2 { - return nil, fmt.Errorf("%s", i18n.T("cmd.build.error.invalid_target", map[string]interface{}{"Target": part})) + return nil, fmt.Errorf("%s", i18n.T("cmd.build.error.invalid_target", map[string]any{"Target": part})) } targets = append(targets, build.Target{ diff --git a/build/buildcmd/cmd_pwa.go b/build/buildcmd/cmd_pwa.go index 1fdc0b6..79a8529 100644 --- a/build/buildcmd/cmd_pwa.go +++ b/build/buildcmd/cmd_pwa.go @@ -147,14 +147,14 @@ func findManifestURL(htmlContent, baseURL string) (string, error) { } // fetchManifest downloads and parses a PWA manifest. -func fetchManifest(manifestURL string) (map[string]interface{}, error) { +func fetchManifest(manifestURL string) (map[string]any, error) { resp, err := http.Get(manifestURL) if err != nil { return nil, err } defer func() { _ = resp.Body.Close() }() - var manifest map[string]interface{} + var manifest map[string]any if err := json.NewDecoder(resp.Body).Decode(&manifest); err != nil { return nil, err } @@ -162,7 +162,7 @@ func fetchManifest(manifestURL string) (map[string]interface{}, error) { } // collectAssets extracts asset URLs from a PWA manifest. -func collectAssets(manifest map[string]interface{}, manifestURL string) []string { +func collectAssets(manifest map[string]any, manifestURL string) []string { var assets []string base, _ := url.Parse(manifestURL) @@ -174,9 +174,9 @@ func collectAssets(manifest map[string]interface{}, manifestURL string) []string } // Add icons - if icons, ok := manifest["icons"].([]interface{}); ok { + if icons, ok := manifest["icons"].([]any); ok { for _, icon := range icons { - if iconMap, ok := icon.(map[string]interface{}); ok { + if iconMap, ok := icon.(map[string]any); ok { if src, ok := iconMap["src"].(string); ok { if resolved, err := base.Parse(src); err == nil { assets = append(assets, resolved.String()) diff --git a/build/builders/cpp.go b/build/builders/cpp.go index 0ce3b34..02fa7db 100644 --- a/build/builders/cpp.go +++ b/build/builders/cpp.go @@ -3,6 +3,7 @@ package builders import ( "context" + "errors" "fmt" "os" "os/exec" @@ -38,7 +39,7 @@ func (b *CPPBuilder) Detect(fs io.Medium, dir string) (bool, error) { // Cross-compilation is handled via Conan profiles specified in .core/build.yaml. func (b *CPPBuilder) Build(ctx context.Context, cfg *build.Config, targets []build.Target) ([]build.Artifact, error) { if cfg == nil { - return nil, fmt.Errorf("builders.CPPBuilder.Build: config is nil") + return nil, errors.New("builders.CPPBuilder.Build: config is nil") } // Validate make is available @@ -244,7 +245,7 @@ func (b *CPPBuilder) targetToProfile(target build.Target) string { // validateMake checks if make is available. func (b *CPPBuilder) validateMake() error { if _, err := exec.LookPath("make"); err != nil { - return fmt.Errorf("cpp: make not found. Install build-essential (Linux) or Xcode Command Line Tools (macOS)") + return errors.New("cpp: make not found. Install build-essential (Linux) or Xcode Command Line Tools (macOS)") } return nil } diff --git a/build/builders/docker.go b/build/builders/docker.go index 560c49c..65b402e 100644 --- a/build/builders/docker.go +++ b/build/builders/docker.go @@ -3,6 +3,7 @@ package builders import ( "context" + "errors" "fmt" "os" "os/exec" @@ -186,7 +187,7 @@ func (b *DockerBuilder) Build(ctx context.Context, cfg *build.Config, targets [] func (b *DockerBuilder) validateDockerCli() error { cmd := exec.Command("docker", "--version") if err := cmd.Run(); err != nil { - return fmt.Errorf("docker: docker CLI not found. Install it from https://docs.docker.com/get-docker/") + return errors.New("docker: docker CLI not found. Install it from https://docs.docker.com/get-docker/") } return nil } @@ -196,7 +197,7 @@ func (b *DockerBuilder) ensureBuildx(ctx context.Context) error { // Check if buildx is available cmd := exec.CommandContext(ctx, "docker", "buildx", "version") if err := cmd.Run(); err != nil { - return fmt.Errorf("docker: buildx is not available. Install it from https://docs.docker.com/buildx/working-with-buildx/") + return errors.New("docker: buildx is not available. Install it from https://docs.docker.com/buildx/working-with-buildx/") } // Check if we have a builder, create one if not diff --git a/build/builders/go.go b/build/builders/go.go index 379572e..cc1e07d 100644 --- a/build/builders/go.go +++ b/build/builders/go.go @@ -3,6 +3,7 @@ package builders import ( "context" + "errors" "fmt" "os" "os/exec" @@ -37,11 +38,11 @@ func (b *GoBuilder) Detect(fs io.Medium, dir string) (bool, error) { // applies ldflags and trimpath, and runs go build. func (b *GoBuilder) Build(ctx context.Context, cfg *build.Config, targets []build.Target) ([]build.Artifact, error) { if cfg == nil { - return nil, fmt.Errorf("builders.GoBuilder.Build: config is nil") + return nil, errors.New("builders.GoBuilder.Build: config is nil") } if len(targets) == 0 { - return nil, fmt.Errorf("builders.GoBuilder.Build: no targets specified") + return nil, errors.New("builders.GoBuilder.Build: no targets specified") } // Ensure output directory exists diff --git a/build/builders/linuxkit.go b/build/builders/linuxkit.go index 93055f6..1818e0b 100644 --- a/build/builders/linuxkit.go +++ b/build/builders/linuxkit.go @@ -3,6 +3,7 @@ package builders import ( "context" + "errors" "fmt" "os" "os/exec" @@ -78,7 +79,7 @@ func (b *LinuxKitBuilder) Build(ctx context.Context, cfg *build.Config, targets } if configPath == "" { - return nil, fmt.Errorf("linuxkit.Build: no LinuxKit config file found. Specify with --config or create linuxkit.yml") + return nil, errors.New("linuxkit.Build: no LinuxKit config file found. Specify with --config or create linuxkit.yml") } // Validate config file exists @@ -266,5 +267,5 @@ func (b *LinuxKitBuilder) validateLinuxKitCli() error { } } - return fmt.Errorf("linuxkit: linuxkit CLI not found. Install with: brew install linuxkit (macOS) or see https://github.com/linuxkit/linuxkit") + return errors.New("linuxkit: linuxkit CLI not found. Install with: brew install linuxkit (macOS) or see https://github.com/linuxkit/linuxkit") } diff --git a/build/builders/taskfile.go b/build/builders/taskfile.go index 5661ee9..1dd796b 100644 --- a/build/builders/taskfile.go +++ b/build/builders/taskfile.go @@ -3,6 +3,7 @@ package builders import ( "context" + "errors" "fmt" "os" "os/exec" @@ -271,5 +272,5 @@ func (b *TaskfileBuilder) validateTaskCli() error { } } - return fmt.Errorf("taskfile: task CLI not found. Install with: brew install go-task (macOS), go install github.com/go-task/task/v3/cmd/task@latest, or see https://taskfile.dev/installation/") + return errors.New("taskfile: task CLI not found. Install with: brew install go-task (macOS), go install github.com/go-task/task/v3/cmd/task@latest, or see https://taskfile.dev/installation/") } diff --git a/build/builders/wails.go b/build/builders/wails.go index 649703f..4fae4e6 100644 --- a/build/builders/wails.go +++ b/build/builders/wails.go @@ -3,6 +3,7 @@ package builders import ( "context" + "errors" "fmt" "os/exec" "path/filepath" @@ -37,11 +38,11 @@ func (b *WailsBuilder) Detect(fs io.Medium, dir string) (bool, error) { // - Wails v2: Uses 'wails build' command func (b *WailsBuilder) Build(ctx context.Context, cfg *build.Config, targets []build.Target) ([]build.Artifact, error) { if cfg == nil { - return nil, fmt.Errorf("builders.WailsBuilder.Build: config is nil") + return nil, errors.New("builders.WailsBuilder.Build: config is nil") } if len(targets) == 0 { - return nil, fmt.Errorf("builders.WailsBuilder.Build: no targets specified") + return nil, errors.New("builders.WailsBuilder.Build: no targets specified") } // Detect Wails version @@ -53,7 +54,7 @@ func (b *WailsBuilder) Build(ctx context.Context, cfg *build.Config, targets []b if detected, _ := taskBuilder.Detect(cfg.FS, cfg.ProjectDir); detected { return taskBuilder.Build(ctx, cfg, targets) } - return nil, fmt.Errorf("wails v3 projects require a Taskfile for building") + return nil, errors.New("wails v3 projects require a Taskfile for building") } // Wails v2 strategy: Use 'wails build' diff --git a/build/checksum.go b/build/checksum.go index 7738dbe..fee1b2e 100644 --- a/build/checksum.go +++ b/build/checksum.go @@ -4,19 +4,21 @@ package build import ( "crypto/sha256" "encoding/hex" + "errors" "fmt" "io" "path/filepath" + "slices" + + "strings" io_interface "forge.lthn.ai/core/go/pkg/io" - "sort" - "strings" ) // Checksum computes SHA256 for an artifact and returns the artifact with the Checksum field filled. func Checksum(fs io_interface.Medium, artifact Artifact) (Artifact, error) { if artifact.Path == "" { - return Artifact{}, fmt.Errorf("build.Checksum: artifact path is empty") + return Artifact{}, errors.New("build.Checksum: artifact path is empty") } // Open the file @@ -84,7 +86,7 @@ func WriteChecksumFile(fs io_interface.Medium, artifacts []Artifact, path string } // Sort lines for consistent output - sort.Strings(lines) + slices.Sort(lines) content := strings.Join(lines, "\n") + "\n" diff --git a/build/signing/codesign.go b/build/signing/codesign.go index 014a026..7c131fc 100644 --- a/build/signing/codesign.go +++ b/build/signing/codesign.go @@ -2,6 +2,7 @@ package signing import ( "context" + "errors" "fmt" "os/exec" "runtime" @@ -42,7 +43,7 @@ func (s *MacOSSigner) Available() bool { // Sign codesigns a binary with hardened runtime. func (s *MacOSSigner) Sign(ctx context.Context, fs io.Medium, binary string) error { if !s.Available() { - return fmt.Errorf("codesign.Sign: codesign not available") + return errors.New("codesign.Sign: codesign not available") } cmd := exec.CommandContext(ctx, "codesign", @@ -65,7 +66,7 @@ func (s *MacOSSigner) Sign(ctx context.Context, fs io.Medium, binary string) err // This blocks until Apple responds (typically 1-5 minutes). func (s *MacOSSigner) Notarize(ctx context.Context, fs io.Medium, binary string) error { if s.config.AppleID == "" || s.config.TeamID == "" || s.config.AppPassword == "" { - return fmt.Errorf("codesign.Notarize: missing Apple credentials (apple_id, team_id, app_password)") + return errors.New("codesign.Notarize: missing Apple credentials (apple_id, team_id, app_password)") } // Create ZIP for submission diff --git a/build/signing/gpg.go b/build/signing/gpg.go index 6183510..9e1878a 100644 --- a/build/signing/gpg.go +++ b/build/signing/gpg.go @@ -2,6 +2,7 @@ package signing import ( "context" + "errors" "fmt" "os/exec" @@ -39,7 +40,7 @@ func (s *GPGSigner) Available() bool { // For file.txt, creates file.txt.asc func (s *GPGSigner) Sign(ctx context.Context, fs io.Medium, file string) error { if !s.Available() { - return fmt.Errorf("gpg.Sign: gpg not available or key not configured") + return errors.New("gpg.Sign: gpg not available or key not configured") } cmd := exec.CommandContext(ctx, "gpg", diff --git a/build/signing/sign.go b/build/signing/sign.go index 33bd907..f23c7f2 100644 --- a/build/signing/sign.go +++ b/build/signing/sign.go @@ -2,6 +2,7 @@ package signing import ( "context" + "errors" "fmt" "runtime" @@ -59,7 +60,7 @@ func NotarizeBinaries(ctx context.Context, fs io.Medium, cfg SignConfig, artifac signer := NewMacOSSigner(cfg.MacOS) if !signer.Available() { - return fmt.Errorf("notarization requested but codesign not available") + return errors.New("notarization requested but codesign not available") } for _, artifact := range artifacts { diff --git a/cmd/dev/cmd_apply.go b/cmd/dev/cmd_apply.go index fe9b58e..76502b9 100644 --- a/cmd/dev/cmd_apply.go +++ b/cmd/dev/cmd_apply.go @@ -203,19 +203,19 @@ func runApply() error { cli.Blank() cli.Print("%s: ", i18n.T("cmd.dev.apply.summary")) if succeeded > 0 { - cli.Print("%s", successStyle.Render(i18n.T("common.count.succeeded", map[string]interface{}{"Count": succeeded}))) + cli.Print("%s", successStyle.Render(i18n.T("common.count.succeeded", map[string]any{"Count": succeeded}))) } if skipped > 0 { if succeeded > 0 { cli.Print(", ") } - cli.Print("%s", dimStyle.Render(i18n.T("common.count.skipped", map[string]interface{}{"Count": skipped}))) + cli.Print("%s", dimStyle.Render(i18n.T("common.count.skipped", map[string]any{"Count": skipped}))) } if failed > 0 { if succeeded > 0 || skipped > 0 { cli.Print(", ") } - cli.Print("%s", errorStyle.Render(i18n.T("common.count.failed", map[string]interface{}{"Count": failed}))) + cli.Print("%s", errorStyle.Render(i18n.T("common.count.failed", map[string]any{"Count": failed}))) } cli.Blank() diff --git a/cmd/dev/cmd_ci.go b/cmd/dev/cmd_ci.go index e3ae3c2..84bed12 100644 --- a/cmd/dev/cmd_ci.go +++ b/cmd/dev/cmd_ci.go @@ -146,18 +146,18 @@ func runCI(registryPath string, branch string, failedOnly bool) error { // Print summary cli.Blank() - cli.Print("%s", i18n.T("cmd.dev.ci.repos_checked", map[string]interface{}{"Count": len(repoList)})) + cli.Print("%s", i18n.T("cmd.dev.ci.repos_checked", map[string]any{"Count": len(repoList)})) if success > 0 { - cli.Print(" * %s", ciSuccessStyle.Render(i18n.T("cmd.dev.ci.passing", map[string]interface{}{"Count": success}))) + cli.Print(" * %s", ciSuccessStyle.Render(i18n.T("cmd.dev.ci.passing", map[string]any{"Count": success}))) } if failed > 0 { - cli.Print(" * %s", ciFailureStyle.Render(i18n.T("cmd.dev.ci.failing", map[string]interface{}{"Count": failed}))) + cli.Print(" * %s", ciFailureStyle.Render(i18n.T("cmd.dev.ci.failing", map[string]any{"Count": failed}))) } if pending > 0 { - cli.Print(" * %s", ciPendingStyle.Render(i18n.T("common.count.pending", map[string]interface{}{"Count": pending}))) + cli.Print(" * %s", ciPendingStyle.Render(i18n.T("common.count.pending", map[string]any{"Count": pending}))) } if len(noCI) > 0 { - cli.Print(" * %s", ciSkippedStyle.Render(i18n.T("cmd.dev.ci.no_ci", map[string]interface{}{"Count": len(noCI)}))) + cli.Print(" * %s", ciSkippedStyle.Render(i18n.T("cmd.dev.ci.no_ci", map[string]any{"Count": len(noCI)}))) } cli.Blank() cli.Blank() diff --git a/cmd/dev/cmd_commit.go b/cmd/dev/cmd_commit.go index 11bbb5f..7d95605 100644 --- a/cmd/dev/cmd_commit.go +++ b/cmd/dev/cmd_commit.go @@ -86,17 +86,17 @@ func runCommit(registryPath string, all bool) error { } // Show dirty repos - cli.Print("\n%s\n\n", i18n.T("cmd.dev.repos_with_changes", map[string]interface{}{"Count": len(dirtyRepos)})) + cli.Print("\n%s\n\n", i18n.T("cmd.dev.repos_with_changes", map[string]any{"Count": len(dirtyRepos)})) for _, s := range dirtyRepos { cli.Print(" %s: ", repoNameStyle.Render(s.Name)) if s.Modified > 0 { - cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.modified", map[string]interface{}{"Count": s.Modified}))) + cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.modified", map[string]any{"Count": s.Modified}))) } if s.Untracked > 0 { - cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.untracked", map[string]interface{}{"Count": s.Untracked}))) + cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.untracked", map[string]any{"Count": s.Untracked}))) } if s.Staged > 0 { - cli.Print("%s ", aheadStyle.Render(i18n.T("cmd.dev.staged", map[string]interface{}{"Count": s.Staged}))) + cli.Print("%s ", aheadStyle.Render(i18n.T("cmd.dev.staged", map[string]any{"Count": s.Staged}))) } cli.Blank() } @@ -128,9 +128,9 @@ func runCommit(registryPath string, all bool) error { } // Summary - cli.Print("%s", successStyle.Render(i18n.T("cmd.dev.done_succeeded", map[string]interface{}{"Count": succeeded}))) + cli.Print("%s", successStyle.Render(i18n.T("cmd.dev.done_succeeded", map[string]any{"Count": succeeded}))) if failed > 0 { - cli.Print(", %s", errorStyle.Render(i18n.T("common.count.failed", map[string]interface{}{"Count": failed}))) + cli.Print(", %s", errorStyle.Render(i18n.T("common.count.failed", map[string]any{"Count": failed}))) } cli.Blank() @@ -170,13 +170,13 @@ func runCommitSingleRepo(ctx context.Context, repoPath string, all bool) error { // Show status cli.Print("%s: ", repoNameStyle.Render(s.Name)) if s.Modified > 0 { - cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.modified", map[string]interface{}{"Count": s.Modified}))) + cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.modified", map[string]any{"Count": s.Modified}))) } if s.Untracked > 0 { - cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.untracked", map[string]interface{}{"Count": s.Untracked}))) + cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.untracked", map[string]any{"Count": s.Untracked}))) } if s.Staged > 0 { - cli.Print("%s ", aheadStyle.Render(i18n.T("cmd.dev.staged", map[string]interface{}{"Count": s.Staged}))) + cli.Print("%s ", aheadStyle.Render(i18n.T("cmd.dev.staged", map[string]any{"Count": s.Staged}))) } cli.Blank() diff --git a/cmd/dev/cmd_file_sync.go b/cmd/dev/cmd_file_sync.go index 822d1f1..e556da2 100644 --- a/cmd/dev/cmd_file_sync.go +++ b/cmd/dev/cmd_file_sync.go @@ -82,7 +82,7 @@ func runFileSync(source string) error { // Let's stick to os.Stat for source properties finding as typically allowed for CLI args. if err != nil { - return log.E("dev.sync", i18n.T("cmd.dev.file_sync.error.source_not_found", map[string]interface{}{"Path": source}), err) + return log.E("dev.sync", i18n.T("cmd.dev.file_sync.error.source_not_found", map[string]any{"Path": source}), err) } // Find target repos @@ -185,19 +185,19 @@ func runFileSync(source string) error { cli.Blank() cli.Print("%s: ", i18n.T("cmd.dev.file_sync.summary")) if succeeded > 0 { - cli.Print("%s", successStyle.Render(i18n.T("common.count.succeeded", map[string]interface{}{"Count": succeeded}))) + cli.Print("%s", successStyle.Render(i18n.T("common.count.succeeded", map[string]any{"Count": succeeded}))) } if skipped > 0 { if succeeded > 0 { cli.Print(", ") } - cli.Print("%s", dimStyle.Render(i18n.T("common.count.skipped", map[string]interface{}{"Count": skipped}))) + cli.Print("%s", dimStyle.Render(i18n.T("common.count.skipped", map[string]any{"Count": skipped}))) } if failed > 0 { if succeeded > 0 || skipped > 0 { cli.Print(", ") } - cli.Print("%s", errorStyle.Render(i18n.T("common.count.failed", map[string]interface{}{"Count": failed}))) + cli.Print("%s", errorStyle.Render(i18n.T("common.count.failed", map[string]any{"Count": failed}))) } cli.Blank() diff --git a/cmd/dev/cmd_health.go b/cmd/dev/cmd_health.go index 1eda3b1..8eaf53b 100644 --- a/cmd/dev/cmd_health.go +++ b/cmd/dev/cmd_health.go @@ -159,7 +159,7 @@ func formatRepoList(reposList []string) string { if len(reposList) <= 5 { return joinRepos(reposList) } - return joinRepos(reposList[:5]) + " " + i18n.T("cmd.dev.health.more", map[string]interface{}{"Count": len(reposList) - 5}) + return joinRepos(reposList[:5]) + " " + i18n.T("cmd.dev.health.more", map[string]any{"Count": len(reposList) - 5}) } func joinRepos(reposList []string) string { diff --git a/cmd/dev/cmd_impact.go b/cmd/dev/cmd_impact.go index 924d888..258a924 100644 --- a/cmd/dev/cmd_impact.go +++ b/cmd/dev/cmd_impact.go @@ -2,7 +2,7 @@ package dev import ( "errors" - "sort" + "slices" "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go/pkg/i18n" @@ -62,7 +62,7 @@ func runImpact(registryPath string, repoName string) error { // Check repo exists repo, exists := reg.Get(repoName) if !exists { - return errors.New(i18n.T("error.repo_not_found", map[string]interface{}{"Name": repoName})) + return errors.New(i18n.T("error.repo_not_found", map[string]any{"Name": repoName})) } // Build reverse dependency graph @@ -86,8 +86,8 @@ func runImpact(registryPath string, repoName string) error { } // Sort for consistent output - sort.Strings(direct) - sort.Strings(indirect) + slices.Sort(direct) + slices.Sort(indirect) // Print results cli.Blank() @@ -98,7 +98,7 @@ func runImpact(registryPath string, repoName string) error { cli.Blank() if len(allAffected) == 0 { - cli.Print("%s %s\n", impactSafeStyle.Render("v"), i18n.T("cmd.dev.impact.no_dependents", map[string]interface{}{"Name": repoName})) + cli.Print("%s %s\n", impactSafeStyle.Render("v"), i18n.T("cmd.dev.impact.no_dependents", map[string]any{"Name": repoName})) return nil } @@ -106,7 +106,7 @@ func runImpact(registryPath string, repoName string) error { if len(direct) > 0 { cli.Print("%s %s\n", impactDirectStyle.Render("*"), - i18n.T("cmd.dev.impact.direct_dependents", map[string]interface{}{"Count": len(direct)}), + i18n.T("cmd.dev.impact.direct_dependents", map[string]any{"Count": len(direct)}), ) for _, d := range direct { r, _ := reg.Get(d) @@ -123,7 +123,7 @@ func runImpact(registryPath string, repoName string) error { if len(indirect) > 0 { cli.Print("%s %s\n", impactIndirectStyle.Render("o"), - i18n.T("cmd.dev.impact.transitive_dependents", map[string]interface{}{"Count": len(indirect)}), + i18n.T("cmd.dev.impact.transitive_dependents", map[string]any{"Count": len(indirect)}), ) for _, d := range indirect { r, _ := reg.Get(d) @@ -139,7 +139,7 @@ func runImpact(registryPath string, repoName string) error { // Summary cli.Print("%s %s\n", dimStyle.Render(i18n.Label("summary")), - i18n.T("cmd.dev.impact.changes_affect", map[string]interface{}{ + i18n.T("cmd.dev.impact.changes_affect", map[string]any{ "Repo": repoNameStyle.Render(repoName), "Affected": len(allAffected), "Total": len(reg.Repos) - 1, diff --git a/cmd/dev/cmd_issues.go b/cmd/dev/cmd_issues.go index 20bc169..c1b51cd 100644 --- a/cmd/dev/cmd_issues.go +++ b/cmd/dev/cmd_issues.go @@ -117,7 +117,7 @@ func runIssues(registryPath string, limit int, assignee string) error { return nil } - cli.Print("\n%s\n\n", i18n.T("cmd.dev.issues.open_issues", map[string]interface{}{"Count": len(allIssues)})) + cli.Print("\n%s\n\n", i18n.T("cmd.dev.issues.open_issues", map[string]any{"Count": len(allIssues)})) for _, issue := range allIssues { printIssue(issue) diff --git a/cmd/dev/cmd_pull.go b/cmd/dev/cmd_pull.go index 2326fc7..db46288 100644 --- a/cmd/dev/cmd_pull.go +++ b/cmd/dev/cmd_pull.go @@ -81,13 +81,13 @@ func runPull(registryPath string, all bool) error { // Show what we're pulling if all { - cli.Print("\n%s\n\n", i18n.T("cmd.dev.pull.pulling_repos", map[string]interface{}{"Count": len(toPull)})) + cli.Print("\n%s\n\n", i18n.T("cmd.dev.pull.pulling_repos", map[string]any{"Count": len(toPull)})) } else { - cli.Print("\n%s\n\n", i18n.T("cmd.dev.pull.repos_behind", map[string]interface{}{"Count": len(toPull)})) + cli.Print("\n%s\n\n", i18n.T("cmd.dev.pull.repos_behind", map[string]any{"Count": len(toPull)})) for _, s := range toPull { cli.Print(" %s: %s\n", repoNameStyle.Render(s.Name), - dimStyle.Render(i18n.T("cmd.dev.pull.commits_behind", map[string]interface{}{"Count": s.Behind})), + dimStyle.Render(i18n.T("cmd.dev.pull.commits_behind", map[string]any{"Count": s.Behind})), ) } cli.Blank() @@ -110,9 +110,9 @@ func runPull(registryPath string, all bool) error { // Summary cli.Blank() - cli.Print("%s", successStyle.Render(i18n.T("cmd.dev.pull.done_pulled", map[string]interface{}{"Count": succeeded}))) + cli.Print("%s", successStyle.Render(i18n.T("cmd.dev.pull.done_pulled", map[string]any{"Count": succeeded}))) if failed > 0 { - cli.Print(", %s", errorStyle.Render(i18n.T("common.count.failed", map[string]interface{}{"Count": failed}))) + cli.Print(", %s", errorStyle.Render(i18n.T("common.count.failed", map[string]any{"Count": failed}))) } cli.Blank() diff --git a/cmd/dev/cmd_push.go b/cmd/dev/cmd_push.go index 6523f9a..e95846b 100644 --- a/cmd/dev/cmd_push.go +++ b/cmd/dev/cmd_push.go @@ -84,12 +84,12 @@ func runPush(registryPath string, force bool) error { } // Show repos to push - cli.Print("\n%s\n\n", i18n.T("common.count.repos_unpushed", map[string]interface{}{"Count": len(aheadRepos)})) + cli.Print("\n%s\n\n", i18n.T("common.count.repos_unpushed", map[string]any{"Count": len(aheadRepos)})) totalCommits := 0 for _, s := range aheadRepos { cli.Print(" %s: %s\n", repoNameStyle.Render(s.Name), - aheadStyle.Render(i18n.T("common.count.commits", map[string]interface{}{"Count": s.Ahead})), + aheadStyle.Render(i18n.T("common.count.commits", map[string]any{"Count": s.Ahead})), ) totalCommits += s.Ahead } @@ -97,7 +97,7 @@ func runPush(registryPath string, force bool) error { // Confirm unless --force if !force { cli.Blank() - if !cli.Confirm(i18n.T("cmd.dev.push.confirm_push", map[string]interface{}{"Commits": totalCommits, "Repos": len(aheadRepos)})) { + if !cli.Confirm(i18n.T("cmd.dev.push.confirm_push", map[string]any{"Commits": totalCommits, "Repos": len(aheadRepos)})) { cli.Text(i18n.T("cli.aborted")) return nil } @@ -158,9 +158,9 @@ func runPush(registryPath string, force bool) error { // Summary cli.Blank() - cli.Print("%s", successStyle.Render(i18n.T("cmd.dev.push.done_pushed", map[string]interface{}{"Count": succeeded}))) + cli.Print("%s", successStyle.Render(i18n.T("cmd.dev.push.done_pushed", map[string]any{"Count": succeeded}))) if failed > 0 { - cli.Print(", %s", errorStyle.Render(i18n.T("common.count.failed", map[string]interface{}{"Count": failed}))) + cli.Print(", %s", errorStyle.Render(i18n.T("common.count.failed", map[string]any{"Count": failed}))) } cli.Blank() @@ -191,13 +191,13 @@ func runPushSingleRepo(ctx context.Context, repoPath string, force bool) error { if s.IsDirty() { cli.Print("%s: ", repoNameStyle.Render(s.Name)) if s.Modified > 0 { - cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.modified", map[string]interface{}{"Count": s.Modified}))) + cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.modified", map[string]any{"Count": s.Modified}))) } if s.Untracked > 0 { - cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.untracked", map[string]interface{}{"Count": s.Untracked}))) + cli.Print("%s ", dirtyStyle.Render(i18n.T("cmd.dev.untracked", map[string]any{"Count": s.Untracked}))) } if s.Staged > 0 { - cli.Print("%s ", aheadStyle.Render(i18n.T("cmd.dev.staged", map[string]interface{}{"Count": s.Staged}))) + cli.Print("%s ", aheadStyle.Render(i18n.T("cmd.dev.staged", map[string]any{"Count": s.Staged}))) } cli.Blank() cli.Blank() @@ -230,12 +230,12 @@ func runPushSingleRepo(ctx context.Context, repoPath string, force bool) error { // Show commits to push cli.Print("%s: %s\n", repoNameStyle.Render(s.Name), - aheadStyle.Render(i18n.T("common.count.commits", map[string]interface{}{"Count": s.Ahead}))) + aheadStyle.Render(i18n.T("common.count.commits", map[string]any{"Count": s.Ahead}))) // Confirm unless --force if !force { cli.Blank() - if !cli.Confirm(i18n.T("cmd.dev.push.confirm_push", map[string]interface{}{"Commits": s.Ahead, "Repos": 1})) { + if !cli.Confirm(i18n.T("cmd.dev.push.confirm_push", map[string]any{"Commits": s.Ahead, "Repos": 1})) { cli.Text(i18n.T("cli.aborted")) return nil } diff --git a/cmd/dev/cmd_reviews.go b/cmd/dev/cmd_reviews.go index 8a1f3bb..c4d8203 100644 --- a/cmd/dev/cmd_reviews.go +++ b/cmd/dev/cmd_reviews.go @@ -144,15 +144,15 @@ func runReviews(registryPath string, author string, showAll bool) error { } cli.Blank() - cli.Print("%s", i18n.T("cmd.dev.reviews.open_prs", map[string]interface{}{"Count": len(allPRs)})) + cli.Print("%s", i18n.T("cmd.dev.reviews.open_prs", map[string]any{"Count": len(allPRs)})) if pending > 0 { - cli.Print(" * %s", prPendingStyle.Render(i18n.T("common.count.pending", map[string]interface{}{"Count": pending}))) + cli.Print(" * %s", prPendingStyle.Render(i18n.T("common.count.pending", map[string]any{"Count": pending}))) } if approved > 0 { - cli.Print(" * %s", prApprovedStyle.Render(i18n.T("cmd.dev.reviews.approved", map[string]interface{}{"Count": approved}))) + cli.Print(" * %s", prApprovedStyle.Render(i18n.T("cmd.dev.reviews.approved", map[string]any{"Count": approved}))) } if changesRequested > 0 { - cli.Print(" * %s", prChangesStyle.Render(i18n.T("cmd.dev.reviews.changes_requested", map[string]interface{}{"Count": changesRequested}))) + cli.Print(" * %s", prChangesStyle.Render(i18n.T("cmd.dev.reviews.changes_requested", map[string]any{"Count": changesRequested}))) } cli.Blank() cli.Blank() diff --git a/cmd/dev/cmd_vm.go b/cmd/dev/cmd_vm.go index 207c012..4e12018 100644 --- a/cmd/dev/cmd_vm.go +++ b/cmd/dev/cmd_vm.go @@ -49,7 +49,7 @@ func runVMInstall() error { if d.IsInstalled() { cli.Text(successStyle.Render(i18n.T("cmd.dev.vm.already_installed"))) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.check_updates", map[string]interface{}{"Command": dimStyle.Render("core dev update")})) + cli.Text(i18n.T("cmd.dev.vm.check_updates", map[string]any{"Command": dimStyle.Render("core dev update")})) return nil } @@ -80,9 +80,9 @@ func runVMInstall() error { elapsed := time.Since(start).Round(time.Second) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.installed_in", map[string]interface{}{"Duration": elapsed})) + cli.Text(i18n.T("cmd.dev.vm.installed_in", map[string]any{"Duration": elapsed})) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.start_with", map[string]interface{}{"Command": dimStyle.Render("core dev boot")})) + cli.Text(i18n.T("cmd.dev.vm.start_with", map[string]any{"Command": dimStyle.Render("core dev boot")})) return nil } @@ -131,7 +131,7 @@ func runVMBoot(memory, cpus int, fresh bool) error { } opts.Fresh = fresh - cli.Print("%s %s\n", dimStyle.Render(i18n.T("cmd.dev.vm.config_label")), i18n.T("cmd.dev.vm.config_value", map[string]interface{}{"Memory": opts.Memory, "CPUs": opts.CPUs})) + cli.Print("%s %s\n", dimStyle.Render(i18n.T("cmd.dev.vm.config_label")), i18n.T("cmd.dev.vm.config_value", map[string]any{"Memory": opts.Memory, "CPUs": opts.CPUs})) cli.Blank() cli.Text(i18n.T("cmd.dev.vm.booting")) @@ -143,7 +143,7 @@ func runVMBoot(memory, cpus int, fresh bool) error { cli.Blank() cli.Text(successStyle.Render(i18n.T("cmd.dev.vm.running"))) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.connect_with", map[string]interface{}{"Command": dimStyle.Render("core dev shell")})) + cli.Text(i18n.T("cmd.dev.vm.connect_with", map[string]any{"Command": dimStyle.Render("core dev shell")})) cli.Print("%s %s\n", i18n.T("cmd.dev.vm.ssh_port"), dimStyle.Render("2222")) return nil @@ -228,7 +228,7 @@ func runVMStatus() error { } else { cli.Print("%s %s\n", dimStyle.Render(i18n.T("cmd.dev.vm.installed_label")), errorStyle.Render(i18n.T("cmd.dev.vm.installed_no"))) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.install_with", map[string]interface{}{"Command": dimStyle.Render("core dev install")})) + cli.Text(i18n.T("cmd.dev.vm.install_with", map[string]any{"Command": dimStyle.Render("core dev install")})) return nil } @@ -245,7 +245,7 @@ func runVMStatus() error { } else { cli.Print("%s %s\n", dimStyle.Render(i18n.Label("status")), dimStyle.Render(i18n.T("common.status.stopped"))) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.start_with", map[string]interface{}{"Command": dimStyle.Render("core dev boot")})) + cli.Text(i18n.T("cmd.dev.vm.start_with", map[string]any{"Command": dimStyle.Render("core dev boot")})) } return nil @@ -474,7 +474,7 @@ func runVMUpdate(apply bool) error { cli.Blank() if !apply { - cli.Text(i18n.T("cmd.dev.vm.run_to_update", map[string]interface{}{"Command": dimStyle.Render("core dev update --apply")})) + cli.Text(i18n.T("cmd.dev.vm.run_to_update", map[string]any{"Command": dimStyle.Render("core dev update --apply")})) return nil } @@ -504,7 +504,7 @@ func runVMUpdate(apply bool) error { elapsed := time.Since(start).Round(time.Second) cli.Blank() - cli.Text(i18n.T("cmd.dev.vm.updated_in", map[string]interface{}{"Duration": elapsed})) + cli.Text(i18n.T("cmd.dev.vm.updated_in", map[string]any{"Duration": elapsed})) return nil } diff --git a/cmd/dev/cmd_work.go b/cmd/dev/cmd_work.go index e602999..5fb458f 100644 --- a/cmd/dev/cmd_work.go +++ b/cmd/dev/cmd_work.go @@ -174,9 +174,9 @@ func runWork(registryPath string, statusOnly, autoCommit bool) error { } cli.Blank() - cli.Print("%s\n", i18n.T("common.count.repos_unpushed", map[string]interface{}{"Count": len(aheadRepos)})) + cli.Print("%s\n", i18n.T("common.count.repos_unpushed", map[string]any{"Count": len(aheadRepos)})) for _, s := range aheadRepos { - cli.Print(" %s: %s\n", s.Name, i18n.T("common.count.commits", map[string]interface{}{"Count": s.Ahead})) + cli.Print(" %s: %s\n", s.Name, i18n.T("common.count.commits", map[string]any{"Count": s.Ahead})) } cli.Blank() diff --git a/cmd/dev/cmd_workflow.go b/cmd/dev/cmd_workflow.go index 18dae0e..b003d36 100644 --- a/cmd/dev/cmd_workflow.go +++ b/cmd/dev/cmd_workflow.go @@ -151,7 +151,7 @@ func runWorkflowSync(registryPath string, workflowFile string, dryRun bool) erro // Find the template workflow templatePath := findTemplateWorkflow(registryDir, workflowFile) if templatePath == "" { - return cli.Err("%s", i18n.T("cmd.dev.workflow.template_not_found", map[string]interface{}{"File": workflowFile})) + return cli.Err("%s", i18n.T("cmd.dev.workflow.template_not_found", map[string]any{"File": workflowFile})) } // Read template content @@ -240,15 +240,15 @@ func runWorkflowSync(registryPath string, workflowFile string, dryRun bool) erro // Summary if dryRun { cli.Print("%s %s\n", - i18n.T("cmd.dev.workflow.would_sync_count", map[string]interface{}{"Count": synced}), - dimStyle.Render(i18n.T("cmd.dev.workflow.skipped_count", map[string]interface{}{"Count": skipped}))) + i18n.T("cmd.dev.workflow.would_sync_count", map[string]any{"Count": synced}), + dimStyle.Render(i18n.T("cmd.dev.workflow.skipped_count", map[string]any{"Count": skipped}))) cli.Text(i18n.T("cmd.dev.workflow.run_without_dry_run")) } else { cli.Print("%s %s\n", - successStyle.Render(i18n.T("cmd.dev.workflow.synced_count", map[string]interface{}{"Count": synced})), - dimStyle.Render(i18n.T("cmd.dev.workflow.skipped_count", map[string]interface{}{"Count": skipped}))) + successStyle.Render(i18n.T("cmd.dev.workflow.synced_count", map[string]any{"Count": synced})), + dimStyle.Render(i18n.T("cmd.dev.workflow.skipped_count", map[string]any{"Count": skipped}))) if failed > 0 { - cli.Print("%s\n", errorStyle.Render(i18n.T("cmd.dev.workflow.failed_count", map[string]interface{}{"Count": failed}))) + cli.Print("%s\n", errorStyle.Render(i18n.T("cmd.dev.workflow.failed_count", map[string]any{"Count": failed}))) } } diff --git a/cmd/docs/cmd_list.go b/cmd/docs/cmd_list.go index efa89e7..454f2fc 100644 --- a/cmd/docs/cmd_list.go +++ b/cmd/docs/cmd_list.go @@ -48,7 +48,7 @@ func runDocsList(registryPath string) error { docsDir := checkMark(false) if len(info.DocsFiles) > 0 { - docsDir = docsFoundStyle.Render(i18n.T("common.count.files", map[string]interface{}{"Count": len(info.DocsFiles)})) + docsDir = docsFoundStyle.Render(i18n.T("common.count.files", map[string]any{"Count": len(info.DocsFiles)})) } cli.Print("%-20s %-8s %-8s %-10s %s\n", @@ -69,7 +69,7 @@ func runDocsList(registryPath string) error { cli.Blank() cli.Print("%s %s\n", cli.KeyStyle.Render(i18n.Label("coverage")), - i18n.T("cmd.docs.list.coverage_summary", map[string]interface{}{"WithDocs": withDocs, "WithoutDocs": withoutDocs}), + i18n.T("cmd.docs.list.coverage_summary", map[string]any{"WithDocs": withDocs, "WithoutDocs": withoutDocs}), ) return nil diff --git a/cmd/docs/cmd_sync.go b/cmd/docs/cmd_sync.go index 3e28295..988576d 100644 --- a/cmd/docs/cmd_sync.go +++ b/cmd/docs/cmd_sync.go @@ -99,7 +99,7 @@ func runPHPSync(reg *repos.Registry, basePath string, outputDir string, dryRun b return nil } - cli.Print("\n%s %s\n\n", dimStyle.Render(i18n.T("cmd.docs.sync.found_label")), i18n.T("cmd.docs.sync.repos_with_docs", map[string]interface{}{"Count": len(docsInfo)})) + cli.Print("\n%s %s\n\n", dimStyle.Render(i18n.T("cmd.docs.sync.found_label")), i18n.T("cmd.docs.sync.repos_with_docs", map[string]any{"Count": len(docsInfo)})) // Show what will be synced var totalFiles int @@ -109,7 +109,7 @@ func runPHPSync(reg *repos.Registry, basePath string, outputDir string, dryRun b cli.Print(" %s → %s %s\n", repoNameStyle.Render(info.Name), docsFileStyle.Render("packages/"+outName+"/"), - dimStyle.Render(i18n.T("cmd.docs.sync.files_count", map[string]interface{}{"Count": len(info.DocsFiles)}))) + dimStyle.Render(i18n.T("cmd.docs.sync.files_count", map[string]any{"Count": len(info.DocsFiles)}))) for _, f := range info.DocsFiles { cli.Print(" %s\n", dimStyle.Render(f)) @@ -118,7 +118,7 @@ func runPHPSync(reg *repos.Registry, basePath string, outputDir string, dryRun b cli.Print("\n%s %s\n", dimStyle.Render(i18n.Label("total")), - i18n.T("cmd.docs.sync.total_summary", map[string]interface{}{"Files": totalFiles, "Repos": len(docsInfo), "Output": outputDir})) + i18n.T("cmd.docs.sync.total_summary", map[string]any{"Files": totalFiles, "Repos": len(docsInfo), "Output": outputDir})) if dryRun { cli.Print("\n%s\n", dimStyle.Render(i18n.T("cmd.docs.sync.dry_run_notice"))) @@ -167,7 +167,7 @@ func runPHPSync(reg *repos.Registry, basePath string, outputDir string, dryRun b synced++ } - cli.Print("\n%s %s\n", successStyle.Render(i18n.T("i18n.done.sync")), i18n.T("cmd.docs.sync.synced_packages", map[string]interface{}{"Count": synced})) + cli.Print("\n%s %s\n", successStyle.Render(i18n.T("i18n.done.sync")), i18n.T("cmd.docs.sync.synced_packages", map[string]any{"Count": synced})) return nil } diff --git a/cmd/prod/cmd_dns.go b/cmd/prod/cmd_dns.go index c99e98e..32d71a4 100644 --- a/cmd/prod/cmd_dns.go +++ b/cmd/prod/cmd_dns.go @@ -2,6 +2,7 @@ package prod import ( "context" + "errors" "fmt" "os" "time" @@ -56,7 +57,7 @@ func getDNSClient() (*infra.CloudNSClient, error) { authID := os.Getenv("CLOUDNS_AUTH_ID") authPass := os.Getenv("CLOUDNS_AUTH_PASSWORD") if authID == "" || authPass == "" { - return nil, fmt.Errorf("CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required") + return nil, errors.New("CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required") } return infra.NewCloudNSClient(authID, authPass), nil } diff --git a/cmd/prod/cmd_lb.go b/cmd/prod/cmd_lb.go index 58e0c21..e9d169c 100644 --- a/cmd/prod/cmd_lb.go +++ b/cmd/prod/cmd_lb.go @@ -2,6 +2,7 @@ package prod import ( "context" + "errors" "fmt" "os" "time" @@ -39,7 +40,7 @@ func init() { func getHCloudClient() (*infra.HCloudClient, error) { token := os.Getenv("HCLOUD_TOKEN") if token == "" { - return nil, fmt.Errorf("HCLOUD_TOKEN environment variable required") + return nil, errors.New("HCLOUD_TOKEN environment variable required") } return infra.NewHCloudClient(token), nil } diff --git a/cmd/prod/cmd_setup.go b/cmd/prod/cmd_setup.go index d31bfec..91a72b4 100644 --- a/cmd/prod/cmd_setup.go +++ b/cmd/prod/cmd_setup.go @@ -2,6 +2,7 @@ package prod import ( "context" + "errors" "fmt" "os" "time" @@ -141,7 +142,7 @@ func stepDiscover(ctx context.Context, cfg *infra.Config) error { func stepLoadBalancer(ctx context.Context, cfg *infra.Config) error { hcloudToken := os.Getenv("HCLOUD_TOKEN") if hcloudToken == "" { - return fmt.Errorf("HCLOUD_TOKEN required for load balancer management") + return errors.New("HCLOUD_TOKEN required for load balancer management") } hc := infra.NewHCloudClient(hcloudToken) @@ -237,7 +238,7 @@ func stepDNS(ctx context.Context, cfg *infra.Config) error { authID := os.Getenv("CLOUDNS_AUTH_ID") authPass := os.Getenv("CLOUDNS_AUTH_PASSWORD") if authID == "" || authPass == "" { - return fmt.Errorf("CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required") + return errors.New("CLOUDNS_AUTH_ID and CLOUDNS_AUTH_PASSWORD required") } dns := infra.NewCloudNSClient(authID, authPass) diff --git a/cmd/qa/cmd_watch.go b/cmd/qa/cmd_watch.go index dc35c22..a4cebb8 100644 --- a/cmd/qa/cmd_watch.go +++ b/cmd/qa/cmd_watch.go @@ -115,7 +115,7 @@ func runWatch() error { // Check if context deadline exceeded if ctx.Err() != nil { cli.Blank() - return log.E("qa.watch", i18n.T("cmd.qa.watch.timeout", map[string]interface{}{"Duration": watchTimeout}), nil) + return log.E("qa.watch", i18n.T("cmd.qa.watch.timeout", map[string]any{"Duration": watchTimeout}), nil) } runs, err := fetchWorkflowRunsForCommit(ctx, repoFullName, commitSha) @@ -335,7 +335,7 @@ func printResults(ctx context.Context, repoFullName string, runs []WorkflowRun) // Exit with error if any failures if len(failures) > 0 { cli.Blank() - return cli.Err("%s", i18n.T("cmd.qa.watch.workflows_failed", map[string]interface{}{"Count": len(failures)})) + return cli.Err("%s", i18n.T("cmd.qa.watch.workflows_failed", map[string]any{"Count": len(failures)})) } cli.Blank() diff --git a/cmd/setup/cmd_github.go b/cmd/setup/cmd_github.go index 5ca342e..6c9b5da 100644 --- a/cmd/setup/cmd_github.go +++ b/cmd/setup/cmd_github.go @@ -126,7 +126,7 @@ func runGitHubSetup() error { // Single repo mode repo, ok := reg.Get(ghRepo) if !ok { - return errors.New(i18n.T("error.repo_not_found", map[string]interface{}{"Name": ghRepo})) + return errors.New(i18n.T("error.repo_not_found", map[string]any{"Name": ghRepo})) } reposToProcess = []*repos.Repo{repo} } else if ghAll { diff --git a/cmd/setup/cmd_registry.go b/cmd/setup/cmd_registry.go index 8597201..9b0577f 100644 --- a/cmd/setup/cmd_registry.go +++ b/cmd/setup/cmd_registry.go @@ -159,9 +159,9 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP // Summary fmt.Println() fmt.Printf("%s, %s, %s\n", - i18n.T("cmd.setup.to_clone", map[string]interface{}{"Count": len(toClone)}), - i18n.T("cmd.setup.exist", map[string]interface{}{"Count": exists}), - i18n.T("common.count.skipped", map[string]interface{}{"Count": skipped})) + i18n.T("cmd.setup.to_clone", map[string]any{"Count": len(toClone)}), + i18n.T("cmd.setup.exist", map[string]any{"Count": exists}), + i18n.T("common.count.skipped", map[string]any{"Count": skipped})) if len(toClone) == 0 { fmt.Printf("\n%s\n", i18n.T("cmd.setup.nothing_to_clone")) @@ -209,12 +209,12 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP // Summary fmt.Println() - fmt.Printf("%s %s", successStyle.Render(i18n.Label("done")), i18n.T("cmd.setup.cloned_count", map[string]interface{}{"Count": succeeded})) + fmt.Printf("%s %s", successStyle.Render(i18n.Label("done")), i18n.T("cmd.setup.cloned_count", map[string]any{"Count": succeeded})) if failed > 0 { fmt.Printf(", %s", errorStyle.Render(i18n.T("i18n.count.failed", failed))) } if exists > 0 { - fmt.Printf(", %s", i18n.T("cmd.setup.already_exist_count", map[string]interface{}{"Count": exists})) + fmt.Printf(", %s", i18n.T("cmd.setup.already_exist_count", map[string]any{"Count": exists})) } fmt.Println() diff --git a/cmd/setup/cmd_wizard.go b/cmd/setup/cmd_wizard.go index 35e747a..36ee6f6 100644 --- a/cmd/setup/cmd_wizard.go +++ b/cmd/setup/cmd_wizard.go @@ -89,6 +89,6 @@ func runPackageWizard(reg *repos.Registry, preselectedTypes []string) ([]string, // confirmClone asks for confirmation before cloning. func confirmClone(count int, target string) (bool, error) { - confirmed := cli.Confirm(i18n.T("cmd.setup.wizard.confirm_clone", map[string]interface{}{"Count": count, "Target": target})) + confirmed := cli.Confirm(i18n.T("cmd.setup.wizard.confirm_clone", map[string]any{"Count": count, "Target": target})) return confirmed, nil } diff --git a/cmd/setup/github_diff.go b/cmd/setup/github_diff.go index 0a5af7c..2eaca66 100644 --- a/cmd/setup/github_diff.go +++ b/cmd/setup/github_diff.go @@ -4,7 +4,8 @@ package setup import ( "fmt" - "sort" + "maps" + "slices" "strings" "forge.lthn.ai/core/cli/pkg/cli" @@ -184,12 +185,7 @@ func (cs *ChangeSet) printByCategory(category ChangeCategory, title string) { fmt.Println() // Print details (sorted for deterministic output) - keys := make([]string, 0, len(c.Details)) - for k := range c.Details { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { + for _, k := range slices.Sorted(maps.Keys(c.Details)) { fmt.Printf(" %s: %s\n", dimStyle.Render(k), c.Details[k]) } } diff --git a/cmd/setup/github_protection.go b/cmd/setup/github_protection.go index 047a17c..56622e4 100644 --- a/cmd/setup/github_protection.go +++ b/cmd/setup/github_protection.go @@ -105,7 +105,7 @@ func SetBranchProtection(repoFullName, branch string, config BranchProtectionCon } // Build the protection payload - payload := map[string]interface{}{ + payload := map[string]any{ "enforce_admins": config.EnforceAdmins, "required_linear_history": config.RequireLinearHistory, "allow_force_pushes": config.AllowForcePushes, @@ -115,7 +115,7 @@ func SetBranchProtection(repoFullName, branch string, config BranchProtectionCon // Required pull request reviews if config.RequiredReviews > 0 { - payload["required_pull_request_reviews"] = map[string]interface{}{ + payload["required_pull_request_reviews"] = map[string]any{ "dismiss_stale_reviews": config.DismissStale, "require_code_owner_reviews": config.RequireCodeOwnerReviews, "required_approving_review_count": config.RequiredReviews, @@ -126,7 +126,7 @@ func SetBranchProtection(repoFullName, branch string, config BranchProtectionCon // Required status checks if len(config.RequiredStatusChecks) > 0 { - payload["required_status_checks"] = map[string]interface{}{ + payload["required_status_checks"] = map[string]any{ "strict": true, "contexts": config.RequiredStatusChecks, } diff --git a/cmd/setup/github_security.go b/cmd/setup/github_security.go index a268902..3a37d95 100644 --- a/cmd/setup/github_security.go +++ b/cmd/setup/github_security.go @@ -154,8 +154,8 @@ func UpdateSecurityAndAnalysis(repoFullName string, secretScanning, pushProtecti } // Build the payload - payload := map[string]interface{}{ - "security_and_analysis": map[string]interface{}{ + payload := map[string]any{ + "security_and_analysis": map[string]any{ "secret_scanning": map[string]string{ "status": boolToStatus(secretScanning), }, diff --git a/cmd/setup/github_webhooks.go b/cmd/setup/github_webhooks.go index 48ce7e4..a530ef3 100644 --- a/cmd/setup/github_webhooks.go +++ b/cmd/setup/github_webhooks.go @@ -69,11 +69,11 @@ func CreateWebhook(repoFullName string, name string, config WebhookConfig) error } // Build the webhook payload - payload := map[string]interface{}{ + payload := map[string]any{ "name": "web", "active": true, "events": config.Events, - "config": map[string]interface{}{ + "config": map[string]any{ "url": config.URL, "content_type": config.ContentType, "insecure_ssl": "0", @@ -85,7 +85,7 @@ func CreateWebhook(repoFullName string, name string, config WebhookConfig) error } if config.Secret != "" { - configMap := payload["config"].(map[string]interface{}) + configMap := payload["config"].(map[string]any) configMap["secret"] = config.Secret } @@ -111,10 +111,10 @@ func UpdateWebhook(repoFullName string, hookID int, config WebhookConfig) error return fmt.Errorf("invalid repo format: %s", repoFullName) } - payload := map[string]interface{}{ + payload := map[string]any{ "active": true, "events": config.Events, - "config": map[string]interface{}{ + "config": map[string]any{ "url": config.URL, "content_type": config.ContentType, "insecure_ssl": "0", @@ -126,7 +126,7 @@ func UpdateWebhook(repoFullName string, hookID int, config WebhookConfig) error } if config.Secret != "" { - configMap := payload["config"].(map[string]interface{}) + configMap := payload["config"].(map[string]any) configMap["secret"] = config.Secret } diff --git a/cmd/vm/cmd_container.go b/cmd/vm/cmd_container.go index 805990e..9a4e7cc 100644 --- a/cmd/vm/cmd_container.go +++ b/cmd/vm/cmd_container.go @@ -99,8 +99,8 @@ func runContainer(image, name string, detach bool, memory, cpus, sshPort int) er fmt.Printf("%s %s\n", successStyle.Render(i18n.Label("started")), c.ID) fmt.Printf("%s %d\n", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID) fmt.Println() - fmt.Println(i18n.T("cmd.vm.hint.view_logs", map[string]interface{}{"ID": c.ID[:8]})) - fmt.Println(i18n.T("cmd.vm.hint.stop", map[string]interface{}{"ID": c.ID[:8]})) + fmt.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": c.ID[:8]})) + fmt.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": c.ID[:8]})) } else { fmt.Printf("\n%s %s\n", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID) } @@ -261,11 +261,11 @@ func resolveContainerID(manager *container.LinuxKitManager, partialID string) (s switch len(matches) { case 0: - return "", errors.New(i18n.T("cmd.vm.error.no_match", map[string]interface{}{"ID": partialID})) + return "", errors.New(i18n.T("cmd.vm.error.no_match", map[string]any{"ID": partialID})) case 1: return matches[0].ID, nil default: - return "", errors.New(i18n.T("cmd.vm.error.multiple_match", map[string]interface{}{"ID": partialID})) + return "", errors.New(i18n.T("cmd.vm.error.multiple_match", map[string]any{"ID": partialID})) } } diff --git a/cmd/vm/cmd_templates.go b/cmd/vm/cmd_templates.go index d8a4e87..bc61403 100644 --- a/cmd/vm/cmd_templates.go +++ b/cmd/vm/cmd_templates.go @@ -204,8 +204,8 @@ func RunFromTemplate(templateName string, vars map[string]string, runOpts contai fmt.Printf("%s %s\n", successStyle.Render(i18n.T("common.label.started")), c.ID) fmt.Printf("%s %d\n", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID) fmt.Println() - fmt.Println(i18n.T("cmd.vm.hint.view_logs", map[string]interface{}{"ID": c.ID[:8]})) - fmt.Println(i18n.T("cmd.vm.hint.stop", map[string]interface{}{"ID": c.ID[:8]})) + fmt.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": c.ID[:8]})) + fmt.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": c.ID[:8]})) } else { fmt.Printf("\n%s %s\n", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID) } diff --git a/container/hypervisor.go b/container/hypervisor.go index dbf151f..4c23dac 100644 --- a/container/hypervisor.go +++ b/container/hypervisor.go @@ -2,6 +2,7 @@ package container import ( "context" + "errors" "fmt" "os" "os/exec" @@ -249,7 +250,7 @@ func DetectHypervisor() (Hypervisor, error) { return qemu, nil } - return nil, fmt.Errorf("no hypervisor available: install qemu or hyperkit (macOS)") + return nil, errors.New("no hypervisor available: install qemu or hyperkit (macOS)") } // GetHypervisor returns a specific hypervisor by name. @@ -258,13 +259,13 @@ func GetHypervisor(name string) (Hypervisor, error) { case "qemu": h := NewQemuHypervisor() if !h.Available() { - return nil, fmt.Errorf("qemu is not available") + return nil, errors.New("qemu is not available") } return h, nil case "hyperkit": h := NewHyperkitHypervisor() if !h.Available() { - return nil, fmt.Errorf("hyperkit is not available (requires macOS)") + return nil, errors.New("hyperkit is not available (requires macOS)") } return h, nil default: diff --git a/deploy/coolify/client.go b/deploy/coolify/client.go index c1b849a..1663561 100644 --- a/deploy/coolify/client.go +++ b/deploy/coolify/client.go @@ -3,6 +3,7 @@ package coolify import ( "context" "encoding/json" + "errors" "fmt" "os" "sync" @@ -41,10 +42,10 @@ func DefaultConfig() Config { // NewClient creates a new Coolify client. func NewClient(cfg Config) (*Client, error) { if cfg.BaseURL == "" { - return nil, fmt.Errorf("COOLIFY_URL not set") + return nil, errors.New("COOLIFY_URL not set") } if cfg.APIToken == "" { - return nil, fmt.Errorf("COOLIFY_TOKEN not set") + return nil, errors.New("COOLIFY_TOKEN not set") } // Initialize Python runtime diff --git a/devkit/devkit.go b/devkit/devkit.go index d7866ee..466cafc 100644 --- a/devkit/devkit.go +++ b/devkit/devkit.go @@ -155,7 +155,7 @@ func (t *Toolkit) FindTODOs(dir string) ([]TODO, error) { return nil, nil } if err != nil && exitCode != 1 { - return nil, fmt.Errorf("git grep failed (exit %d): %s\n%s", exitCode, err, stderr) + return nil, fmt.Errorf("git grep failed (exit %d): %w\n%s", exitCode, err, stderr) } var todos []TODO @@ -191,7 +191,7 @@ func (t *Toolkit) FindTODOs(dir string) ([]TODO, error) { func (t *Toolkit) AuditDeps() ([]Vulnerability, error) { stdout, stderr, exitCode, err := t.Run("govulncheck", "./...") if err != nil && exitCode != 0 && !strings.Contains(stdout, "Vulnerability") { - return nil, fmt.Errorf("govulncheck failed (exit %d): %s\n%s", exitCode, err, stderr) + return nil, fmt.Errorf("govulncheck failed (exit %d): %w\n%s", exitCode, err, stderr) } var vulns []Vulnerability @@ -240,7 +240,7 @@ func (t *Toolkit) AuditDeps() ([]Vulnerability, error) { func (t *Toolkit) DiffStat() (DiffSummary, error) { stdout, stderr, exitCode, err := t.Run("git", "diff", "--stat") if err != nil && exitCode != 0 { - return DiffSummary{}, fmt.Errorf("git diff failed (exit %d): %s\n%s", exitCode, err, stderr) + return DiffSummary{}, fmt.Errorf("git diff failed (exit %d): %w\n%s", exitCode, err, stderr) } var s DiffSummary @@ -273,7 +273,7 @@ func (t *Toolkit) DiffStat() (DiffSummary, error) { func (t *Toolkit) UncommittedFiles() ([]string, error) { stdout, stderr, exitCode, err := t.Run("git", "status", "--porcelain") if err != nil && exitCode != 0 { - return nil, fmt.Errorf("git status failed: %s\n%s", err, stderr) + return nil, fmt.Errorf("git status failed: %w\n%s", err, stderr) } var files []string for line := range strings.SplitSeq(strings.TrimSpace(stdout), "\n") { @@ -371,7 +371,7 @@ func (t *Toolkit) Build(targets ...string) ([]BuildResult, error) { func (t *Toolkit) TestCount(pkg string) (int, error) { stdout, stderr, exitCode, err := t.Run("go", "test", "-list", ".*", pkg) if err != nil && exitCode != 0 { - return 0, fmt.Errorf("go test -list failed: %s\n%s", err, stderr) + return 0, fmt.Errorf("go test -list failed: %w\n%s", err, stderr) } count := 0 for line := range strings.SplitSeq(strings.TrimSpace(stdout), "\n") { @@ -389,7 +389,7 @@ func (t *Toolkit) Coverage(pkg string) ([]CoverageReport, error) { } stdout, stderr, exitCode, err := t.Run("go", "test", "-cover", pkg) if err != nil && exitCode != 0 && !strings.Contains(stdout, "coverage:") { - return nil, fmt.Errorf("go test -cover failed (exit %d): %s\n%s", exitCode, err, stderr) + return nil, fmt.Errorf("go test -cover failed (exit %d): %w\n%s", exitCode, err, stderr) } var reports []CoverageReport @@ -443,7 +443,7 @@ func (t *Toolkit) RaceDetect(pkg string) ([]RaceCondition, error) { func (t *Toolkit) Complexity(threshold int) ([]ComplexFunc, error) { stdout, stderr, exitCode, err := t.Run("gocyclo", "-over", strconv.Itoa(threshold), ".") if err != nil && exitCode == -1 { - return nil, fmt.Errorf("gocyclo not available: %s\n%s", err, stderr) + return nil, fmt.Errorf("gocyclo not available: %w\n%s", err, stderr) } var funcs []ComplexFunc @@ -476,7 +476,7 @@ func (t *Toolkit) Complexity(threshold int) ([]ComplexFunc, error) { func (t *Toolkit) DepGraph(pkg string) (*Graph, error) { stdout, stderr, exitCode, err := t.Run("go", "mod", "graph") if err != nil && exitCode != 0 { - return nil, fmt.Errorf("go mod graph failed (exit %d): %s\n%s", exitCode, err, stderr) + return nil, fmt.Errorf("go mod graph failed (exit %d): %w\n%s", exitCode, err, stderr) } graph := &Graph{Edges: make(map[string][]string)} @@ -503,7 +503,7 @@ func (t *Toolkit) DepGraph(pkg string) (*Graph, error) { func (t *Toolkit) GitLog(n int) ([]Commit, error) { stdout, stderr, exitCode, err := t.Run("git", "log", fmt.Sprintf("-n%d", n), "--format=%H|%an|%aI|%s") if err != nil && exitCode != 0 { - return nil, fmt.Errorf("git log failed (exit %d): %s\n%s", exitCode, err, stderr) + return nil, fmt.Errorf("git log failed (exit %d): %w\n%s", exitCode, err, stderr) } var commits []Commit diff --git a/devops/devops.go b/devops/devops.go index 52ea755..f54b10e 100644 --- a/devops/devops.go +++ b/devops/devops.go @@ -3,6 +3,7 @@ package devops import ( "context" + "errors" "fmt" "os" "path/filepath" @@ -116,14 +117,14 @@ func DefaultBootOptions() BootOptions { // Boot starts the dev environment. func (d *DevOps) Boot(ctx context.Context, opts BootOptions) error { if !d.images.IsInstalled() { - return fmt.Errorf("dev image not installed (run 'core dev install' first)") + return errors.New("dev image not installed (run 'core dev install' first)") } // Check if already running if !opts.Fresh { running, err := d.IsRunning(ctx) if err == nil && running { - return fmt.Errorf("dev environment already running (use 'core dev stop' first or --fresh)") + return errors.New("dev environment already running (use 'core dev stop' first or --fresh)") } } @@ -177,7 +178,7 @@ func (d *DevOps) Stop(ctx context.Context) error { return err } if c == nil { - return fmt.Errorf("dev environment not found") + return errors.New("dev environment not found") } return d.container.Stop(ctx, c.ID) } diff --git a/devops/images.go b/devops/images.go index 8a6b46d..d7f984f 100644 --- a/devops/images.go +++ b/devops/images.go @@ -3,6 +3,7 @@ package devops import ( "context" "encoding/json" + "errors" "fmt" "os" "path/filepath" @@ -109,7 +110,7 @@ func (m *ImageManager) Install(ctx context.Context, progress func(downloaded, to } } if src == nil { - return fmt.Errorf("no image source available") + return errors.New("no image source available") } // Get version @@ -139,7 +140,7 @@ func (m *ImageManager) Install(ctx context.Context, progress func(downloaded, to func (m *ImageManager) CheckUpdate(ctx context.Context) (current, latest string, hasUpdate bool, err error) { info, ok := m.manifest.Images[ImageName()] if !ok { - return "", "", false, fmt.Errorf("image not installed") + return "", "", false, errors.New("image not installed") } current = info.Version @@ -152,7 +153,7 @@ func (m *ImageManager) CheckUpdate(ctx context.Context) (current, latest string, } } if src == nil { - return current, "", false, fmt.Errorf("no image source available") + return current, "", false, errors.New("no image source available") } latest, err = src.LatestVersion(ctx) diff --git a/devops/serve.go b/devops/serve.go index 6eeb1fa..f81ec69 100644 --- a/devops/serve.go +++ b/devops/serve.go @@ -2,6 +2,7 @@ package devops import ( "context" + "errors" "fmt" "os" "os/exec" @@ -23,7 +24,7 @@ func (d *DevOps) Serve(ctx context.Context, projectDir string, opts ServeOptions return err } if !running { - return fmt.Errorf("dev environment not running (run 'core dev boot' first)") + return errors.New("dev environment not running (run 'core dev boot' first)") } if opts.Port == 0 { diff --git a/devops/shell.go b/devops/shell.go index fe94d1b..512226f 100644 --- a/devops/shell.go +++ b/devops/shell.go @@ -2,6 +2,7 @@ package devops import ( "context" + "errors" "fmt" "os" "os/exec" @@ -20,7 +21,7 @@ func (d *DevOps) Shell(ctx context.Context, opts ShellOptions) error { return err } if !running { - return fmt.Errorf("dev environment not running (run 'core dev boot' first)") + return errors.New("dev environment not running (run 'core dev boot' first)") } if opts.Console { @@ -61,7 +62,7 @@ func (d *DevOps) serialConsole(ctx context.Context) error { return err } if c == nil { - return fmt.Errorf("console not available: container not found") + return errors.New("console not available: container not found") } // Use socat to connect to the console socket diff --git a/devops/ssh_utils.go b/devops/ssh_utils.go index d05902b..90a3399 100644 --- a/devops/ssh_utils.go +++ b/devops/ssh_utils.go @@ -2,6 +2,7 @@ package devops import ( "context" + "errors" "fmt" "os" "os/exec" @@ -37,7 +38,7 @@ func ensureHostKey(ctx context.Context, port int) error { } if len(out) == 0 { - return fmt.Errorf("ssh-keyscan returned no keys") + return errors.New("ssh-keyscan returned no keys") } // Read existing known_hosts to avoid duplicates diff --git a/devops/test.go b/devops/test.go index 430579c..735c29b 100644 --- a/devops/test.go +++ b/devops/test.go @@ -3,6 +3,7 @@ package devops import ( "context" "encoding/json" + "errors" "fmt" "path/filepath" "strings" @@ -38,7 +39,7 @@ func (d *DevOps) Test(ctx context.Context, projectDir string, opts TestOptions) return err } if !running { - return fmt.Errorf("dev environment not running (run 'core dev boot' first)") + return errors.New("dev environment not running (run 'core dev boot' first)") } var cmd string @@ -63,7 +64,7 @@ func (d *DevOps) Test(ctx context.Context, projectDir string, opts TestOptions) } else { cmd = DetectTestCommand(d.medium, projectDir) if cmd == "" { - return fmt.Errorf("could not detect test command (create .core/test.yaml)") + return errors.New("could not detect test command (create .core/test.yaml)") } } @@ -177,7 +178,7 @@ func hasComposerScript(m io.Medium, projectDir, script string) bool { } var pkg struct { - Scripts map[string]interface{} `json:"scripts"` + Scripts map[string]any `json:"scripts"` } if err := json.Unmarshal([]byte(content), &pkg); err != nil { return false diff --git a/go.sum b/go.sum index 2522fe1..9f7ad96 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ forge.lthn.ai/core/cli v0.0.3 h1:Qd/ACf8as4cwWoqAzkLIPF86NhXzfkkt1t/6xmgznVw= forge.lthn.ai/core/cli v0.0.3/go.mod h1:xa3Nqw3sUtYYJ1k+1jYul18tgs6sBevCUsGsHJI1hHA= forge.lthn.ai/core/go v0.0.1 h1:ubk4nmkA3treOUNgPS28wKd1jB6cUlEQUV7jDdGa3zM= forge.lthn.ai/core/go v0.0.1/go.mod h1:59YsnuMaAGQUxIhX68oK2/HnhQJEPWL1iEZhDTrNCbY= -forge.lthn.ai/core/go-agentic v0.0.2 h1:dsngOpUp8ATUWlM1O8gqFgS4FLJG0ngDvsXNQJigBDA= -forge.lthn.ai/core/go-agentic v0.0.2/go.mod h1:KwalcfzQACtedb7wNe/7U/59PtdpvezqMJmmvhTptOY= +forge.lthn.ai/core/go-agentic v0.0.2 h1:G2nhiFY0j66A8/dyPXrS3CDYT1VLIin//GDszz4zEEo= +forge.lthn.ai/core/go-agentic v0.0.2/go.mod h1:wTZRajs+rt0YJbRk26ijC1sfICbg8O2782ZhCz2tv/k= forge.lthn.ai/core/go-crypt v0.0.2 h1:m8mCIrmC0tserVx9bfmrB8h4GtgAgQeedBPeNBvCxx0= forge.lthn.ai/core/go-crypt v0.0.2/go.mod h1:+JoZ4mwjzTklysI/DI7f6/0iocdJoJG2ZF/nQy6HTuI= forge.lthn.ai/core/go-scm v0.0.2 h1:Ue+gS5vxZkDgTvQrqYu9QdaqEezuTV1kZY3TMqM2uho= diff --git a/release/changelog.go b/release/changelog.go index c25fc52..deba6fa 100644 --- a/release/changelog.go +++ b/release/changelog.go @@ -7,7 +7,7 @@ import ( "fmt" "os/exec" "regexp" - "sort" + "slices" "strings" "golang.org/x/text/cases" @@ -269,18 +269,11 @@ func formatChangelog(commits []ConventionalCommit, version string) string { // Any remaining types not in the order list var remainingTypes []string for commitType := range grouped { - found := false - for _, t := range commitTypeOrder { - if t == commitType { - found = true - break - } - } - if !found { + if !slices.Contains(commitTypeOrder, commitType) { remainingTypes = append(remainingTypes, commitType) } } - sort.Strings(remainingTypes) + slices.Sort(remainingTypes) for _, commitType := range remainingTypes { commits := grouped[commitType] diff --git a/release/publishers/aur.go b/release/publishers/aur.go index 3234380..8f8e30b 100644 --- a/release/publishers/aur.go +++ b/release/publishers/aur.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "embed" + "errors" "fmt" "os" "os/exec" @@ -47,7 +48,7 @@ func (p *AURPublisher) Publish(ctx context.Context, release *Release, pubCfg Pub cfg := p.parseConfig(pubCfg, relCfg) if cfg.Maintainer == "" { - return fmt.Errorf("aur.Publish: maintainer is required (set publish.aur.maintainer in config)") + return errors.New("aur.Publish: maintainer is required (set publish.aur.maintainer in config)") } repo := "" diff --git a/release/publishers/chocolatey.go b/release/publishers/chocolatey.go index 9fb196a..cb9a348 100644 --- a/release/publishers/chocolatey.go +++ b/release/publishers/chocolatey.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "embed" + "errors" "fmt" "os" "os/exec" @@ -231,7 +232,7 @@ func (p *ChocolateyPublisher) pushToChocolatey(ctx context.Context, packageDir s // Check for CHOCOLATEY_API_KEY apiKey := os.Getenv("CHOCOLATEY_API_KEY") if apiKey == "" { - return fmt.Errorf("chocolatey.Publish: CHOCOLATEY_API_KEY environment variable is required for push") + return errors.New("chocolatey.Publish: CHOCOLATEY_API_KEY environment variable is required for push") } // Pack the package diff --git a/release/publishers/docker.go b/release/publishers/docker.go index 981d442..d04e039 100644 --- a/release/publishers/docker.go +++ b/release/publishers/docker.go @@ -3,6 +3,7 @@ package publishers import ( "context" + "errors" "fmt" "os" "os/exec" @@ -250,7 +251,7 @@ func (p *DockerPublisher) ensureBuildx(ctx context.Context) error { // Check if buildx is available cmd := exec.CommandContext(ctx, "docker", "buildx", "version") if err := cmd.Run(); err != nil { - return fmt.Errorf("docker: buildx is not available. Install it from https://docs.docker.com/buildx/working-with-buildx/") + return errors.New("docker: buildx is not available. Install it from https://docs.docker.com/buildx/working-with-buildx/") } // Check if we have a builder, create one if not @@ -272,7 +273,7 @@ func (p *DockerPublisher) ensureBuildx(ctx context.Context) error { func validateDockerCli() error { cmd := exec.Command("docker", "--version") if err := cmd.Run(); err != nil { - return fmt.Errorf("docker: docker CLI not found. Install it from https://docs.docker.com/get-docker/") + return errors.New("docker: docker CLI not found. Install it from https://docs.docker.com/get-docker/") } return nil } diff --git a/release/publishers/github.go b/release/publishers/github.go index b1eaf70..fc367e8 100644 --- a/release/publishers/github.go +++ b/release/publishers/github.go @@ -3,6 +3,7 @@ package publishers import ( "context" + "errors" "fmt" "os" "os/exec" @@ -146,18 +147,18 @@ func validateGhCli() error { // Check if gh is installed cmd := exec.Command("gh", "--version") if err := cmd.Run(); err != nil { - return fmt.Errorf("github: gh CLI not found. Install it from https://cli.github.com") + return errors.New("github: gh CLI not found. Install it from https://cli.github.com") } // Check if authenticated cmd = exec.Command("gh", "auth", "status") output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("github: not authenticated with gh CLI. Run 'gh auth login' first") + return errors.New("github: not authenticated with gh CLI. Run 'gh auth login' first") } if !strings.Contains(string(output), "Logged in") { - return fmt.Errorf("github: not authenticated with gh CLI. Run 'gh auth login' first") + return errors.New("github: not authenticated with gh CLI. Run 'gh auth login' first") } return nil diff --git a/release/publishers/homebrew.go b/release/publishers/homebrew.go index 5614a3b..f708c85 100644 --- a/release/publishers/homebrew.go +++ b/release/publishers/homebrew.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "embed" + "errors" "fmt" "os" "os/exec" @@ -57,7 +58,7 @@ func (p *HomebrewPublisher) Publish(ctx context.Context, release *Release, pubCf // Validate configuration if cfg.Tap == "" && (cfg.Official == nil || !cfg.Official.Enabled) { - return fmt.Errorf("homebrew.Publish: tap is required (set publish.homebrew.tap in config)") + return errors.New("homebrew.Publish: tap is required (set publish.homebrew.tap in config)") } // Get repository and project info diff --git a/release/publishers/linuxkit.go b/release/publishers/linuxkit.go index edb1d97..1af2601 100644 --- a/release/publishers/linuxkit.go +++ b/release/publishers/linuxkit.go @@ -3,6 +3,7 @@ package publishers import ( "context" + "errors" "fmt" "os" "os/exec" @@ -48,7 +49,7 @@ func (p *LinuxKitPublisher) Publish(ctx context.Context, release *Release, pubCf // Validate config file exists if release.FS == nil { - return fmt.Errorf("linuxkit.Publish: release filesystem (FS) is nil") + return errors.New("linuxkit.Publish: release filesystem (FS) is nil") } if !release.FS.Exists(lkCfg.Config) { return fmt.Errorf("linuxkit.Publish: config file not found: %s", lkCfg.Config) @@ -297,7 +298,7 @@ func (p *LinuxKitPublisher) getFormatExtension(format string) string { func validateLinuxKitCli() error { cmd := exec.Command("linuxkit", "version") if err := cmd.Run(); err != nil { - return fmt.Errorf("linuxkit: linuxkit CLI not found. Install it from https://github.com/linuxkit/linuxkit") + return errors.New("linuxkit: linuxkit CLI not found. Install it from https://github.com/linuxkit/linuxkit") } return nil } diff --git a/release/publishers/npm.go b/release/publishers/npm.go index 51b49f8..5ac94f1 100644 --- a/release/publishers/npm.go +++ b/release/publishers/npm.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "embed" + "errors" "fmt" "os" "os/exec" @@ -47,7 +48,7 @@ func (p *NpmPublisher) Publish(ctx context.Context, release *Release, pubCfg Pub // Validate configuration if npmCfg.Package == "" { - return fmt.Errorf("npm.Publish: package name is required (set publish.npm.package in config)") + return errors.New("npm.Publish: package name is required (set publish.npm.package in config)") } // Get repository @@ -162,7 +163,7 @@ func (p *NpmPublisher) dryRunPublish(m io.Medium, data npmTemplateData, cfg *Npm func (p *NpmPublisher) executePublish(ctx context.Context, m io.Medium, data npmTemplateData, cfg *NpmConfig) error { // Check for NPM_TOKEN if os.Getenv("NPM_TOKEN") == "" { - return fmt.Errorf("npm.Publish: NPM_TOKEN environment variable is required") + return errors.New("npm.Publish: NPM_TOKEN environment variable is required") } // Create temp directory for package diff --git a/release/publishers/scoop.go b/release/publishers/scoop.go index ce1a46e..a436e5f 100644 --- a/release/publishers/scoop.go +++ b/release/publishers/scoop.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "embed" + "errors" "fmt" "os" "os/exec" @@ -45,7 +46,7 @@ func (p *ScoopPublisher) Publish(ctx context.Context, release *Release, pubCfg P cfg := p.parseConfig(pubCfg, relCfg) if cfg.Bucket == "" && (cfg.Official == nil || !cfg.Official.Enabled) { - return fmt.Errorf("scoop.Publish: bucket is required (set publish.scoop.bucket in config)") + return errors.New("scoop.Publish: bucket is required (set publish.scoop.bucket in config)") } repo := "" diff --git a/release/release.go b/release/release.go index 8ece33f..59c9c2e 100644 --- a/release/release.go +++ b/release/release.go @@ -5,14 +5,15 @@ package release import ( "context" + "errors" "fmt" "path/filepath" "strings" "forge.lthn.ai/core/go-devops/build" "forge.lthn.ai/core/go-devops/build/builders" - "forge.lthn.ai/core/go/pkg/io" "forge.lthn.ai/core/go-devops/release/publishers" + "forge.lthn.ai/core/go/pkg/io" ) // Release represents a release with its version, artifacts, and changelog. @@ -34,7 +35,7 @@ type Release struct { // If dryRun is true, it will show what would be done without actually publishing. func Publish(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) { if cfg == nil { - return nil, fmt.Errorf("release.Publish: config is nil") + return nil, errors.New("release.Publish: config is nil") } m := io.Local @@ -67,7 +68,7 @@ func Publish(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) { } if len(artifacts) == 0 { - return nil, fmt.Errorf("release.Publish: no artifacts found in dist/\nRun 'core build' first to create artifacts") + return nil, errors.New("release.Publish: no artifacts found in dist/\nRun 'core build' first to create artifacts") } // Step 3: Generate changelog @@ -109,7 +110,7 @@ func Publish(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) { // findArtifacts discovers pre-built artifacts in the dist directory. func findArtifacts(m io.Medium, distDir string) ([]build.Artifact, error) { if !m.IsDir(distDir) { - return nil, fmt.Errorf("dist/ directory not found") + return nil, errors.New("dist/ directory not found") } var artifacts []build.Artifact @@ -145,7 +146,7 @@ func findArtifacts(m io.Medium, distDir string) ([]build.Artifact, error) { // If dryRun is true, it will show what would be done without actually publishing. func Run(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) { if cfg == nil { - return nil, fmt.Errorf("release.Run: config is nil") + return nil, errors.New("release.Run: config is nil") } m := io.Local @@ -317,9 +318,9 @@ func getBuilder(projectType build.ProjectType) (build.Builder, error) { case build.ProjectTypeGo: return builders.NewGoBuilder(), nil case build.ProjectTypeNode: - return nil, fmt.Errorf("node.js builder not yet implemented") + return nil, errors.New("node.js builder not yet implemented") case build.ProjectTypePHP: - return nil, fmt.Errorf("PHP builder not yet implemented") + return nil, errors.New("PHP builder not yet implemented") default: return nil, fmt.Errorf("unsupported project type: %s", projectType) } diff --git a/release/sdk.go b/release/sdk.go index 30c2540..5e947a7 100644 --- a/release/sdk.go +++ b/release/sdk.go @@ -3,6 +3,7 @@ package release import ( "context" + "errors" "fmt" "forge.lthn.ai/core/go-devops/sdk" @@ -22,10 +23,10 @@ type SDKRelease struct { // If dryRun is true, it shows what would be done without generating. func RunSDK(ctx context.Context, cfg *Config, dryRun bool) (*SDKRelease, error) { if cfg == nil { - return nil, fmt.Errorf("release.RunSDK: config is nil") + return nil, errors.New("release.RunSDK: config is nil") } if cfg.SDK == nil { - return nil, fmt.Errorf("release.RunSDK: sdk not configured in .core/release.yaml") + return nil, errors.New("release.RunSDK: sdk not configured in .core/release.yaml") } projectDir := cfg.projectDir @@ -51,7 +52,7 @@ func RunSDK(ctx context.Context, cfg *Config, dryRun bool) (*SDKRelease, error) fmt.Printf("Warning: diff check failed: %v\n", err) } else if breaking { if cfg.SDK.Diff.FailOnBreaking { - return nil, fmt.Errorf("release.RunSDK: breaking API changes detected") + return nil, errors.New("release.RunSDK: breaking API changes detected") } fmt.Printf("Warning: breaking API changes detected\n") } diff --git a/sdk/detect.go b/sdk/detect.go index 2b1b1a8..0b6b83f 100644 --- a/sdk/detect.go +++ b/sdk/detect.go @@ -1,6 +1,7 @@ package sdk import ( + "errors" "fmt" "path/filepath" "strings" @@ -46,14 +47,14 @@ func (s *SDK) DetectSpec() (string, error) { return specPath, nil } - return "", fmt.Errorf("sdk.DetectSpec: no OpenAPI spec found (checked config, common paths, Scramble)") + return "", errors.New("sdk.DetectSpec: no OpenAPI spec found (checked config, common paths, Scramble)") } // detectScramble checks for Laravel Scramble and exports the spec. func (s *SDK) detectScramble() (string, error) { composerPath := filepath.Join(s.projectDir, "composer.json") if !coreio.Local.IsFile(composerPath) { - return "", fmt.Errorf("no composer.json") + return "", errors.New("no composer.json") } // Check for scramble in composer.json @@ -64,11 +65,11 @@ func (s *SDK) detectScramble() (string, error) { // Simple check for scramble package if !containsScramble(data) { - return "", fmt.Errorf("scramble not found in composer.json") + return "", errors.New("scramble not found in composer.json") } // TODO: Run php artisan scramble:export - return "", fmt.Errorf("scramble export not implemented") + return "", errors.New("scramble export not implemented") } // containsScramble checks if composer.json includes scramble. diff --git a/sdk/generators/php.go b/sdk/generators/php.go index 0c7a569..69fa446 100644 --- a/sdk/generators/php.go +++ b/sdk/generators/php.go @@ -2,6 +2,7 @@ package generators import ( "context" + "errors" "fmt" "os" "os/exec" @@ -37,7 +38,7 @@ func (g *PHPGenerator) Install() string { // Generate creates SDK from OpenAPI spec. func (g *PHPGenerator) Generate(ctx context.Context, opts Options) error { if !g.Available() { - return fmt.Errorf("php.Generate: Docker is required but not available") + return errors.New("php.Generate: Docker is required but not available") } if err := coreio.Local.EnsureDir(opts.OutputDir); err != nil {