From cf05d80cb48fabd90f3d0b0ef480be1d2b554cc7 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:33:04 -0500 Subject: [PATCH] refactor(breaking): refactor flags to be more inline with their commands (#210) --- app/commands/cmd_list.go | 9 +++-- app/commands/cmd_new.go | 38 +++++++++++++++----- app/commands/controller.go | 13 ------- app/commands/resolve.go | 13 ++++--- app/commands/runner.go | 5 ++- main.go | 67 ++++++++++++++++++++--------------- tests/nested-snapshot.test.sh | 2 +- tests/runner.sh | 3 +- 8 files changed, 88 insertions(+), 62 deletions(-) diff --git a/app/commands/cmd_list.go b/app/commands/cmd_list.go index 2bd501d..30188c3 100644 --- a/app/commands/cmd_list.go +++ b/app/commands/cmd_list.go @@ -5,16 +5,19 @@ import ( "github.com/hay-kot/scaffold/app/scaffold/pkgs" "github.com/hay-kot/scaffold/internal/printer" - "github.com/urfave/cli/v2" ) -func (ctrl *Controller) List(ctx *cli.Context) error { +type FlagsList struct { + OutputDir string +} + +func (ctrl *Controller) List(flags FlagsList) error { systemScaffolds, err := pkgs.ListSystem(os.DirFS(ctrl.Flags.Cache)) if err != nil { return err } - localScaffolds, err := pkgs.ListLocal(os.DirFS(ctrl.Flags.OutputDir)) + localScaffolds, err := pkgs.ListLocal(os.DirFS(flags.OutputDir)) if err != nil { return err } diff --git a/app/commands/cmd_new.go b/app/commands/cmd_new.go index ad255a8..8ec0b2c 100644 --- a/app/commands/cmd_new.go +++ b/app/commands/cmd_new.go @@ -1,6 +1,7 @@ package commands import ( + "errors" "fmt" "math/rand" "os" @@ -9,6 +10,7 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/hay-kot/scaffold/app/core/fsast" + "github.com/hay-kot/scaffold/app/core/rwfs" "github.com/hay-kot/scaffold/app/scaffold" "github.com/hay-kot/scaffold/app/scaffold/pkgs" "github.com/hay-kot/scaffold/internal/styles" @@ -16,17 +18,32 @@ import ( ) type FlagsNew struct { - NoPrompt bool - Preset string - Snapshot string + NoPrompt bool + Preset string + Snapshot string + NoClobber bool + ForceApply bool + OutputDir string +} + +// OutputFS returns a WriteFS based on the OutputDir flag +func (f FlagsNew) OutputFS() rwfs.WriteFS { + if f.OutputDir == ":memory:" { + return rwfs.NewMemoryWFS() + } + + return rwfs.NewOsWFS(f.OutputDir) } func (ctrl *Controller) New(args []string, flags FlagsNew) error { if len(args) == 0 { - return fmt.Errorf("missing scaffold name") + ctrl.printer.FatalError(errors.New("missing scaffold path")) + return ctrl.List(FlagsList{ + OutputDir: flags.OutputDir, + }) } - path, err := ctrl.resolve(args[0], flags.NoPrompt) + path, err := ctrl.resolve(args[0], flags.OutputDir, flags.NoPrompt, flags.ForceApply) if err != nil { return err } @@ -47,7 +64,7 @@ func (ctrl *Controller) New(args []string, flags FlagsNew) error { varfunc = func(p *scaffold.Project) (map[string]any, error) { caseVars, ok := p.Conf.Presets[flags.Preset] if !ok { - return nil, fmt.Errorf("case %s not found", flags.Preset) + return nil, fmt.Errorf("preset '%s' not found", flags.Preset) } project, ok := caseVars["Project"].(string) @@ -76,13 +93,16 @@ func (ctrl *Controller) New(args []string, flags FlagsNew) error { } } - outfs := ctrl.Flags.OutputFS() + outfs := flags.OutputFS() err = ctrl.runscaffold(runconf{ scaffolddir: path, noPrompt: flags.NoPrompt, varfunc: varfunc, outputfs: outfs, + options: scaffold.Options{ + NoClobber: flags.NoClobber, + }, }) if err != nil { return err @@ -114,13 +134,13 @@ func (ctrl *Controller) New(args []string, flags FlagsNew) error { return nil } -func (ctrl *Controller) fuzzyFallBack(str string) ([]string, []string, error) { +func (ctrl *Controller) fuzzyFallBack(str, outputdir string) ([]string, []string, error) { systemScaffolds, err := pkgs.ListSystem(os.DirFS(ctrl.Flags.Cache)) if err != nil { return nil, nil, err } - localScaffolds, err := pkgs.ListLocal(os.DirFS(ctrl.Flags.OutputDir)) + localScaffolds, err := pkgs.ListLocal(os.DirFS(outputdir)) if err != nil { return nil, nil, err } diff --git a/app/commands/controller.go b/app/commands/controller.go index 4ad58ea..61bc706 100644 --- a/app/commands/controller.go +++ b/app/commands/controller.go @@ -6,7 +6,6 @@ import ( "os" "github.com/hay-kot/scaffold/app/core/engine" - "github.com/hay-kot/scaffold/app/core/rwfs" "github.com/hay-kot/scaffold/app/scaffold/scaffoldrc" "github.com/hay-kot/scaffold/internal/printer" "github.com/hay-kot/scaffold/internal/styles" @@ -14,23 +13,11 @@ import ( ) type Flags struct { - NoClobber bool - Force bool ScaffoldRCPath string Cache string - OutputDir string ScaffoldDirs []string } -// OutputFS returns a WriteFS based on the OutputDir flag -func (f Flags) OutputFS() rwfs.WriteFS { - if f.OutputDir == ":memory:" { - return rwfs.NewMemoryWFS() - } - - return rwfs.NewOsWFS(f.OutputDir) -} - type Controller struct { // Flags contains the CLI flags // that are from the root command diff --git a/app/commands/resolve.go b/app/commands/resolve.go index 49af6be..c7788b1 100644 --- a/app/commands/resolve.go +++ b/app/commands/resolve.go @@ -9,15 +9,20 @@ import ( "github.com/rs/zerolog/log" ) -func (ctrl *Controller) resolve(argPath string, noPrompt bool) (string, error) { +func (ctrl *Controller) resolve( + argPath string, + outputdir string, + noPrompt bool, + force bool, +) (string, error) { if argPath == "" { return "", fmt.Errorf("path is required") } // Status() call for go-git is too slow to be used here // https://github.com/go-git/go-git/issues/181 - if !ctrl.Flags.Force { - ok := checkWorkingTree(ctrl.Flags.OutputDir) + if !force { + ok := checkWorkingTree(outputdir) if !ok { log.Warn().Msg("working tree is dirty, use --force to apply changes") return "", nil @@ -54,7 +59,7 @@ func (ctrl *Controller) resolve(argPath string, noPrompt bool) (string, error) { return "", err } - systemMatches, localMatches, err := ctrl.fuzzyFallBack(argPath) + systemMatches, localMatches, err := ctrl.fuzzyFallBack(argPath, outputdir) if err != nil { return "", err } diff --git a/app/commands/runner.go b/app/commands/runner.go index 93e8a06..29584086 100644 --- a/app/commands/runner.go +++ b/app/commands/runner.go @@ -27,6 +27,7 @@ type runconf struct { varfunc func(*scaffold.Project) (map[string]any, error) // outputdir is the output directory or filesystem. outputfs rwfs.WriteFS + options scaffold.Options } // runscaffold runs the scaffold. This method exists outside of the `new` receiver function @@ -34,9 +35,7 @@ type runconf struct { // as possible. func (ctrl *Controller) runscaffold(cfg runconf) error { scaffoldFS := os.DirFS(cfg.scaffolddir) - p, err := scaffold.LoadProject(scaffoldFS, scaffold.Options{ - NoClobber: ctrl.Flags.NoClobber, - }) + p, err := scaffold.LoadProject(scaffoldFS, cfg.options) if err != nil { return err } diff --git a/main.go b/main.go index ca8b12d..ee1302c 100644 --- a/main.go +++ b/main.go @@ -76,24 +76,6 @@ func main() { Value: HomeDir(".scaffold/cache"), EnvVars: []string{"SCAFFOLD_CACHE"}, }, - &cli.BoolFlag{ - Name: "no-clobber", - Usage: "do not overwrite existing files", - EnvVars: []string{"SCAFFOLD_NO_CLOBBER"}, - Value: true, - }, - &cli.BoolFlag{ - Name: "force", - Usage: "apply changes when git tree is dirty", - Value: true, - EnvVars: []string{"SCAFFOLD_FORCE"}, - }, - &cli.StringFlag{ - Name: "output-dir", - Usage: "scaffold output directory (use ':memory:' for in-memory filesystem)", - Value: ".", - EnvVars: []string{"SCAFFOLD_OUT"}, - }, &cli.StringFlag{ Name: "log-level", Usage: "log level (debug, info, warn, error, fatal, panic)", @@ -109,7 +91,7 @@ func main() { Name: "theme", Usage: "theme to use for the scaffold output", Value: "scaffold", - EnvVars: []string{"SCAFFOLD_THEME", "SCAFFOLD_SETTINGS_THEME"}, + EnvVars: []string{"SCAFFOLD_SETTINGS_THEME", "SCAFFOLD_THEME"}, }, &cli.StringFlag{ Name: "run-hooks", @@ -119,9 +101,6 @@ func main() { }, Before: func(ctx *cli.Context) error { ctrl.Flags = commands.Flags{ - NoClobber: ctx.Bool("no-clobber"), - Force: ctx.Bool("force"), - OutputDir: ctx.String("output-dir"), Cache: ctx.String("cache"), ScaffoldRCPath: ctx.String("scaffoldrc"), ScaffoldDirs: ctx.StringSlice("scaffold-dir"), @@ -242,7 +221,7 @@ func main() { { Name: "new", Usage: "create a new project from a scaffold", - UsageText: "scaffold new [scaffold (url | path)] [flags]", + UsageText: "scaffold new [flags] [scaffold (url | path)]", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "no-prompt", @@ -259,20 +238,52 @@ func main() { Usage: "path or `stdout` to save the output ast", Value: "", }, + &cli.BoolFlag{ + Name: "no-clobber", + Usage: "do not overwrite existing files", + EnvVars: []string{"SCAFFOLD_NO_CLOBBER"}, + Value: true, + }, + &cli.BoolFlag{ + Name: "force", + Usage: "apply changes when git tree is dirty", + Value: true, + EnvVars: []string{"SCAFFOLD_FORCE"}, + }, + &cli.StringFlag{ + Name: "output-dir", + Usage: "scaffold output directory (use ':memory:' for in-memory filesystem)", + Value: ".", + EnvVars: []string{"SCAFFOLD_OUT"}, + }, }, Action: func(ctx *cli.Context) error { return ctrl.New(ctx.Args().Slice(), commands.FlagsNew{ - NoPrompt: ctx.Bool("no-prompt"), - Preset: ctx.String("preset"), - Snapshot: ctx.String("snapshot"), + NoPrompt: ctx.Bool("no-prompt"), + Preset: ctx.String("preset"), + Snapshot: ctx.String("snapshot"), + NoClobber: ctx.Bool("no-clobber"), + ForceApply: ctx.Bool("force"), + OutputDir: ctx.String("output-dir"), }) }, }, { - Name: "list", + Name: "list", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "cwd", + Usage: "current working directory to list scaffolds for", + Value: ".", + }, + }, Aliases: []string{"ls"}, Usage: "list available scaffolds", - Action: ctrl.List, + Action: func(ctx *cli.Context) error { + return ctrl.List(commands.FlagsList{ + OutputDir: ctx.String("cwd"), + }) + }, }, { Name: "update", diff --git a/tests/nested-snapshot.test.sh b/tests/nested-snapshot.test.sh index da88997..d22ed19 100755 --- a/tests/nested-snapshot.test.sh +++ b/tests/nested-snapshot.test.sh @@ -8,8 +8,8 @@ source tests/assert.sh # Your script continues as before... output=$($1 --log-level="error" \ - --output-dir=":memory:" \ new \ + --output-dir=":memory:" \ --preset="default" \ --no-prompt \ --snapshot="stdout" \ diff --git a/tests/runner.sh b/tests/runner.sh index 41d64b7..ec84f17 100755 --- a/tests/runner.sh +++ b/tests/runner.sh @@ -1,12 +1,13 @@ #!/bin/bash export SCAFFOLD_NO_CLOBBER="true" export SCAFFOLD_OUT="gen" +export SCAFFOLD_CACHE="./scaffold/.cache" export SCAFFOLD_DIR=".scaffold,.examples" checkmark="✓" crossmark="✗" -# build main.go into random temp path +# build main.go into temp path go build -o /tmp/scaffold-test ./main.go echo "Running Script Tests"