diff --git a/README.md b/README.md index ad8233c..fa7e1f1 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,17 @@ $ jen do create ## Invoking actions -You can now call different project actions with `jen do ACTION`. This `hello-world` example includes actions `create`, `prompt`, `install` and `uninstall`. The last two are meant to register your project with your CI/CD pipeline and infra, but here they just call dummy bash scripts that simulate the real thing. For example: +You can now call different project actions with `jen do ACTION`, but first let's see what actions this `hello-world` example defines: + +```bash +$ jen list actions +create +install +prompt +uninstall +``` + +We have already discussed about `create` and `prompt`. Now, `install` and `uninstall` are meant to register/unregister your project with your CI/CD pipeline and infra, but here they just call dummy bash scripts that simulate the real thing. For example: ```bash $ jen do install @@ -395,13 +405,13 @@ To associate a template with an existing project that was not initially generate - Add `jen list scripts` to list available scripts (both shared and template-specific). - Add `jen list vars` to list project variables and their values (same as `jen export` but more human-readable). - Add `jen chk vars VAR1 VAR2 ...` to ensure that all given variables are set in environment (to document and make scripts more robust). -- Add `jen shell` to start a sub-shell with all project variables in environment (same as `jen exec $SHELL`). - Allow `do` step to define multiple actions to call. - Invoking `jen do` without specifying an action should prompt user to select it from available list of actions. - Add reusable modules (including both templates and scripts). - Add `set` step to set multiple variables. - Add `--dry-run` flag (automatically turns on `--verbose`?). - Add regex validation for `input` prompt. +- Add more example templates, for go, node... - Fix `choice` step to pre-select current value, if any. - Allow special `.tmpl` and `.notmpl` extensions to be placed before actual extension (ie: `file.tmpl.txt`), to allow file editor to recognize them better during template editing. - Allow to customize placeholders in spec file: diff --git a/src/cmd/do/do.go b/src/cmd/do/do.go index f5c9c24..61580a2 100644 --- a/src/cmd/do/do.go +++ b/src/cmd/do/do.go @@ -7,7 +7,7 @@ import ( "github.com/spf13/cobra" ) -// New creates the "jen do" cobra sub-command +// New creates a cobra command func New(options *internal.Options) *cobra.Command { return &cobra.Command{ Use: "do", diff --git a/src/cmd/exec/exec.go b/src/cmd/exec/exec.go index 2088ee8..ad7475a 100644 --- a/src/cmd/exec/exec.go +++ b/src/cmd/exec/exec.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" ) -// New creates the "jen exec" cobra sub-command +// New creates a cobra command func New(options *internal.Options) *cobra.Command { return &cobra.Command{ Use: "exec", diff --git a/src/cmd/internal/internal.go b/src/cmd/internal/internal.go index 006727c..eeed465 100644 --- a/src/cmd/internal/internal.go +++ b/src/cmd/internal/internal.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "sort" "strings" "github.com/Samasource/jen/src/internal/exec" @@ -173,6 +174,16 @@ func (c context) GetAction(name string) exec.Executable { return action } +// GetActionNames returns the names of all actions available in template. +func (c context) GetActionNames() []string { + names := make([]string, 0, len(c.spec.Actions)) + for name := range c.spec.Actions { + names = append(names, name) + } + sort.Strings(names) + return names +} + // GetProjectDir returns the current project's dir func (c context) GetProjectDir() string { return c.project.Dir diff --git a/src/cmd/list/actions/actions.go b/src/cmd/list/actions/actions.go new file mode 100644 index 0000000..69ff9c8 --- /dev/null +++ b/src/cmd/list/actions/actions.go @@ -0,0 +1,33 @@ +package actions + +import ( + "fmt" + + "github.com/Samasource/jen/src/cmd/internal" + "github.com/spf13/cobra" +) + +// New creates a cobra command +func New(options *internal.Options) *cobra.Command { + return &cobra.Command{ + Use: "actions", + Aliases: []string{"action"}, + Short: "Lists actions available in current template", + Args: cobra.NoArgs, + RunE: func(_ *cobra.Command, args []string) error { + return run(options, args) + }, + } +} + +func run(options *internal.Options, args []string) error { + execContext, err := options.NewContext() + if err != nil { + return err + } + + for _, action := range execContext.GetActionNames() { + fmt.Println(action) + } + return nil +} diff --git a/src/cmd/list/list.go b/src/cmd/list/list.go new file mode 100644 index 0000000..74244b5 --- /dev/null +++ b/src/cmd/list/list.go @@ -0,0 +1,33 @@ +package list + +import ( + "strings" + + "github.com/Samasource/jen/src/cmd/internal" + "github.com/Samasource/jen/src/cmd/list/actions" + "github.com/Samasource/jen/src/internal/shell" + "github.com/spf13/cobra" +) + +// New creates a cobra command +func New(options *internal.Options) *cobra.Command { + c := &cobra.Command{ + Use: "list", + Aliases: []string{"ls"}, + Short: "Lists available templates, actions, variables or scripts", + RunE: func(_ *cobra.Command, args []string) error { + return run(options, args) + }, + } + c.AddCommand(actions.New(options)) + return c +} + +func run(options *internal.Options, args []string) error { + execContext, err := options.NewContext() + if err != nil { + return err + } + + return shell.Execute(execContext.GetShellVars(), "", strings.Join(args, " ")) +} diff --git a/src/cmd/pull/pull.go b/src/cmd/pull/pull.go index 366df2d..a9d839c 100644 --- a/src/cmd/pull/pull.go +++ b/src/cmd/pull/pull.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -// New creates the "jen pull" cobra sub-command +// New creates a cobra command func New() *cobra.Command { return &cobra.Command{ Use: "pull", diff --git a/src/cmd/root.go b/src/cmd/root.go index 1e5033e..cdfd16d 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -4,6 +4,7 @@ import ( "github.com/Samasource/jen/src/cmd/do" "github.com/Samasource/jen/src/cmd/exec" "github.com/Samasource/jen/src/cmd/internal" + "github.com/Samasource/jen/src/cmd/list" "github.com/Samasource/jen/src/cmd/pull" "github.com/Samasource/jen/src/cmd/shell" "github.com/Samasource/jen/src/internal/logging" @@ -30,5 +31,6 @@ continues to support you throughout development in executing project-related com c.AddCommand(do.New(&options)) c.AddCommand(exec.New(&options)) c.AddCommand(shell.New(&options)) + c.AddCommand(list.New(&options)) return c } diff --git a/src/cmd/shell/shell.go b/src/cmd/shell/shell.go index 7a7876c..ebd34d6 100644 --- a/src/cmd/shell/shell.go +++ b/src/cmd/shell/shell.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -// New creates the "jen exec" cobra sub-command +// New creates a cobra command func New(options *internal.Options) *cobra.Command { return &cobra.Command{ Use: "shell", diff --git a/src/internal/exec/exec.go b/src/internal/exec/exec.go index 9e92655..a7ad89b 100644 --- a/src/internal/exec/exec.go +++ b/src/internal/exec/exec.go @@ -35,6 +35,9 @@ type Context interface { // found. GetAction(name string) Executable + // GetActionNames returns the names of all actions available in template. + GetActionNames() []string + // GetProjectDir returns the current project's dir GetProjectDir() string }