github.com/clusterize-io/tusk@v0.6.3-0.20211001020217-cfe8a8cd0d4a/runner/metadata.go (about)

     1  package runner
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/clusterize-io/tusk/ui"
    10  	yaml "gopkg.in/yaml.v2"
    11  )
    12  
    13  // NewMetadata creates a metadata struct with a default logger.
    14  func NewMetadata() *Metadata {
    15  	return &Metadata{
    16  		Logger: ui.New(),
    17  	}
    18  }
    19  
    20  // Metadata contains global configuration settings.
    21  //
    22  // Metadata should be instantiated using NewMetadata.
    23  type Metadata struct {
    24  	CfgText             []byte
    25  	Interpreter         []string
    26  	Directory           string
    27  	InstallCompletion   string
    28  	UninstallCompletion string
    29  	PrintHelp           bool
    30  	PrintVersion        bool
    31  	Logger              *ui.Logger
    32  }
    33  
    34  // Set sets the metadata based on options.
    35  func (m *Metadata) Set(o OptGetter) error {
    36  	fullPath := o.String("file")
    37  
    38  	if fullPath == "" {
    39  		var err error
    40  		fullPath, err = searchForFile()
    41  		if err != nil {
    42  			return err
    43  		}
    44  	}
    45  
    46  	if fullPath != "" {
    47  		var err error
    48  		m.CfgText, err = ioutil.ReadFile(fullPath)
    49  		if err != nil {
    50  			return fmt.Errorf("reading config file %q: %w", fullPath, err)
    51  		}
    52  	}
    53  
    54  	interpreter, err := getInterpreter(m.CfgText)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	m.Interpreter = interpreter
    60  	m.InstallCompletion = o.String("install-completion")
    61  	m.UninstallCompletion = o.String("uninstall-completion")
    62  	m.Directory = filepath.Dir(fullPath)
    63  	m.PrintHelp = o.Bool("help")
    64  	m.PrintVersion = o.Bool("version")
    65  	if m.Logger == nil {
    66  		m.Logger = ui.New()
    67  	}
    68  	m.Logger.Verbosity = getVerbosity(o)
    69  	return nil
    70  }
    71  
    72  // getInterpreter attempts to determine the interpreter from reading the env
    73  // var and the config file, in that order. If no interpreter is specified, "sh"
    74  // is used.
    75  func getInterpreter(cfgText []byte) ([]string, error) {
    76  	var cfg struct {
    77  		Interpreter string `yaml:"interpreter"`
    78  	}
    79  
    80  	if err := yaml.Unmarshal(cfgText, &cfg); err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	if cfg.Interpreter == "" {
    85  		return nil, nil
    86  	}
    87  
    88  	return strings.Fields(cfg.Interpreter), nil
    89  }
    90  
    91  // OptGetter pulls various options based on a name.
    92  // These options will generally come from the command line.
    93  type OptGetter interface {
    94  	Bool(string) bool
    95  	String(string) string
    96  }
    97  
    98  func getVerbosity(c OptGetter) ui.VerbosityLevel {
    99  	switch {
   100  	case c.Bool("silent"):
   101  		return ui.VerbosityLevelSilent
   102  	case c.Bool("quiet"):
   103  		return ui.VerbosityLevelQuiet
   104  	case c.Bool("verbose"):
   105  		return ui.VerbosityLevelVerbose
   106  	default:
   107  		return ui.VerbosityLevelNormal
   108  	}
   109  }