From 4c5e12c9f86762c85deebf6c9d46e256ddcb4faf Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 16 Mar 2026 19:09:50 +0000 Subject: [PATCH] refactor: replace os.ReadFile/WriteFile and fmt.Errorf/errors.New with framework equivalents Replace os.ReadFile with coreio.Local.Read for consistent filesystem abstraction. Replace fmt.Errorf/errors.New with log.E() from go-log for structured error context. Co-Authored-By: Virgil --- cmd/deploy/cmd_deploy.go | 3 ++- cmd/dev/cmd_impact.go | 6 +++--- cmd/dev/cmd_tag.go | 17 +++++++++-------- cmd/dev/cmd_vm.go | 4 ++-- cmd/dev/forge_client.go | 10 +++++----- cmd/setup/cmd_bootstrap.go | 15 ++++++++------- cmd/setup/cmd_github.go | 10 +++++----- cmd/setup/cmd_registry.go | 13 +++++++------ cmd/setup/cmd_repo.go | 5 +++-- cmd/setup/github_config.go | 21 +++++++++++---------- cmd/setup/github_protection.go | 5 +++-- cmd/setup/github_security.go | 11 ++++++----- cmd/setup/github_webhooks.go | 7 ++++--- deploy/coolify/client.go | 15 ++++++++------- snapshot/snapshot.go | 5 +++-- 15 files changed, 79 insertions(+), 68 deletions(-) diff --git a/cmd/deploy/cmd_deploy.go b/cmd/deploy/cmd_deploy.go index b6c63fd..7b962dd 100644 --- a/cmd/deploy/cmd_deploy.go +++ b/cmd/deploy/cmd_deploy.go @@ -9,6 +9,7 @@ import ( "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go-devops/deploy/coolify" "forge.lthn.ai/core/go-i18n" + log "forge.lthn.ai/core/go-log" ) var ( @@ -266,7 +267,7 @@ func runCall(cmd *cli.Command, args []string) error { var params map[string]any if len(args) > 1 { if err := json.Unmarshal([]byte(args[1]), ¶ms); err != nil { - return fmt.Errorf("invalid JSON params: %w", err) + return log.E("deploy", "invalid JSON params", err) } } diff --git a/cmd/dev/cmd_impact.go b/cmd/dev/cmd_impact.go index f3de823..2515e40 100644 --- a/cmd/dev/cmd_impact.go +++ b/cmd/dev/cmd_impact.go @@ -1,12 +1,12 @@ package dev import ( - "errors" "slices" "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go-i18n" "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" "forge.lthn.ai/core/go-scm/repos" ) @@ -55,14 +55,14 @@ func runImpact(registryPath string, repoName string) error { return cli.Wrap(err, "failed to load registry") } } else { - return errors.New(i18n.T("cmd.dev.impact.requires_registry")) + return log.E("dev.impact", i18n.T("cmd.dev.impact.requires_registry"), nil) } } // Check repo exists repo, exists := reg.Get(repoName) if !exists { - return errors.New(i18n.T("error.repo_not_found", map[string]any{"Name": repoName})) + return log.E("dev.impact", i18n.T("error.repo_not_found", map[string]any{"Name": repoName}), nil) } // Build reverse dependency graph diff --git a/cmd/dev/cmd_tag.go b/cmd/dev/cmd_tag.go index af2d2ff..7096632 100644 --- a/cmd/dev/cmd_tag.go +++ b/cmd/dev/cmd_tag.go @@ -11,6 +11,7 @@ import ( "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go-i18n" + log "forge.lthn.ai/core/go-log" ) // Tag command flags @@ -77,7 +78,7 @@ func runTag(registryPath string, dryRun, force bool) error { next, err := bumpPatch(current) if err != nil { - return fmt.Errorf("%s: failed to bump version %s: %w", repo.Name, current, err) + return log.E("dev.tag", fmt.Sprintf("%s: failed to bump version %s", repo.Name, current), err) } hasGoMod := fileExists(filepath.Join(repo.Path, "go.mod")) @@ -207,11 +208,11 @@ func bumpPatch(tag string) (string, error) { v := strings.TrimPrefix(tag, "v") parts := strings.Split(v, ".") if len(parts) != 3 { - return "", fmt.Errorf("invalid semver: %s", tag) + return "", log.E("dev.tag", fmt.Sprintf("invalid semver: %s", tag), nil) } patch, err := strconv.Atoi(parts[2]) if err != nil { - return "", fmt.Errorf("invalid patch version: %s", parts[2]) + return "", log.E("dev.tag", fmt.Sprintf("invalid patch version: %s", parts[2]), nil) } return fmt.Sprintf("v%s.%s.%d", parts[0], parts[1], patch+1), nil } @@ -223,7 +224,7 @@ func goGetUpdate(ctx context.Context, repoPath string) error { cmd.Env = append(os.Environ(), "GOWORK=off") out, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("%s: %w", strings.TrimSpace(string(out)), err) + return log.E("dev.tag", strings.TrimSpace(string(out)), err) } return nil } @@ -235,7 +236,7 @@ func goModTidy(ctx context.Context, repoPath string) error { cmd.Env = append(os.Environ(), "GOWORK=off") out, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("%s: %w", strings.TrimSpace(string(out)), err) + return log.E("dev.tag", strings.TrimSpace(string(out)), err) } return nil } @@ -261,7 +262,7 @@ func commitGoMod(ctx context.Context, repoPath, version string) error { addCmd := exec.CommandContext(ctx, "git", "add", "go.mod", "go.sum") addCmd.Dir = repoPath if out, err := addCmd.CombinedOutput(); err != nil { - return fmt.Errorf("git add: %s: %w", strings.TrimSpace(string(out)), err) + return log.E("dev.tag", "git add: "+strings.TrimSpace(string(out)), err) } // Check if anything is actually staged @@ -276,7 +277,7 @@ func commitGoMod(ctx context.Context, repoPath, version string) error { commitCmd := exec.CommandContext(ctx, "git", "commit", "-m", msg) commitCmd.Dir = repoPath if out, err := commitCmd.CombinedOutput(); err != nil { - return fmt.Errorf("git commit: %s: %w", strings.TrimSpace(string(out)), err) + return log.E("dev.tag", "git commit: "+strings.TrimSpace(string(out)), err) } return nil } @@ -286,7 +287,7 @@ func createTag(ctx context.Context, repoPath, tag string) error { cmd := exec.CommandContext(ctx, "git", "tag", "-a", tag, "-m", tag) cmd.Dir = repoPath if out, err := cmd.CombinedOutput(); err != nil { - return fmt.Errorf("%s: %w", strings.TrimSpace(string(out)), err) + return log.E("dev.tag", strings.TrimSpace(string(out)), err) } return nil } diff --git a/cmd/dev/cmd_vm.go b/cmd/dev/cmd_vm.go index 7fb002f..d33df36 100644 --- a/cmd/dev/cmd_vm.go +++ b/cmd/dev/cmd_vm.go @@ -2,7 +2,6 @@ package dev import ( "context" - "errors" "os" "time" @@ -10,6 +9,7 @@ import ( "forge.lthn.ai/core/go-container/devenv" "forge.lthn.ai/core/go-i18n" "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" ) // addVMCommands adds the dev environment VM commands to the dev parent command. @@ -119,7 +119,7 @@ func runVMBoot(memory, cpus int, fresh bool) error { } if !d.IsInstalled() { - return errors.New(i18n.T("cmd.dev.vm.not_installed")) + return log.E("dev.vm", i18n.T("cmd.dev.vm.not_installed"), nil) } opts := devenv.DefaultBootOptions() diff --git a/cmd/dev/forge_client.go b/cmd/dev/forge_client.go index 7571802..649aa97 100644 --- a/cmd/dev/forge_client.go +++ b/cmd/dev/forge_client.go @@ -1,13 +1,13 @@ package dev import ( - "fmt" - "os" "path/filepath" "strings" "code.gitea.io/sdk/gitea" + coreio "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" "forge.lthn.ai/core/go-scm/forge" ) @@ -19,7 +19,7 @@ func forgeAPIClient() (*gitea.Client, error) { return nil, err } if token == "" { - return nil, fmt.Errorf("no Forge API token configured (set FORGE_TOKEN or run: core forge config --token TOKEN)") + return nil, log.E("dev.forge", "no Forge API token configured (set FORGE_TOKEN or run: core forge config --token TOKEN)", nil) } return gitea.NewClient(forgeURL, gitea.SetToken(token)) } @@ -28,12 +28,12 @@ func forgeAPIClient() (*gitea.Client, error) { // Falls back to fallbackOrg/repoName if no forge.lthn.ai remote is found. func forgeRepoIdentity(repoPath, fallbackOrg, repoName string) (owner, repo string) { configPath := filepath.Join(repoPath, ".git", "config") - content, err := os.ReadFile(configPath) + content, err := coreio.Local.Read(configPath) if err != nil { return fallbackOrg, repoName } - for _, line := range strings.Split(string(content), "\n") { + for _, line := range strings.Split(content, "\n") { line = strings.TrimSpace(line) if !strings.HasPrefix(line, "url = ") { continue diff --git a/cmd/setup/cmd_bootstrap.go b/cmd/setup/cmd_bootstrap.go index 7ead9ba..cfacb93 100644 --- a/cmd/setup/cmd_bootstrap.go +++ b/cmd/setup/cmd_bootstrap.go @@ -16,6 +16,7 @@ import ( "forge.lthn.ai/core/agent/cmd/workspace" "forge.lthn.ai/core/go-i18n" coreio "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" "forge.lthn.ai/core/go-scm/repos" ) @@ -46,7 +47,7 @@ func runSetupOrchestrator(registryPath, only string, dryRun, all bool, projectNa func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectName string, runBuild bool) error { cwd, err := os.Getwd() if err != nil { - return fmt.Errorf("failed to get working directory: %w", err) + return log.E("setup.bootstrap", "failed to get working directory", err) } fmt.Printf("%s %s\n", dimStyle.Render(">>"), i18n.T("cmd.setup.bootstrap_mode")) @@ -56,7 +57,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam // Check if current directory is empty empty, err := isDirEmpty(cwd) if err != nil { - return fmt.Errorf("failed to check directory: %w", err) + return log.E("setup.bootstrap", "failed to check directory", err) } if empty { @@ -71,7 +72,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam // Offer choice: setup working directory or create package choice, err := promptSetupChoice() if err != nil { - return fmt.Errorf("failed to get choice: %w", err) + return log.E("setup.bootstrap", "failed to get choice", err) } if choice == "setup" { @@ -88,7 +89,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam } else { projectName, err = promptProjectName(defaultOrg) if err != nil { - return fmt.Errorf("failed to get project name: %w", err) + return log.E("setup.bootstrap", "failed to get project name", err) } } } @@ -98,7 +99,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam if !dryRun { if err := coreio.Local.EnsureDir(targetDir); err != nil { - return fmt.Errorf("failed to create directory: %w", err) + return log.E("setup.bootstrap", "failed to create directory", err) } } } @@ -110,7 +111,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam if !dryRun { if err := gitClone(ctx, defaultOrg, devopsRepo, devopsPath); err != nil { - return fmt.Errorf("failed to clone %s: %w", devopsRepo, err) + return log.E("setup.bootstrap", fmt.Sprintf("failed to clone %s", devopsRepo), err) } fmt.Printf("%s %s %s\n", successStyle.Render(">>"), devopsRepo, i18n.T("cmd.setup.cloned")) } else { @@ -130,7 +131,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam reg, err := repos.LoadRegistry(coreio.Local, registryPath) if err != nil { - return fmt.Errorf("failed to load registry from %s: %w", devopsRepo, err) + return log.E("setup.bootstrap", fmt.Sprintf("failed to load registry from %s", devopsRepo), err) } // Override base path to target directory diff --git a/cmd/setup/cmd_github.go b/cmd/setup/cmd_github.go index 2664e11..3d5779e 100644 --- a/cmd/setup/cmd_github.go +++ b/cmd/setup/cmd_github.go @@ -18,13 +18,13 @@ package setup import ( - "errors" "os/exec" "path/filepath" "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go-i18n" coreio "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" "forge.lthn.ai/core/go-scm/repos" ) @@ -69,12 +69,12 @@ func addGitHubCommand(parent *cli.Command) { func runGitHubSetup() error { // Check gh is available if _, err := exec.LookPath("gh"); err != nil { - return errors.New(i18n.T("error.gh_not_found")) + return log.E("setup.github", i18n.T("error.gh_not_found"), nil) } // Check gh is authenticated if !cli.GhAuthenticated() { - return errors.New(i18n.T("cmd.setup.github.error.not_authenticated")) + return log.E("setup.github", i18n.T("cmd.setup.github.error.not_authenticated"), nil) } // Find registry @@ -118,14 +118,14 @@ func runGitHubSetup() error { // Reject conflicting flags if ghRepo != "" && ghAll { - return errors.New(i18n.T("cmd.setup.github.error.conflicting_flags")) + return log.E("setup.github", i18n.T("cmd.setup.github.error.conflicting_flags"), nil) } if ghRepo != "" { // Single repo mode repo, ok := reg.Get(ghRepo) if !ok { - return errors.New(i18n.T("error.repo_not_found", map[string]any{"Name": ghRepo})) + return log.E("setup.github", i18n.T("error.repo_not_found", map[string]any{"Name": ghRepo}), nil) } reposToProcess = []*repos.Repo{repo} } else if ghAll { diff --git a/cmd/setup/cmd_registry.go b/cmd/setup/cmd_registry.go index d62dca3..acf8b59 100644 --- a/cmd/setup/cmd_registry.go +++ b/cmd/setup/cmd_registry.go @@ -17,6 +17,7 @@ import ( "forge.lthn.ai/core/cli/pkg/cli" "forge.lthn.ai/core/go-i18n" coreio "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" "forge.lthn.ai/core/go-scm/repos" ) @@ -24,7 +25,7 @@ import ( func runRegistrySetup(ctx context.Context, registryPath, only string, dryRun, all, runBuild bool) error { reg, err := repos.LoadRegistry(coreio.Local, registryPath) if err != nil { - return fmt.Errorf("failed to load registry: %w", err) + return log.E("setup.registry", "failed to load registry", err) } // Check workspace config for default_only if no filter specified @@ -82,7 +83,7 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP // Ensure base path exists if !dryRun { if err := coreio.Local.EnsureDir(basePath); err != nil { - return fmt.Errorf("failed to create packages directory: %w", err) + return log.E("setup.registry", "failed to create packages directory", err) } } @@ -99,7 +100,7 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP if useWizard { selected, err := runPackageWizard(reg, typeFilter) if err != nil { - return fmt.Errorf("wizard error: %w", err) + return log.E("setup.registry", "wizard error", err) } // Build set of selected repos @@ -227,7 +228,7 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP buildCmd.Stdout = os.Stdout buildCmd.Stderr = os.Stderr if err := buildCmd.Run(); err != nil { - return fmt.Errorf("%s: %w", i18n.T("i18n.fail.run", "build"), err) + return log.E("setup.registry", i18n.T("i18n.fail.run", "build"), err) } } @@ -249,7 +250,7 @@ func gitClone(ctx context.Context, org, repo, path string) error { // Only fall through to SSH if it's an auth error if !strings.Contains(errStr, "Permission denied") && !strings.Contains(errStr, "could not read") { - return fmt.Errorf("%s", errStr) + return log.E("setup.registry", errStr, nil) } } @@ -258,7 +259,7 @@ func gitClone(ctx context.Context, org, repo, path string) error { cmd := exec.CommandContext(ctx, "git", "clone", url, path) output, err := cmd.CombinedOutput() if err != nil { - return fmt.Errorf("%s", strings.TrimSpace(string(output))) + return log.E("setup.registry", strings.TrimSpace(string(output)), nil) } return nil } diff --git a/cmd/setup/cmd_repo.go b/cmd/setup/cmd_repo.go index 780e733..dfc7b44 100644 --- a/cmd/setup/cmd_repo.go +++ b/cmd/setup/cmd_repo.go @@ -14,6 +14,7 @@ import ( "forge.lthn.ai/core/go-i18n" coreio "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" ) // runRepoSetup sets up the current repository with .core/ configuration. @@ -28,7 +29,7 @@ func runRepoSetup(repoPath string, dryRun bool) error { coreDir := filepath.Join(repoPath, ".core") if !dryRun { if err := coreio.Local.EnsureDir(coreDir); err != nil { - return fmt.Errorf("failed to create .core directory: %w", err) + return log.E("setup.repo", "failed to create .core directory", err) } } @@ -55,7 +56,7 @@ func runRepoSetup(repoPath string, dryRun bool) error { for filename, content := range configs { configPath := filepath.Join(coreDir, filename) if err := coreio.Local.Write(configPath, content); err != nil { - return fmt.Errorf("failed to write %s: %w", filename, err) + return log.E("setup.repo", fmt.Sprintf("failed to write %s", filename), err) } fmt.Printf("%s %s %s\n", successStyle.Render(">>"), i18n.T("cmd.setup.repo.created"), configPath) } diff --git a/cmd/setup/github_config.go b/cmd/setup/github_config.go index 01f547c..3ccaf01 100644 --- a/cmd/setup/github_config.go +++ b/cmd/setup/github_config.go @@ -13,6 +13,7 @@ import ( "strings" coreio "forge.lthn.ai/core/go-io" + log "forge.lthn.ai/core/go-log" "gopkg.in/yaml.v3" ) @@ -67,7 +68,7 @@ type SecurityConfig struct { func LoadGitHubConfig(path string) (*GitHubConfig, error) { data, err := coreio.Local.Read(path) if err != nil { - return nil, fmt.Errorf("failed to read config file: %w", err) + return nil, log.E("setup.github_config", "failed to read config file", err) } // Expand environment variables before parsing @@ -75,7 +76,7 @@ func LoadGitHubConfig(path string) (*GitHubConfig, error) { var config GitHubConfig if err := yaml.Unmarshal([]byte(expanded), &config); err != nil { - return nil, fmt.Errorf("failed to parse config file: %w", err) + return nil, log.E("setup.github_config", "failed to parse config file", err) } // Set defaults @@ -131,7 +132,7 @@ func FindGitHubConfig(registryDir, specifiedPath string) (string, error) { if coreio.Local.IsFile(specifiedPath) { return specifiedPath, nil } - return "", fmt.Errorf("config file not found: %s", specifiedPath) + return "", log.E("setup.github_config", fmt.Sprintf("config file not found: %s", specifiedPath), nil) } // Search in common locations (using filepath.Join for OS-portable paths) @@ -146,26 +147,26 @@ func FindGitHubConfig(registryDir, specifiedPath string) (string, error) { } } - return "", fmt.Errorf("github.yaml not found in %s/.core/ or %s/", registryDir, registryDir) + return "", log.E("setup.github_config", fmt.Sprintf("github.yaml not found in %s/.core/ or %s/", registryDir, registryDir), nil) } // Validate checks the configuration for errors. func (c *GitHubConfig) Validate() error { if c.Version != 1 { - return fmt.Errorf("unsupported config version: %d (expected 1)", c.Version) + return log.E("setup.github_config", fmt.Sprintf("unsupported config version: %d (expected 1)", c.Version), nil) } // Validate labels for i, label := range c.Labels { if label.Name == "" { - return fmt.Errorf("label %d: name is required", i+1) + return log.E("setup.github_config", fmt.Sprintf("label %d: name is required", i+1), nil) } if label.Color == "" { - return fmt.Errorf("label %q: color is required", label.Name) + return log.E("setup.github_config", fmt.Sprintf("label %q: color is required", label.Name), nil) } // Validate color format (hex without #) if !isValidHexColor(label.Color) { - return fmt.Errorf("label %q: invalid color %q (expected 6-digit hex without #)", label.Name, label.Color) + return log.E("setup.github_config", fmt.Sprintf("label %q: invalid color %q (expected 6-digit hex without #)", label.Name, label.Color), nil) } } @@ -176,14 +177,14 @@ func (c *GitHubConfig) Validate() error { continue } if len(wh.Events) == 0 { - return fmt.Errorf("webhook %q: at least one event is required", name) + return log.E("setup.github_config", fmt.Sprintf("webhook %q: at least one event is required", name), nil) } } // Validate branch protection for i, bp := range c.BranchProtection { if bp.Branch == "" { - return fmt.Errorf("branch_protection %d: branch is required", i+1) + return log.E("setup.github_config", fmt.Sprintf("branch_protection %d: branch is required", i+1), nil) } } diff --git a/cmd/setup/github_protection.go b/cmd/setup/github_protection.go index 56622e4..98b0243 100644 --- a/cmd/setup/github_protection.go +++ b/cmd/setup/github_protection.go @@ -13,6 +13,7 @@ import ( "strings" "forge.lthn.ai/core/cli/pkg/cli" + log "forge.lthn.ai/core/go-log" ) // GitHubBranchProtection represents branch protection rules from the GitHub API. @@ -68,7 +69,7 @@ type RequiredConversationResolution struct { func GetBranchProtection(repoFullName, branch string) (*GitHubBranchProtection, error) { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return nil, fmt.Errorf("invalid repo format: %s", repoFullName) + return nil, log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } endpoint := fmt.Sprintf("repos/%s/%s/branches/%s/protection", parts[0], parts[1], branch) @@ -101,7 +102,7 @@ func GetBranchProtection(repoFullName, branch string) (*GitHubBranchProtection, func SetBranchProtection(repoFullName, branch string, config BranchProtectionConfig) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } // Build the protection payload diff --git a/cmd/setup/github_security.go b/cmd/setup/github_security.go index 3a37d95..4353664 100644 --- a/cmd/setup/github_security.go +++ b/cmd/setup/github_security.go @@ -15,6 +15,7 @@ import ( "strings" "forge.lthn.ai/core/cli/pkg/cli" + log "forge.lthn.ai/core/go-log" ) // GitHubSecurityStatus represents the security settings status of a repository. @@ -46,7 +47,7 @@ type SecurityFeature struct { func GetSecuritySettings(repoFullName string) (*GitHubSecurityStatus, error) { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return nil, fmt.Errorf("invalid repo format: %s", repoFullName) + return nil, log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } status := &GitHubSecurityStatus{} @@ -102,7 +103,7 @@ func GetSecuritySettings(repoFullName string) (*GitHubSecurityStatus, error) { func EnableDependabotAlerts(repoFullName string) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } endpoint := fmt.Sprintf("repos/%s/%s/vulnerability-alerts", parts[0], parts[1]) @@ -118,7 +119,7 @@ func EnableDependabotAlerts(repoFullName string) error { func EnableDependabotSecurityUpdates(repoFullName string) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } endpoint := fmt.Sprintf("repos/%s/%s/automated-security-fixes", parts[0], parts[1]) @@ -134,7 +135,7 @@ func EnableDependabotSecurityUpdates(repoFullName string) error { func DisableDependabotSecurityUpdates(repoFullName string) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } endpoint := fmt.Sprintf("repos/%s/%s/automated-security-fixes", parts[0], parts[1]) @@ -150,7 +151,7 @@ func DisableDependabotSecurityUpdates(repoFullName string) error { func UpdateSecurityAndAnalysis(repoFullName string, secretScanning, pushProtection bool) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } // Build the payload diff --git a/cmd/setup/github_webhooks.go b/cmd/setup/github_webhooks.go index a530ef3..c448591 100644 --- a/cmd/setup/github_webhooks.go +++ b/cmd/setup/github_webhooks.go @@ -13,6 +13,7 @@ import ( "strings" "forge.lthn.ai/core/cli/pkg/cli" + log "forge.lthn.ai/core/go-log" ) // GitHubWebhook represents a webhook as returned by the GitHub API. @@ -35,7 +36,7 @@ type GitHubWebhookConfig struct { func ListWebhooks(repoFullName string) ([]GitHubWebhook, error) { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return nil, fmt.Errorf("invalid repo format: %s", repoFullName) + return nil, log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } endpoint := fmt.Sprintf("repos/%s/%s/hooks", parts[0], parts[1]) @@ -65,7 +66,7 @@ func ListWebhooks(repoFullName string) ([]GitHubWebhook, error) { func CreateWebhook(repoFullName string, name string, config WebhookConfig) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } // Build the webhook payload @@ -108,7 +109,7 @@ func CreateWebhook(repoFullName string, name string, config WebhookConfig) error func UpdateWebhook(repoFullName string, hookID int, config WebhookConfig) error { parts := strings.Split(repoFullName, "/") if len(parts) != 2 { - return fmt.Errorf("invalid repo format: %s", repoFullName) + return log.E("setup.github", fmt.Sprintf("invalid repo format: %s", repoFullName), nil) } payload := map[string]any{ diff --git a/deploy/coolify/client.go b/deploy/coolify/client.go index 1663561..5ae236a 100644 --- a/deploy/coolify/client.go +++ b/deploy/coolify/client.go @@ -3,11 +3,12 @@ package coolify import ( "context" "encoding/json" - "errors" "fmt" "os" "sync" + log "forge.lthn.ai/core/go-log" + "forge.lthn.ai/core/go-devops/deploy/python" ) @@ -42,15 +43,15 @@ func DefaultConfig() Config { // NewClient creates a new Coolify client. func NewClient(cfg Config) (*Client, error) { if cfg.BaseURL == "" { - return nil, errors.New("COOLIFY_URL not set") + return nil, log.E("coolify", "COOLIFY_URL not set", nil) } if cfg.APIToken == "" { - return nil, errors.New("COOLIFY_TOKEN not set") + return nil, log.E("coolify", "COOLIFY_TOKEN not set", nil) } // Initialize Python runtime if err := python.Init(); err != nil { - return nil, fmt.Errorf("failed to initialize Python: %w", err) + return nil, log.E("coolify", "failed to initialize Python", err) } return &Client{ @@ -73,11 +74,11 @@ func (c *Client) Call(ctx context.Context, operationID string, params map[string // Generate and run Python script script, err := python.CoolifyScript(c.baseURL, c.apiToken, operationID, params) if err != nil { - return nil, fmt.Errorf("failed to generate script: %w", err) + return nil, log.E("coolify", "failed to generate script", err) } output, err := python.RunScript(ctx, script) if err != nil { - return nil, fmt.Errorf("API call %s failed: %w", operationID, err) + return nil, log.E("coolify", fmt.Sprintf("API call %s failed", operationID), err) } // Parse JSON result @@ -88,7 +89,7 @@ func (c *Client) Call(ctx context.Context, operationID string, params map[string if err2 := json.Unmarshal([]byte(output), &arrResult); err2 == nil { return map[string]any{"result": arrResult}, nil } - return nil, fmt.Errorf("failed to parse response: %w (output: %s)", err, output) + return nil, log.E("coolify", fmt.Sprintf("failed to parse response (output: %s)", output), err) } return result, nil diff --git a/snapshot/snapshot.go b/snapshot/snapshot.go index 05c5125..51e6164 100644 --- a/snapshot/snapshot.go +++ b/snapshot/snapshot.go @@ -3,9 +3,10 @@ package snapshot import ( "encoding/json" - "errors" "time" + log "forge.lthn.ai/core/go-log" + "forge.lthn.ai/core/go-scm/manifest" ) @@ -35,7 +36,7 @@ func Generate(m *manifest.Manifest, commit, tag string) ([]byte, error) { // GenerateAt creates a core.json snapshot with an explicit build timestamp. func GenerateAt(m *manifest.Manifest, commit, tag string, built time.Time) ([]byte, error) { if m == nil { - return nil, errors.New("snapshot: manifest is nil") + return nil, log.E("snapshot", "manifest is nil", nil) } snap := Snapshot{