github.com/wfusion/gofusion@v1.1.14/config/loader.go (about)

     1  package config
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"path/filepath"
     7  	"syscall"
     8  
     9  	"github.com/pkg/errors"
    10  	"gopkg.in/yaml.v3"
    11  
    12  	"github.com/wfusion/gofusion/common/env"
    13  	"github.com/wfusion/gofusion/common/utils"
    14  	"github.com/wfusion/gofusion/internal/configor"
    15  )
    16  
    17  type loader struct {
    18  	files []string
    19  }
    20  
    21  // NewDefaultLoader front files overwrite the backs
    22  func NewDefaultLoader(files ...string) *loader {
    23  	return &loader{
    24  		files: files,
    25  	}
    26  }
    27  
    28  // Unmarshal support required and default tag setting
    29  // be carefully we can only assign default value when value is a pointer in map or slice
    30  func (l *loader) Unmarshal(out any) (err error) {
    31  	return configor.New(&configor.Config{
    32  		Environment:        env.GetEnv(),
    33  		ENVPrefix:          "",
    34  		Debug:              false,
    35  		Verbose:            false,
    36  		Silent:             true,
    37  		AutoReload:         true,
    38  		AutoReloadInterval: 0,
    39  		AutoReloadCallback: func(config any) {
    40  			log.Printf("%v [Gofusion] Config auto reload config successfully => \n%s",
    41  				syscall.Getpid(), utils.Must(yaml.Marshal(config)))
    42  		},
    43  		ErrorOnUnmatchedKeys: false,
    44  		FS:                   nil,
    45  	}).Load(out, l.files...)
    46  }
    47  
    48  var profile string
    49  
    50  type loadConfigFunc func(out any, opts ...utils.OptionExtender)
    51  
    52  func loadConfig(out any, opts ...utils.OptionExtender) {
    53  	parseFlags()
    54  
    55  	opt := utils.ApplyOptions[initOption](opts...)
    56  
    57  	files := make([]string, 0, 2)
    58  	switch {
    59  	case len(customConfigPath) > 0:
    60  		for _, p := range customConfigPath {
    61  			files = append(files, filepath.Clean(p))
    62  		}
    63  	case len(opt.filenames) > 0:
    64  		files = append(files, opt.filenames...)
    65  	default:
    66  		defaultPathPrefix := filepath.Join(env.WorkDir, "configs", "app.")
    67  		defaultLocal1PathPrefix := filepath.Join(env.WorkDir, "configs", "app.local.")
    68  		defaultLocal2PathPrefix := filepath.Join(env.WorkDir, "configs", "app_local.")
    69  		defaultLocal3PathPrefix := filepath.Join(env.WorkDir, "configs", "app-local.")
    70  		extensions := []string{"yaml", "yml", "json", "toml"}
    71  		for _, ext := range extensions {
    72  			localFilename := defaultLocal1PathPrefix + ext
    73  			if _, err := os.Stat(localFilename); err == nil {
    74  				files = append(files, localFilename)
    75  				continue
    76  			}
    77  			localFilename = defaultLocal2PathPrefix + ext
    78  			if _, err := os.Stat(localFilename); err == nil {
    79  				files = append(files, localFilename)
    80  				continue
    81  			}
    82  			localFilename = defaultLocal3PathPrefix + ext
    83  			if _, err := os.Stat(localFilename); err == nil {
    84  				files = append(files, localFilename)
    85  				continue
    86  			}
    87  		}
    88  		for _, ext := range extensions {
    89  			defaultFilename := defaultPathPrefix + ext
    90  			files = append(files, defaultFilename)
    91  		}
    92  	}
    93  
    94  	if profile != "" {
    95  		if err := configor.New(&configor.Config{Environment: profile}).Load(out, files...); err != nil {
    96  			panic(errors.Errorf("parse config file of config env %s error: %v", profile, err))
    97  		}
    98  		return
    99  	}
   100  
   101  	if err := NewDefaultLoader(files...).Unmarshal(out); err != nil {
   102  		panic(errors.Errorf("parse config file error! %s", err))
   103  	}
   104  }