diff --git a/cli/deploy.go b/cli/deploy.go index 5d2be919..e96292fc 100644 --- a/cli/deploy.go +++ b/cli/deploy.go @@ -68,15 +68,15 @@ func (obj *DeployArgs) Run(ctx context.Context, data *cliUtil.Data) (bool, error var name string var args interface{} if cmd := obj.DeployEmpty; cmd != nil { - name = emptyGAPI.Name + name = cliUtil.LookupSubcommand(obj, cmd) // "empty" args = cmd } if cmd := obj.DeployLang; cmd != nil { - name = langGAPI.Name + name = cliUtil.LookupSubcommand(obj, cmd) // "lang" args = cmd } if cmd := obj.DeployYaml; cmd != nil { - name = yamlGAPI.Name + name = cliUtil.LookupSubcommand(obj, cmd) // "yaml" args = cmd } diff --git a/cli/run.go b/cli/run.go index 1d0ee16b..4ae55cd4 100644 --- a/cli/run.go +++ b/cli/run.go @@ -109,15 +109,15 @@ func (obj *RunArgs) Run(ctx context.Context, data *cliUtil.Data) (bool, error) { var name string var args interface{} if cmd := obj.RunEmpty; cmd != nil { - name = emptyGAPI.Name + name = cliUtil.LookupSubcommand(obj, cmd) // "empty" args = cmd } if cmd := obj.RunLang; cmd != nil { - name = langGAPI.Name + name = cliUtil.LookupSubcommand(obj, cmd) // "lang" args = cmd } if cmd := obj.RunYaml; cmd != nil { - name = yamlGAPI.Name + name = cliUtil.LookupSubcommand(obj, cmd) // "yaml" args = cmd } diff --git a/cli/util/args.go b/cli/util/args.go new file mode 100644 index 00000000..ff2cce0c --- /dev/null +++ b/cli/util/args.go @@ -0,0 +1,58 @@ +// Mgmt +// Copyright (C) 2013-2024+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package util + +import ( + "reflect" + "strings" +) + +// LookupSubcommand returns the name of the subcommand in the obj, of a struct. +// This is useful for determining the name of the subcommand that was activated. +// It returns an empty string if a specific name was not found. +func LookupSubcommand(obj interface{}, st interface{}) string { + val := reflect.ValueOf(obj) + if val.Kind() == reflect.Ptr { // max one de-referencing + val = val.Elem() + } + + v := reflect.ValueOf(st) // value of the struct + typ := val.Type() + for i := 0; i < typ.NumField(); i++ { + f := val.Field(i) // value of the field + if f.Interface() != v.Interface() { + continue + } + + field := typ.Field(i) + alias, ok := field.Tag.Lookup("arg") + if !ok { + continue + } + + // XXX: `arg` needs a split by comma first or fancier parsing + prefix := "subcommand" + split := strings.Split(alias, ":") + if len(split) != 2 || split[0] != prefix { + continue + } + + return split[1] // found + } + return "" // not found +}