parent
aaa7739749
commit
9d6ffaf219
4 changed files with 36 additions and 49 deletions
BIN
core-test
BIN
core-test
Binary file not shown.
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/host-uk/core/pkg/errors"
|
"github.com/host-uk/core/pkg/errors"
|
||||||
"github.com/host-uk/core/pkg/git"
|
"github.com/host-uk/core/pkg/git"
|
||||||
"github.com/host-uk/core/pkg/i18n"
|
"github.com/host-uk/core/pkg/i18n"
|
||||||
|
"github.com/host-uk/core/pkg/io"
|
||||||
"github.com/host-uk/core/pkg/repos"
|
"github.com/host-uk/core/pkg/repos"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -76,8 +77,8 @@ func runApply() error {
|
||||||
|
|
||||||
// Validate script exists
|
// Validate script exists
|
||||||
if applyScript != "" {
|
if applyScript != "" {
|
||||||
if _, err := os.Stat(applyScript); err != nil {
|
if !io.Local.IsFile(applyScript) {
|
||||||
return errors.E("dev.apply", "script not found: "+applyScript, err)
|
return errors.E("dev.apply", "script not found: "+applyScript, nil) // Error mismatch? IsFile returns bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ package dev
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -19,6 +18,7 @@ import (
|
||||||
"github.com/host-uk/core/pkg/errors"
|
"github.com/host-uk/core/pkg/errors"
|
||||||
"github.com/host-uk/core/pkg/git"
|
"github.com/host-uk/core/pkg/git"
|
||||||
"github.com/host-uk/core/pkg/i18n"
|
"github.com/host-uk/core/pkg/i18n"
|
||||||
|
coreio "github.com/host-uk/core/pkg/io"
|
||||||
"github.com/host-uk/core/pkg/repos"
|
"github.com/host-uk/core/pkg/repos"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -63,7 +63,24 @@ func runFileSync(source string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate source exists
|
// Validate source exists
|
||||||
sourceInfo, err := os.Stat(source)
|
sourceInfo, err := os.Stat(source) // Keep os.Stat for local source check or use coreio? coreio.Local.IsFile is bool.
|
||||||
|
// If source is local file on disk (not in medium), we can use os.Stat.
|
||||||
|
// But concept is everything is via Medium?
|
||||||
|
// User is running CLI on host. `source` is relative to CWD.
|
||||||
|
// coreio.Local uses absolute path or relative to root (which is "/" by default).
|
||||||
|
// So coreio.Local works.
|
||||||
|
if !coreio.Local.IsFile(source) {
|
||||||
|
// Might be directory
|
||||||
|
// IsFile returns false for directory.
|
||||||
|
}
|
||||||
|
// Let's rely on os.Stat for initial source check to distinguish dir vs file easily if coreio doesn't expose Stat.
|
||||||
|
// coreio doesn't expose Stat.
|
||||||
|
|
||||||
|
// Check using standard os for source determination as we are outside strict sandbox for input args potentially?
|
||||||
|
// But we should use coreio where possible.
|
||||||
|
// coreio.Local.List worked for dirs.
|
||||||
|
// Let's stick to os.Stat for source properties finding as typically allowed for CLI args.
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.E("dev.sync", i18n.T("cmd.dev.file_sync.error.source_not_found", map[string]interface{}{"Path": source}), err)
|
return errors.E("dev.sync", i18n.T("cmd.dev.file_sync.error.source_not_found", map[string]interface{}{"Path": source}), err)
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +130,9 @@ func runFileSync(source string) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := copyFile(source, destPath); err != nil {
|
// Ensure dir exists
|
||||||
|
coreio.Local.EnsureDir(filepath.Dir(destPath))
|
||||||
|
if err := coreio.Copy(coreio.Local, source, coreio.Local, destPath); err != nil {
|
||||||
cli.Print(" %s %s: copy failed: %s\n", errorStyle.Render("x"), repoName, err)
|
cli.Print(" %s %s: copy failed: %s\n", errorStyle.Render("x"), repoName, err)
|
||||||
failed++
|
failed++
|
||||||
continue
|
continue
|
||||||
|
|
@ -287,47 +306,14 @@ func gitCommandQuiet(ctx context.Context, dir string, args ...string) (string, e
|
||||||
return string(output), nil
|
return string(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyFile copies a single file
|
|
||||||
func copyFile(src, dst string) error {
|
|
||||||
// Ensure parent directory exists
|
|
||||||
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
srcFile, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer srcFile.Close()
|
|
||||||
|
|
||||||
srcInfo, err := srcFile.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
dstFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, srcInfo.Mode())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer dstFile.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(dstFile, srcFile)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// copyDir recursively copies a directory
|
// copyDir recursively copies a directory
|
||||||
func copyDir(src, dst string) error {
|
func copyDir(src, dst string) error {
|
||||||
srcInfo, err := os.Stat(src)
|
entries, err := coreio.Local.List(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(dst, srcInfo.Mode()); err != nil {
|
if err := coreio.Local.EnsureDir(dst); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
entries, err := os.ReadDir(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,7 +326,7 @@ func copyDir(src, dst string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := copyFile(srcPath, dstPath); err != nil {
|
if err := coreio.Copy(coreio.Local, srcPath, coreio.Local, dstPath); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
package dev
|
package dev
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/host-uk/core/pkg/cli"
|
"github.com/host-uk/core/pkg/cli"
|
||||||
"github.com/host-uk/core/pkg/i18n"
|
"github.com/host-uk/core/pkg/i18n"
|
||||||
|
"github.com/host-uk/core/pkg/io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Workflow command flags
|
// Workflow command flags
|
||||||
|
|
@ -156,7 +156,7 @@ func runWorkflowSync(registryPath string, workflowFile string, dryRun bool) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read template content
|
// Read template content
|
||||||
templateContent, err := os.ReadFile(templatePath)
|
templateContent, err := io.Local.Read(templatePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.Wrap(err, i18n.T("cmd.dev.workflow.read_template_error"))
|
return cli.Wrap(err, i18n.T("cmd.dev.workflow.read_template_error"))
|
||||||
}
|
}
|
||||||
|
|
@ -189,8 +189,8 @@ func runWorkflowSync(registryPath string, workflowFile string, dryRun bool) erro
|
||||||
destPath := filepath.Join(destDir, workflowFile)
|
destPath := filepath.Join(destDir, workflowFile)
|
||||||
|
|
||||||
// Check if workflow already exists and is identical
|
// Check if workflow already exists and is identical
|
||||||
if existingContent, err := os.ReadFile(destPath); err == nil {
|
if existingContent, err := io.Local.Read(destPath); err == nil {
|
||||||
if string(existingContent) == string(templateContent) {
|
if existingContent == templateContent {
|
||||||
cli.Print(" %s %s %s\n",
|
cli.Print(" %s %s %s\n",
|
||||||
dimStyle.Render("-"),
|
dimStyle.Render("-"),
|
||||||
repoNameStyle.Render(repo.Name),
|
repoNameStyle.Render(repo.Name),
|
||||||
|
|
@ -210,7 +210,7 @@ func runWorkflowSync(registryPath string, workflowFile string, dryRun bool) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create .github/workflows directory if needed
|
// Create .github/workflows directory if needed
|
||||||
if err := os.MkdirAll(destDir, 0755); err != nil {
|
if err := io.Local.EnsureDir(destDir); err != nil {
|
||||||
cli.Print(" %s %s %s\n",
|
cli.Print(" %s %s %s\n",
|
||||||
errorStyle.Render(cli.Glyph(":cross:")),
|
errorStyle.Render(cli.Glyph(":cross:")),
|
||||||
repoNameStyle.Render(repo.Name),
|
repoNameStyle.Render(repo.Name),
|
||||||
|
|
@ -220,7 +220,7 @@ func runWorkflowSync(registryPath string, workflowFile string, dryRun bool) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write workflow file
|
// Write workflow file
|
||||||
if err := os.WriteFile(destPath, templateContent, 0644); err != nil {
|
if err := io.Local.Write(destPath, templateContent); err != nil {
|
||||||
cli.Print(" %s %s %s\n",
|
cli.Print(" %s %s %s\n",
|
||||||
errorStyle.Render(cli.Glyph(":cross:")),
|
errorStyle.Render(cli.Glyph(":cross:")),
|
||||||
repoNameStyle.Render(repo.Name),
|
repoNameStyle.Render(repo.Name),
|
||||||
|
|
@ -264,7 +264,7 @@ func findWorkflows(dir string) []string {
|
||||||
workflowsDir = dir
|
workflowsDir = dir
|
||||||
}
|
}
|
||||||
|
|
||||||
entries, err := os.ReadDir(workflowsDir)
|
entries, err := io.Local.List(workflowsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +298,7 @@ func findTemplateWorkflow(registryDir, workflowFile string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, candidate := range candidates {
|
for _, candidate := range candidates {
|
||||||
if _, err := os.Stat(candidate); err == nil {
|
if io.Local.IsFile(candidate) {
|
||||||
return candidate
|
return candidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue