feat(open,generate): implement command parity
This commit is contained in:
@@ -176,7 +176,9 @@ type cdCmd struct {
|
|||||||
Castle string `arg:"" optional:"" name:"CASTLE" help:"Castle name."`
|
Castle string `arg:"" optional:"" name:"CASTLE" help:"Castle name."`
|
||||||
}
|
}
|
||||||
|
|
||||||
type openCmd struct{}
|
type openCmd struct {
|
||||||
|
Castle string `arg:"" optional:"" name:"CASTLE" help:"Castle name."`
|
||||||
|
}
|
||||||
|
|
||||||
type execCmd struct{}
|
type execCmd struct{}
|
||||||
|
|
||||||
@@ -186,7 +188,9 @@ type rcCmd struct {
|
|||||||
Castle string `arg:"" optional:"" name:"CASTLE" help:"Castle name."`
|
Castle string `arg:"" optional:"" name:"CASTLE" help:"Castle name."`
|
||||||
}
|
}
|
||||||
|
|
||||||
type generateCmd struct{}
|
type generateCmd struct {
|
||||||
|
Path string `arg:"" name:"PATH" help:"Path to generate a homesick-ready castle repository."`
|
||||||
|
}
|
||||||
|
|
||||||
func (c *pullCmd) Run(app *core.App) error { return app.Pull(defaultCastle(c.Castle)) }
|
func (c *pullCmd) Run(app *core.App) error { return app.Pull(defaultCastle(c.Castle)) }
|
||||||
func (c *pushCmd) Run(app *core.App) error { return app.Push(defaultCastle(c.Castle)) }
|
func (c *pushCmd) Run(app *core.App) error { return app.Push(defaultCastle(c.Castle)) }
|
||||||
@@ -195,11 +199,11 @@ func (c *commitCmd) Run(app *core.App) error {
|
|||||||
}
|
}
|
||||||
func (c *destroyCmd) Run(app *core.App) error { return app.Destroy(defaultCastle(c.Castle)) }
|
func (c *destroyCmd) Run(app *core.App) error { return app.Destroy(defaultCastle(c.Castle)) }
|
||||||
func (c *cdCmd) Run(app *core.App) error { return app.ShowPath(defaultCastle(c.Castle)) }
|
func (c *cdCmd) Run(app *core.App) error { return app.ShowPath(defaultCastle(c.Castle)) }
|
||||||
func (c *openCmd) Run() error { return notImplemented("open") }
|
func (c *openCmd) Run(app *core.App) error { return app.Open(defaultCastle(c.Castle)) }
|
||||||
func (c *execCmd) Run() error { return notImplemented("exec") }
|
func (c *execCmd) Run() error { return notImplemented("exec") }
|
||||||
func (c *execAllCmd) Run() error { return notImplemented("exec_all") }
|
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 *rcCmd) Run(app *core.App) error { return app.Rc(defaultCastle(c.Castle)) }
|
||||||
func (c *generateCmd) Run() error { return notImplemented("generate") }
|
func (c *generateCmd) Run(app *core.App) error { return app.Generate(c.Path) }
|
||||||
|
|
||||||
func defaultCastle(castle string) string {
|
func defaultCastle(castle string) string {
|
||||||
if strings.TrimSpace(castle) == "" {
|
if strings.TrimSpace(castle) == "" {
|
||||||
|
|||||||
@@ -192,6 +192,68 @@ func (a *App) Destroy(castle string) error {
|
|||||||
return os.RemoveAll(castleRoot)
|
return os.RemoveAll(castleRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *App) Open(castle string) error {
|
||||||
|
if strings.TrimSpace(castle) == "" {
|
||||||
|
castle = "dotfiles"
|
||||||
|
}
|
||||||
|
|
||||||
|
editor := strings.TrimSpace(os.Getenv("EDITOR"))
|
||||||
|
if editor == "" {
|
||||||
|
return errors.New("the $EDITOR environment variable must be set to use this command")
|
||||||
|
}
|
||||||
|
|
||||||
|
castleHome := filepath.Join(a.ReposDir, castle, "home")
|
||||||
|
if info, err := os.Stat(castleHome); err != nil || !info.IsDir() {
|
||||||
|
return fmt.Errorf("could not open %s, expected %s to exist and contain dotfiles", castle, castleHome)
|
||||||
|
}
|
||||||
|
|
||||||
|
castleRoot := filepath.Join(a.ReposDir, castle)
|
||||||
|
cmd := exec.Command("sh", "-c", editor+" .")
|
||||||
|
cmd.Dir = castleRoot
|
||||||
|
cmd.Stdout = a.Stdout
|
||||||
|
cmd.Stderr = a.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return fmt.Errorf("open failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *App) Generate(castlePath string) error {
|
||||||
|
trimmed := strings.TrimSpace(castlePath)
|
||||||
|
if trimmed == "" {
|
||||||
|
return errors.New("generate requires PATH")
|
||||||
|
}
|
||||||
|
|
||||||
|
absCastle, err := filepath.Abs(trimmed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(absCastle, 0o755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := runGitWithIO(absCastle, a.Stdout, a.Stderr, "init"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
githubUser := ""
|
||||||
|
if out, cfgErr := gitOutput(absCastle, "config", "github.user"); cfgErr == nil {
|
||||||
|
githubUser = strings.TrimSpace(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
if githubUser != "" {
|
||||||
|
repoName := filepath.Base(absCastle)
|
||||||
|
url := fmt.Sprintf("git@github.com:%s/%s.git", githubUser, repoName)
|
||||||
|
if err := runGitWithIO(absCastle, a.Stdout, a.Stderr, "remote", "add", "origin", url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return os.MkdirAll(filepath.Join(absCastle, "home"), 0o755)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *App) Link(castle string) error {
|
func (a *App) Link(castle string) error {
|
||||||
if strings.TrimSpace(castle) == "" {
|
if strings.TrimSpace(castle) == "" {
|
||||||
castle = "dotfiles"
|
castle = "dotfiles"
|
||||||
|
|||||||
Reference in New Issue
Block a user