gotty/utils/flags.go
kernel 2424e48e17 Imported the existing codebase and refactored it to work with the new build system.
Adjusted dependencies to use our own repository mirrors.
Modified the Makefile for proper build output and target directory.
2025-07-31 19:44:16 +03:00

124 lines
2.5 KiB
Go

package utils
import (
"io/ioutil"
"log"
"os"
"reflect"
"strings"
"github.com/fatih/structs"
"github.com/urfave/cli"
"github.com/yudai/hcl"
"github.com/kernel-punk/gotty/pkg/homedir"
)
func GenerateFlags(options ...interface{}) (flags []cli.Flag, mappings map[string]string, err error) {
mappings = make(map[string]string)
for _, struct_ := range options {
o := structs.New(struct_)
for _, field := range o.Fields() {
flagName := field.Tag("flagName")
if flagName == "" {
continue
}
envName := "GOTTY_" + strings.ToUpper(strings.Join(strings.Split(flagName, "-"), "_"))
mappings[flagName] = field.Name()
flagShortName := field.Tag("flagSName")
if flagShortName != "" {
flagName += ", " + flagShortName
}
flagDescription := field.Tag("flagDescribe")
switch field.Kind() {
case reflect.String:
flags = append(flags, cli.StringFlag{
Name: flagName,
Value: field.Value().(string),
Usage: flagDescription,
EnvVar: envName,
})
case reflect.Bool:
flags = append(flags, cli.BoolFlag{
Name: flagName,
Usage: flagDescription,
EnvVar: envName,
})
case reflect.Int:
flags = append(flags, cli.IntFlag{
Name: flagName,
Value: field.Value().(int),
Usage: flagDescription,
EnvVar: envName,
})
}
}
}
return
}
func ApplyFlags(
flags []cli.Flag,
mappingHint map[string]string,
c *cli.Context,
options ...interface{},
) {
objects := make([]*structs.Struct, len(options))
for i, struct_ := range options {
objects[i] = structs.New(struct_)
}
for flagName, fieldName := range mappingHint {
if !c.IsSet(flagName) {
continue
}
var field *structs.Field
var ok bool
for _, o := range objects {
field, ok = o.FieldOk(fieldName)
if ok {
break
}
}
if field == nil {
continue
}
var val interface{}
switch field.Kind() {
case reflect.String:
val = c.String(flagName)
case reflect.Bool:
val = c.Bool(flagName)
case reflect.Int:
val = c.Int(flagName)
}
field.Set(val)
}
}
func ApplyConfigFile(filePath string, options ...interface{}) error {
filePath = homedir.Expand(filePath)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return err
}
fileString := []byte{}
log.Printf("Loading config file at: %s", filePath)
fileString, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
for _, object := range options {
if err := hcl.Decode(object, string(fileString)); err != nil {
return err
}
}
return nil
}