feat(cli): implement exec and exec_all commands
This commit is contained in:
@@ -219,6 +219,75 @@ func (a *App) Open(castle string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) Exec(castle string, command []string) error {
|
||||
commandString := strings.TrimSpace(strings.Join(command, " "))
|
||||
if commandString == "" {
|
||||
return errors.New("exec requires COMMAND")
|
||||
}
|
||||
|
||||
castleRoot := filepath.Join(a.ReposDir, castle)
|
||||
if _, err := os.Stat(castleRoot); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return fmt.Errorf("castle %q not found", castle)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("sh", "-c", commandString)
|
||||
cmd.Dir = castleRoot
|
||||
cmd.Stdout = a.Stdout
|
||||
cmd.Stderr = a.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("exec failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) ExecAll(command []string) error {
|
||||
commandString := strings.TrimSpace(strings.Join(command, " "))
|
||||
if commandString == "" {
|
||||
return errors.New("exec_all requires COMMAND")
|
||||
}
|
||||
|
||||
if _, err := os.Stat(a.ReposDir); err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var castles []string
|
||||
err := filepath.WalkDir(a.ReposDir, func(path string, d fs.DirEntry, walkErr error) error {
|
||||
if walkErr != nil {
|
||||
return walkErr
|
||||
}
|
||||
if !d.IsDir() || d.Name() != ".git" {
|
||||
return nil
|
||||
}
|
||||
|
||||
castleRoot := filepath.Dir(path)
|
||||
rel, err := filepath.Rel(a.ReposDir, castleRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
castles = append(castles, rel)
|
||||
return filepath.SkipDir
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sort.Strings(castles)
|
||||
for _, castle := range castles {
|
||||
if err := a.Exec(castle, []string{commandString}); err != nil {
|
||||
return fmt.Errorf("exec_all failed for %q: %w", castle, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) Generate(castlePath string) error {
|
||||
trimmed := strings.TrimSpace(castlePath)
|
||||
if trimmed == "" {
|
||||
|
||||
Reference in New Issue
Block a user