diff --git a/internal/cmd/pkgcmd/cmd_install.go b/internal/cmd/pkgcmd/cmd_install.go index 08bf87c9..d3d0bf55 100644 --- a/internal/cmd/pkgcmd/cmd_install.go +++ b/internal/cmd/pkgcmd/cmd_install.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/host-uk/core/pkg/i18n" + coreio "github.com/host-uk/core/pkg/io" "github.com/host-uk/core/pkg/repos" "github.com/spf13/cobra" ) @@ -73,12 +74,12 @@ func runPkgInstall(repoArg, targetDir string, addToRegistry bool) error { repoPath := filepath.Join(targetDir, repoName) - if _, err := os.Stat(filepath.Join(repoPath, ".git")); err == nil { + if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err == nil { fmt.Printf("%s %s\n", dimStyle.Render(i18n.Label("skip")), i18n.T("cmd.pkg.install.already_exists", map[string]string{"Name": repoName, "Path": repoPath})) return nil } - if err := os.MkdirAll(targetDir, 0755); err != nil { + if err := coreio.Local.EnsureDir(targetDir); err != nil { return fmt.Errorf("%s: %w", i18n.T("i18n.fail.create", "directory"), err) } @@ -123,18 +124,17 @@ func addToRegistryFile(org, repoName string) error { return nil } - f, err := os.OpenFile(regPath, os.O_APPEND|os.O_WRONLY, 0644) + content, err := coreio.Local.Read(regPath) if err != nil { return err } - defer f.Close() repoType := detectRepoType(repoName) entry := fmt.Sprintf("\n %s:\n type: %s\n description: (installed via core pkg install)\n", repoName, repoType) - _, err = f.WriteString(entry) - return err + content += entry + return coreio.Local.Write(regPath, content) } func detectRepoType(name string) string { diff --git a/internal/cmd/pkgcmd/cmd_manage.go b/internal/cmd/pkgcmd/cmd_manage.go index d7f1bb95..cabba86f 100644 --- a/internal/cmd/pkgcmd/cmd_manage.go +++ b/internal/cmd/pkgcmd/cmd_manage.go @@ -3,12 +3,12 @@ package pkgcmd import ( "errors" "fmt" - "os" "os/exec" "path/filepath" "strings" "github.com/host-uk/core/pkg/i18n" + coreio "github.com/host-uk/core/pkg/io" "github.com/host-uk/core/pkg/repos" "github.com/spf13/cobra" ) @@ -58,7 +58,7 @@ func runPkgList() error { for _, r := range allRepos { repoPath := filepath.Join(basePath, r.Name) exists := false - if _, err := os.Stat(filepath.Join(repoPath, ".git")); err == nil { + if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err == nil { exists = true installed++ } else { @@ -147,7 +147,7 @@ func runPkgUpdate(packages []string, all bool) error { for _, name := range toUpdate { repoPath := filepath.Join(basePath, name) - if _, err := os.Stat(filepath.Join(repoPath, ".git")); os.IsNotExist(err) { + if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err != nil { fmt.Printf(" %s %s (%s)\n", dimStyle.Render("○"), name, i18n.T("cmd.pkg.update.not_installed")) skipped++ continue @@ -219,7 +219,7 @@ func runPkgOutdated() error { for _, r := range reg.List() { repoPath := filepath.Join(basePath, r.Name) - if _, err := os.Stat(filepath.Join(repoPath, ".git")); os.IsNotExist(err) { + if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err != nil { notInstalled++ continue } diff --git a/internal/cmd/sdk/detect.go b/internal/cmd/sdk/detect.go index aeb221f1..a835ab88 100644 --- a/internal/cmd/sdk/detect.go +++ b/internal/cmd/sdk/detect.go @@ -2,9 +2,10 @@ package sdk import ( "fmt" - "os" "path/filepath" "strings" + + coreio "github.com/host-uk/core/pkg/io" ) // commonSpecPaths are checked in order when no spec is configured. @@ -25,7 +26,7 @@ func (s *SDK) DetectSpec() (string, error) { // 1. Check configured path if s.config.Spec != "" { specPath := filepath.Join(s.projectDir, s.config.Spec) - if _, err := os.Stat(specPath); err == nil { + if coreio.Local.IsFile(specPath) { return specPath, nil } return "", fmt.Errorf("sdk.DetectSpec: configured spec not found: %s", s.config.Spec) @@ -34,7 +35,7 @@ func (s *SDK) DetectSpec() (string, error) { // 2. Check common paths for _, p := range commonSpecPaths { specPath := filepath.Join(s.projectDir, p) - if _, err := os.Stat(specPath); err == nil { + if coreio.Local.IsFile(specPath) { return specPath, nil } } @@ -51,12 +52,12 @@ func (s *SDK) DetectSpec() (string, error) { // detectScramble checks for Laravel Scramble and exports the spec. func (s *SDK) detectScramble() (string, error) { composerPath := filepath.Join(s.projectDir, "composer.json") - if _, err := os.Stat(composerPath); err != nil { + if !coreio.Local.IsFile(composerPath) { return "", fmt.Errorf("no composer.json") } // Check for scramble in composer.json - data, err := os.ReadFile(composerPath) + data, err := coreio.Local.Read(composerPath) if err != nil { return "", err } @@ -71,8 +72,7 @@ func (s *SDK) detectScramble() (string, error) { } // containsScramble checks if composer.json includes scramble. -func containsScramble(data []byte) bool { - content := string(data) +func containsScramble(content string) bool { return strings.Contains(content, "dedoc/scramble") || strings.Contains(content, "\"scramble\"") } diff --git a/internal/cmd/sdk/detect_test.go b/internal/cmd/sdk/detect_test.go index 4511e08f..fef2dbcb 100644 --- a/internal/cmd/sdk/detect_test.go +++ b/internal/cmd/sdk/detect_test.go @@ -62,7 +62,7 @@ func TestContainsScramble(t *testing.T) { } for _, tt := range tests { - assert.Equal(t, tt.expected, containsScramble([]byte(tt.data))) + assert.Equal(t, tt.expected, containsScramble(tt.data)) } } diff --git a/internal/cmd/sdk/generators/go.go b/internal/cmd/sdk/generators/go.go index e2c2bc16..0aff5279 100644 --- a/internal/cmd/sdk/generators/go.go +++ b/internal/cmd/sdk/generators/go.go @@ -6,6 +6,8 @@ import ( "os" "os/exec" "path/filepath" + + coreio "github.com/host-uk/core/pkg/io" ) // GoGenerator generates Go SDKs from OpenAPI specs. @@ -34,7 +36,7 @@ func (g *GoGenerator) Install() string { // Generate creates SDK from OpenAPI spec. func (g *GoGenerator) Generate(ctx context.Context, opts Options) error { - if err := os.MkdirAll(opts.OutputDir, 0755); err != nil { + if err := coreio.Local.EnsureDir(opts.OutputDir); err != nil { return fmt.Errorf("go.Generate: failed to create output dir: %w", err) } @@ -61,7 +63,7 @@ func (g *GoGenerator) generateNative(ctx context.Context, opts Options) error { } goMod := fmt.Sprintf("module %s\n\ngo 1.21\n", opts.PackageName) - return os.WriteFile(filepath.Join(opts.OutputDir, "go.mod"), []byte(goMod), 0644) + return coreio.Local.Write(filepath.Join(opts.OutputDir, "go.mod"), goMod) } func (g *GoGenerator) generateDocker(ctx context.Context, opts Options) error { diff --git a/internal/cmd/sdk/generators/php.go b/internal/cmd/sdk/generators/php.go index 6403af37..ce701916 100644 --- a/internal/cmd/sdk/generators/php.go +++ b/internal/cmd/sdk/generators/php.go @@ -6,6 +6,8 @@ import ( "os" "os/exec" "path/filepath" + + coreio "github.com/host-uk/core/pkg/io" ) // PHPGenerator generates PHP SDKs from OpenAPI specs. @@ -38,7 +40,7 @@ func (g *PHPGenerator) Generate(ctx context.Context, opts Options) error { return fmt.Errorf("php.Generate: Docker is required but not available") } - if err := os.MkdirAll(opts.OutputDir, 0755); err != nil { + if err := coreio.Local.EnsureDir(opts.OutputDir); err != nil { return fmt.Errorf("php.Generate: failed to create output dir: %w", err) } diff --git a/internal/cmd/sdk/generators/python.go b/internal/cmd/sdk/generators/python.go index bd5f91f0..a95bcb6d 100644 --- a/internal/cmd/sdk/generators/python.go +++ b/internal/cmd/sdk/generators/python.go @@ -6,6 +6,8 @@ import ( "os" "os/exec" "path/filepath" + + coreio "github.com/host-uk/core/pkg/io" ) // PythonGenerator generates Python SDKs from OpenAPI specs. @@ -34,7 +36,7 @@ func (g *PythonGenerator) Install() string { // Generate creates SDK from OpenAPI spec. func (g *PythonGenerator) Generate(ctx context.Context, opts Options) error { - if err := os.MkdirAll(opts.OutputDir, 0755); err != nil { + if err := coreio.Local.EnsureDir(opts.OutputDir); err != nil { return fmt.Errorf("python.Generate: failed to create output dir: %w", err) } diff --git a/internal/cmd/sdk/generators/typescript.go b/internal/cmd/sdk/generators/typescript.go index c88b9b6e..843a146b 100644 --- a/internal/cmd/sdk/generators/typescript.go +++ b/internal/cmd/sdk/generators/typescript.go @@ -6,6 +6,8 @@ import ( "os" "os/exec" "path/filepath" + + coreio "github.com/host-uk/core/pkg/io" ) // TypeScriptGenerator generates TypeScript SDKs from OpenAPI specs. @@ -38,7 +40,7 @@ func (g *TypeScriptGenerator) Install() string { // Generate creates SDK from OpenAPI spec. func (g *TypeScriptGenerator) Generate(ctx context.Context, opts Options) error { - if err := os.MkdirAll(opts.OutputDir, 0755); err != nil { + if err := coreio.Local.EnsureDir(opts.OutputDir); err != nil { return fmt.Errorf("typescript.Generate: failed to create output dir: %w", err) } diff --git a/internal/cmd/workspace/config.go b/internal/cmd/workspace/config.go index fc781b5b..2be8e35f 100644 --- a/internal/cmd/workspace/config.go +++ b/internal/cmd/workspace/config.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" + coreio "github.com/host-uk/core/pkg/io" "gopkg.in/yaml.v3" ) @@ -28,9 +29,14 @@ func DefaultConfig() *WorkspaceConfig { // Returns nil if no config file exists (caller should check for nil). func LoadConfig(dir string) (*WorkspaceConfig, error) { path := filepath.Join(dir, ".core", "workspace.yaml") - data, err := os.ReadFile(path) + data, err := coreio.Local.Read(path) if err != nil { - if os.IsNotExist(err) { + // If using Local.Read, it returns error on not found. + // We can check if file exists first or handle specific error if exposed. + // Simplest is to check existence first or assume IsNotExist. + // Since we don't have easy IsNotExist check on coreio error returned yet (uses wrapped error), + // let's check IsFile first. + if !coreio.Local.IsFile(path) { // Try parent directory parent := filepath.Dir(dir) if parent != dir { @@ -43,7 +49,7 @@ func LoadConfig(dir string) (*WorkspaceConfig, error) { } config := DefaultConfig() - if err := yaml.Unmarshal(data, config); err != nil { + if err := yaml.Unmarshal([]byte(data), config); err != nil { return nil, fmt.Errorf("failed to parse workspace config: %w", err) } @@ -57,7 +63,7 @@ func LoadConfig(dir string) (*WorkspaceConfig, error) { // SaveConfig saves the configuration to the given directory's .core/workspace.yaml. func SaveConfig(dir string, config *WorkspaceConfig) error { coreDir := filepath.Join(dir, ".core") - if err := os.MkdirAll(coreDir, 0755); err != nil { + if err := coreio.Local.EnsureDir(coreDir); err != nil { return fmt.Errorf("failed to create .core directory: %w", err) } @@ -67,7 +73,7 @@ func SaveConfig(dir string, config *WorkspaceConfig) error { return fmt.Errorf("failed to marshal workspace config: %w", err) } - if err := os.WriteFile(path, data, 0644); err != nil { + if err := coreio.Local.Write(path, string(data)); err != nil { return fmt.Errorf("failed to write workspace config: %w", err) } @@ -82,7 +88,7 @@ func FindWorkspaceRoot() (string, error) { } for { - if _, err := os.Stat(filepath.Join(dir, ".core", "workspace.yaml")); err == nil { + if coreio.Local.IsFile(filepath.Join(dir, ".core", "workspace.yaml")) { return dir, nil }