github.com/git-ogawa/go-dbyml@v1.2.1/dbyml/config.go (about)

     1  package dbyml
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"regexp"
     8  
     9  	"gopkg.in/yaml.v2"
    10  )
    11  
    12  // Configuration defines the hierarchy of the settings in config file.
    13  type Configuration struct {
    14  	ImageInfo    ImageInfo    `yaml:"image"`
    15  	BuildInfo    BuildInfo    `yaml:"build"`
    16  	RegistryInfo RegistryInfo `yaml:"registry"`
    17  	BuildkitInfo BuildkitInfo `yaml:"buildkit"`
    18  }
    19  
    20  // NewConfiguration makes Configuration struct with default values.
    21  func NewConfiguration() *Configuration {
    22  	config := new(Configuration)
    23  	config.ImageInfo = *NewImageInfo()
    24  	config.BuildInfo = *NewBuildInfo()
    25  	config.RegistryInfo = *NewRegistryInfo()
    26  	config.BuildkitInfo = *NewBuildkitInfo()
    27  	return config
    28  }
    29  
    30  // ShowConfig shows the current Configuration to stdout.
    31  func (config *Configuration) ShowConfig() {
    32  	PrintCenter("Build info", 30, "-")
    33  	config.ImageInfo.ShowProperties()
    34  	fmt.Println()
    35  	PrintCenter("Registry info", 30, "-")
    36  	config.RegistryInfo.ShowProperties()
    37  }
    38  
    39  // BuildInfo defines some options related to setting or progress on image build.
    40  type BuildInfo struct {
    41  	Target  string `yaml:"target"`
    42  	NoCache bool   `yaml:"no_cache"`
    43  	Verbose bool   `yaml:"verbose"`
    44  }
    45  
    46  // NewBuildInfo makes Configuration struct with default values.
    47  func NewBuildInfo() *BuildInfo {
    48  	build := new(BuildInfo)
    49  	build.Verbose = true
    50  	build.NoCache = false
    51  	return build
    52  }
    53  
    54  // LoadConfig loads the configuration from the path.
    55  func LoadConfig(path string) (conf *Configuration) {
    56  	conf = NewConfiguration()
    57  	data, err := ioutil.ReadFile(path)
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  	rep, err := parseEnv(string(data))
    62  	if err != nil {
    63  		panic(err)
    64  	}
    65  	if err = yaml.Unmarshal([]byte(rep), &conf); err != nil {
    66  		panic(err)
    67  	}
    68  	conf.ImageInfo.SetProperties()
    69  	return conf
    70  }
    71  
    72  // ConfigExists checks if the input config exists.
    73  func ConfigExists(path string) bool {
    74  	_, err := os.Stat(path)
    75  	return err == nil
    76  }
    77  
    78  func parseEnv(data string) (string, error) {
    79  	matches := regexp.MustCompile(`\${.*}`).FindAllString(data, -1)
    80  	res, err := getEnvs(matches)
    81  	if err != nil {
    82  		return "", err
    83  	}
    84  	for k, v := range res {
    85  		data = regexp.MustCompile(fmt.Sprintf(`\%v`, k)).ReplaceAllString(data, v)
    86  	}
    87  	return data, nil
    88  }
    89  
    90  // getEnvs replaces the specified variables in environment variables.
    91  // If the environment variable is not defined and the default value is not set, returns error.
    92  func getEnvs(envs []string) (map[string]string, error) {
    93  	var target, def string
    94  	res := map[string]string{}
    95  	for _, env := range envs {
    96  		e := regexp.MustCompile("[${}]").ReplaceAllString(env, "")
    97  
    98  		// Split env and its default value.
    99  		arr := regexp.MustCompile("(:-)").Split(e, -1)
   100  		if len(arr) == 1 {
   101  			target = arr[0]
   102  			def = ""
   103  		} else if len(arr) == 2 {
   104  			target = arr[0]
   105  			def = regexp.MustCompile("[${}]").ReplaceAllString(arr[1], "")
   106  		}
   107  
   108  		// Get the env value.
   109  		rep := os.Getenv(target)
   110  		if rep == "" {
   111  			if def == "" {
   112  				return res, fmt.Errorf(fmt.Sprintf("ENV %v not defined.", env))
   113  			}
   114  			rep = def
   115  		}
   116  		res[env] = rep
   117  	}
   118  	return res, nil
   119  }