feat(release): migrate filesystem operations to io.Local abstraction

Migrate config.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
- os.MkdirAll → io.Local.EnsureDir
- os.WriteFile → io.Local.Write

Migrate release.go:
- os.Stat → io.Local.IsDir
- os.ReadDir → io.Local.List

Uses filepath.Abs for relative path support.

Part of #101 (io.Medium migration tracking issue).

Closes #106

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-02-02 04:56:07 +00:00
parent d50e6982de
commit 0bf91842d7
2 changed files with 27 additions and 10 deletions

View file

@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"github.com/host-uk/core/pkg/io"
"gopkg.in/yaml.v3"
)
@ -171,7 +172,13 @@ type ChangelogConfig struct {
func LoadConfig(dir string) (*Config, error) {
configPath := filepath.Join(dir, ConfigDir, ConfigFileName)
data, err := os.ReadFile(configPath)
// Convert to absolute path for io.Local
absPath, err := filepath.Abs(configPath)
if err != nil {
return nil, fmt.Errorf("release.LoadConfig: failed to resolve path: %w", err)
}
content, err := io.Local.Read(absPath)
if err != nil {
if os.IsNotExist(err) {
cfg := DefaultConfig()
@ -182,7 +189,7 @@ func LoadConfig(dir string) (*Config, error) {
}
var cfg Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
if err := yaml.Unmarshal([]byte(content), &cfg); err != nil {
return nil, fmt.Errorf("release.LoadConfig: failed to parse config file: %w", err)
}
@ -263,8 +270,12 @@ func ConfigPath(dir string) string {
// ConfigExists checks if a release config file exists in the given directory.
func ConfigExists(dir string) bool {
_, err := os.Stat(ConfigPath(dir))
return err == nil
configPath := ConfigPath(dir)
absPath, err := filepath.Abs(configPath)
if err != nil {
return false
}
return io.Local.IsFile(absPath)
}
// GetRepository returns the repository from the config.
@ -281,9 +292,15 @@ func (c *Config) GetProjectName() string {
func WriteConfig(cfg *Config, dir string) error {
configPath := ConfigPath(dir)
// Convert to absolute path for io.Local
absPath, err := filepath.Abs(configPath)
if err != nil {
return fmt.Errorf("release.WriteConfig: failed to resolve path: %w", err)
}
// Ensure directory exists
configDir := filepath.Dir(configPath)
if err := os.MkdirAll(configDir, 0755); err != nil {
configDir := filepath.Dir(absPath)
if err := io.Local.EnsureDir(configDir); err != nil {
return fmt.Errorf("release.WriteConfig: failed to create directory: %w", err)
}
@ -292,7 +309,7 @@ func WriteConfig(cfg *Config, dir string) error {
return fmt.Errorf("release.WriteConfig: failed to marshal config: %w", err)
}
if err := os.WriteFile(configPath, data, 0644); err != nil {
if err := io.Local.Write(absPath, string(data)); err != nil {
return fmt.Errorf("release.WriteConfig: failed to write config file: %w", err)
}

View file

@ -6,12 +6,12 @@ package release
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/host-uk/core/pkg/build"
"github.com/host-uk/core/pkg/build/builders"
"github.com/host-uk/core/pkg/io"
"github.com/host-uk/core/pkg/release/publishers"
)
@ -103,13 +103,13 @@ func Publish(ctx context.Context, cfg *Config, dryRun bool) (*Release, error) {
// findArtifacts discovers pre-built artifacts in the dist directory.
func findArtifacts(distDir string) ([]build.Artifact, error) {
if _, err := os.Stat(distDir); os.IsNotExist(err) {
if !io.Local.IsDir(distDir) {
return nil, fmt.Errorf("dist/ directory not found")
}
var artifacts []build.Artifact
entries, err := os.ReadDir(distDir)
entries, err := io.Local.List(distDir)
if err != nil {
return nil, fmt.Errorf("failed to read dist/: %w", err)
}