2026-02-01 05:20:46 +00:00
|
|
|
package dev
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"testing"
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
|
2026-02-16 14:24:37 +00:00
|
|
|
"forge.lthn.ai/core/go/pkg/io"
|
2026-02-01 05:20:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestFindWorkflows_Good(t *testing.T) {
|
|
|
|
|
// Create a temp directory with workflow files
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
workflowsDir := filepath.Join(tmpDir, ".github", "workflows")
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.EnsureDir(workflowsDir); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create workflows dir: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create some workflow files
|
|
|
|
|
for _, name := range []string{"qa.yml", "tests.yml", "codeql.yaml"} {
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.Write(filepath.Join(workflowsDir, name), "name: Test"); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create workflow file: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a non-workflow file (should be ignored)
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.Write(filepath.Join(workflowsDir, "readme.md"), "# Workflows"); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create readme file: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
workflows := findWorkflows(tmpDir)
|
|
|
|
|
|
|
|
|
|
if len(workflows) != 3 {
|
|
|
|
|
t.Errorf("Expected 3 workflows, got %d", len(workflows))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check that all expected workflows are found
|
|
|
|
|
found := make(map[string]bool)
|
|
|
|
|
for _, wf := range workflows {
|
|
|
|
|
found[wf] = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, expected := range []string{"qa.yml", "tests.yml", "codeql.yaml"} {
|
|
|
|
|
if !found[expected] {
|
|
|
|
|
t.Errorf("Expected to find workflow %s", expected)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindWorkflows_NoWorkflowsDir(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
workflows := findWorkflows(tmpDir)
|
|
|
|
|
|
|
|
|
|
if len(workflows) != 0 {
|
|
|
|
|
t.Errorf("Expected 0 workflows for non-existent dir, got %d", len(workflows))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindTemplateWorkflow_Good(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
templatesDir := filepath.Join(tmpDir, ".github", "workflow-templates")
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.EnsureDir(templatesDir); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create templates dir: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
templateContent := "name: QA\non: [push]"
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.Write(filepath.Join(templatesDir, "qa.yml"), templateContent); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create template file: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test finding with .yml extension
|
|
|
|
|
result := findTemplateWorkflow(tmpDir, "qa.yml")
|
|
|
|
|
if result == "" {
|
|
|
|
|
t.Error("Expected to find qa.yml template")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test finding without extension (should auto-add .yml)
|
|
|
|
|
result = findTemplateWorkflow(tmpDir, "qa")
|
|
|
|
|
if result == "" {
|
|
|
|
|
t.Error("Expected to find qa template without extension")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindTemplateWorkflow_FallbackToWorkflows(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
workflowsDir := filepath.Join(tmpDir, ".github", "workflows")
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.EnsureDir(workflowsDir); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create workflows dir: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
templateContent := "name: Tests\non: [push]"
|
chore(io): migrate filesystem operations to io.Local abstraction (#247)
* feat(devops): migrate filesystem operations to io.Local abstraction
Migrate config.go:
- os.ReadFile → io.Local.Read
Migrate devops.go:
- os.Stat → io.Local.IsFile
Migrate images.go:
- os.MkdirAll → io.Local.EnsureDir
- os.Stat → io.Local.IsFile
- os.ReadFile → io.Local.Read
- os.WriteFile → io.Local.Write
Migrate test.go:
- os.ReadFile → io.Local.Read
- os.Stat → io.Local.IsFile
Migrate claude.go:
- os.Stat → io.Local.IsDir
Updated tests to reflect improved behavior:
- Manifest.Save() now creates parent directories
- hasFile() correctly returns false for directories
Part of #101 (io.Medium migration tracking issue).
Closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate remaining packages to io.Local abstraction
Migrate filesystem operations to use the io.Local abstraction for
improved security, testability, and consistency:
- pkg/cache: Replace os.ReadFile, WriteFile, Remove, RemoveAll with
io.Local equivalents. io.Local.Write creates parent dirs automatically.
- pkg/agentic: Migrate config.go and context.go to use io.Local for
reading config files and gathering file context.
- pkg/repos: Use io.Local.Read, Exists, IsDir, List for registry
operations and git repo detection.
- pkg/release: Use io.Local for config loading, existence checks,
and artifact discovery.
- pkg/devops/sources: Use io.Local.EnsureDir for CDN download.
All paths are converted to absolute using filepath.Abs() before
calling io.Local methods to handle relative paths correctly.
Closes #104, closes #106, closes #108, closes #111
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate pkg/cli and pkg/container to io.Local abstraction
Continue io.Medium migration for the remaining packages:
- pkg/cli/daemon.go: PIDFile Acquire/Release now use io.Local.Read,
Delete, and Write for managing daemon PID files.
- pkg/container/state.go: LoadState and SaveState use io.Local for
JSON state persistence. EnsureLogsDir uses io.Local.EnsureDir.
- pkg/container/templates.go: Template loading and directory scanning
now use io.Local.IsFile, IsDir, Read, and List.
- pkg/container/linuxkit.go: Image validation uses io.Local.IsFile,
log file check uses io.Local.IsFile. Streaming log file creation
(os.Create) remains unchanged as io.Local doesn't support streaming.
Closes #105, closes #107
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit feedback - use errors.E for context
Add contextual error handling using errors.E helper as suggested:
- config.go: Wrap LoadConfig read/parse errors
- images.go: Wrap NewImageManager, loadManifest, and Manifest.Save errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(io): add contextual error handling with E() helper
Address CodeRabbit review feedback by wrapping raw errors with the
errors.E() helper to provide service/action context for debugging:
- pkg/cache: wrap cache.New, Get, Set, Delete, Clear errors
- pkg/devops/test: wrap LoadTestConfig path/read/parse errors
- pkg/cli/daemon: wrap PIDFile.Release path resolution error
- pkg/container/state: wrap LoadState/SaveState errors
- pkg/container/templates: wrap GetTemplate embedded/user read errors
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore(io): migrate internal/cmd/dev to io.Local abstraction
- Replace os.Stat with io.Local.Stat in cmd_file_sync.go
- Update test file to use io.Local.EnsureDir and io.Local.Write
- Add filepath.Abs for proper path resolution before io.Local calls
Closes #114
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use log.E instead of errors.E in cmd_file_sync
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 08:12:59 +00:00
|
|
|
if err := io.Local.Write(filepath.Join(workflowsDir, "tests.yml"), templateContent); err != nil {
|
2026-02-01 05:20:46 +00:00
|
|
|
t.Fatalf("Failed to create workflow file: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result := findTemplateWorkflow(tmpDir, "tests.yml")
|
|
|
|
|
if result == "" {
|
|
|
|
|
t.Error("Expected to find tests.yml in workflows dir")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestFindTemplateWorkflow_NotFound(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
|
|
|
|
|
result := findTemplateWorkflow(tmpDir, "nonexistent.yml")
|
|
|
|
|
if result != "" {
|
|
|
|
|
t.Errorf("Expected empty string for non-existent template, got %s", result)
|
|
|
|
|
}
|
|
|
|
|
}
|