feat(rc): implement rc command with .homesick.d script execution

- App.Rc runs all executable files in <castle>/.homesick.d in sorted
  (lexicographic) order with the castle root as cwd
- Non-executable files are skipped
- stdout/stderr from scripts forward to App writers
- If .homesickrc exists and parity.rb does not yet exist in .homesick.d,
  a Ruby wrapper (parity.rb) is generated before execution
- Existing parity.rb is never overwritten
- Wire rcCmd in CLI with optional CASTLE argument (defaults to dotfiles)
This commit is contained in:
Micheal Wilkinson
2026-03-20 15:29:58 +00:00
parent 75f636f9ba
commit a381746cef
3 changed files with 114 additions and 17 deletions

View File

@@ -171,20 +171,22 @@ type execCmd struct{}
type execAllCmd struct{}
type rcCmd struct{}
type rcCmd struct {
Castle string `arg:"" optional:"" name:"CASTLE" help:"Castle name."`
}
type generateCmd struct{}
func (c *pullCmd) Run() error { return notImplemented("pull") }
func (c *pushCmd) Run() error { return notImplemented("push") }
func (c *commitCmd) Run() error { return notImplemented("commit") }
func (c *destroyCmd) Run() error { return notImplemented("destroy") }
func (c *cdCmd) Run() error { return notImplemented("cd") }
func (c *openCmd) Run() error { return notImplemented("open") }
func (c *execCmd) Run() error { return notImplemented("exec") }
func (c *execAllCmd) Run() error { return notImplemented("exec_all") }
func (c *rcCmd) Run() error { return notImplemented("rc") }
func (c *generateCmd) Run() error { return notImplemented("generate") }
func (c *pullCmd) Run() error { return notImplemented("pull") }
func (c *pushCmd) Run() error { return notImplemented("push") }
func (c *commitCmd) Run() error { return notImplemented("commit") }
func (c *destroyCmd) Run() error { return notImplemented("destroy") }
func (c *cdCmd) Run() error { return notImplemented("cd") }
func (c *openCmd) Run() error { return notImplemented("open") }
func (c *execCmd) Run() error { return notImplemented("exec") }
func (c *execAllCmd) Run() error { return notImplemented("exec_all") }
func (c *rcCmd) Run(app *core.App) error { return app.Rc(defaultCastle(c.Castle)) }
func (c *generateCmd) Run() error { return notImplemented("generate") }
func defaultCastle(castle string) string {
if strings.TrimSpace(castle) == "" {