Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ func (app *appImpl) init() error {
return err
}
for _, actConf := range actions {
if err = actConf.EnsureLoaded(); err != nil {
return err
}

if launchrConfig != nil && len(launchrConfig.ActionsNaming) > 0 {
actID := actConf.ID
for _, an := range launchrConfig.ActionsNaming {
Expand Down Expand Up @@ -247,6 +251,10 @@ func (app *appImpl) exec() error {
actions := app.actionMngr.AllRef()
// Check the requested command to see what actions we must actually load.
if app.reqCmd != "" {
aliases := app.actionMngr.AllAliasRef()
if alias, ok := aliases[app.reqCmd]; ok {
app.reqCmd = alias
}
a, ok := actions[app.reqCmd]
if ok {
// Use only the requested action.
Expand Down
3 changes: 3 additions & 0 deletions docs/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Action configuration files are written in `yaml`, example declaration:
action:
title: Verb
description: Handles some logic
alias:
- "alias1"
- "alias2"
arguments:
- name: myArg1
title: Argument 1
Expand Down
3 changes: 3 additions & 0 deletions docs/actions.schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Basic action definition must have `image` and `command` to run the command in th
action:
title: Action name
description: Long description
alias:
- "alias1"
- "alias2"
image: alpine:latest
command:
- ls
Expand Down
3 changes: 2 additions & 1 deletion pkg/action/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func CobraImpl(a *Action, streams cli.Streams) (*cobra.Command, error) {
Use: use,
// Using custom args validation in ValidateInput.
// @todo: maybe we need a long template for arguments description
Short: getDesc(actConf.Title, actConf.Description),
Short: getDesc(actConf.Title, actConf.Description),
Aliases: actConf.Aliases,
RunE: func(cmd *cobra.Command, args []string) error {
// Pass to the run environment its flags.
if env, ok := a.env.(RunEnvironmentFlags); ok {
Expand Down
34 changes: 24 additions & 10 deletions pkg/action/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type Manager interface {
// Use it only if you need to read-only actions without allocations. It may be unsafe to read/write the map.
// If you need to run actions, use Get or All, it will provide configured for run Action.
AllRef() map[string]*Action
// AllAliasRef returns map of all aliased actions
AllAliasRef() map[string]string
// Get returns a copy of an action from the manager with default decorators.
Get(id string) (*Action, bool)
// GetRef returns an original action value from the storage.
Expand Down Expand Up @@ -49,21 +51,23 @@ type Manager interface {
type DecorateWithFn = func(m Manager, a *Action)

type actionManagerMap struct {
actionStore map[string]*Action
runStore map[string]RunInfo // @todo consider persistent storage
mx sync.Mutex
mxRun sync.Mutex
dwFns []DecorateWithFn
processors map[string]ValueProcessor
actionStore map[string]*Action
actionAliases map[string]string
runStore map[string]RunInfo // @todo consider persistent storage
mx sync.Mutex
mxRun sync.Mutex
dwFns []DecorateWithFn
processors map[string]ValueProcessor
}

// NewManager constructs a new action manager.
func NewManager(withFns ...DecorateWithFn) Manager {
return &actionManagerMap{
actionStore: make(map[string]*Action),
runStore: make(map[string]RunInfo),
dwFns: withFns,
processors: make(map[string]ValueProcessor),
actionStore: make(map[string]*Action),
actionAliases: make(map[string]string),
runStore: make(map[string]RunInfo),
dwFns: withFns,
processors: make(map[string]ValueProcessor),
}
}

Expand All @@ -75,6 +79,10 @@ func (m *actionManagerMap) Add(a *Action) {
m.mx.Lock()
defer m.mx.Unlock()
m.actionStore[a.ID] = a

for _, alias := range a.ActionDef().Aliases {
m.actionAliases[alias] = a.ID
}
}

func (m *actionManagerMap) AllRef() map[string]*Action {
Expand All @@ -83,6 +91,12 @@ func (m *actionManagerMap) AllRef() map[string]*Action {
return copyMap(m.actionStore)
}

func (m *actionManagerMap) AllAliasRef() map[string]string {
m.mx.Lock()
defer m.mx.Unlock()
return copyMap(m.actionAliases)
}

func (m *actionManagerMap) All() map[string]*Action {
ret := m.AllRef()
for k, v := range ret {
Expand Down
1 change: 1 addition & 0 deletions pkg/action/yaml.def.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func validateV1(_ *Definition) error {
type DefAction struct {
Title string `yaml:"title"`
Description string `yaml:"description"`
Aliases []string `yaml:"alias"`
Arguments ArgumentsList `yaml:"arguments"`
Options OptionsList `yaml:"options"`
Command StrSliceOrStr `yaml:"command"`
Expand Down