Skip to content

Commit

Permalink
Handle config precedence properly (#64)
Browse files Browse the repository at this point in the history
* Implement override precedence between config files

* Fix precedence between config files and environment variables

* Document configuration precedence

* Fix logic of readConfigFile

* Fix merge logic

* Update go.mod

* Update comment

* Simplify main

* Update comments
  • Loading branch information
apstndb committed Jun 9, 2020
1 parent f9afb1d commit cfc5125
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 25 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ instance = myinstance
prompt = "[\\p:\\i:\\d]\\t> "
```

## Configuration Precedence

1. Command line flags(highest)
2. Environment variables
3. `.spanner_cli.cnf` in current directory
4. `.spanner_cli.cnf` in home directory(lowest)

## How to develop

Run unit tests.
Expand Down
43 changes: 18 additions & 25 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ type spannerOptions struct {

func main() {
var gopts globalOptions
parser := flags.NewParser(&gopts, flags.Default)

// check config file at first
if err := readConfigFile(parser); err != nil {
// process config files at first
if err := readConfigFile(flags.NewParser(&gopts, flags.Default)); err != nil {
exitf("Invalid config file format\n")
}

// then, parse command line options
if _, err := parser.Parse(); err != nil {
// then, process environment variables and command line options
// use another parser to process environment variable
if _, err := flags.NewParser(&gopts, flags.Default).Parse(); err != nil {
exitf("Invalid options\n")
}

Expand Down Expand Up @@ -117,30 +116,24 @@ func exitf(format string, a ...interface{}) {
const cnfFileName = ".spanner_cli.cnf"

func readConfigFile(parser *flags.Parser) error {
var cnfFile string
var cnfFiles []string
if currentUser, err := user.Current(); err == nil {
cnfFiles = append(cnfFiles, filepath.Join(currentUser.HomeDir, cnfFileName))
}

cwd, _ := os.Getwd() // ignore err
if _, err := os.Stat(filepath.Join(cwd, cnfFileName)); err == nil {
cnfFile = filepath.Join(cwd, cnfFileName)
} else {
currentUser, err := user.Current()
if err != nil {
// ignore error
return nil
}

// TODO: customize config path
cnfFile = filepath.Join(currentUser.HomeDir, cnfFileName)
cwdCnfFile := filepath.Join(cwd, cnfFileName)
cnfFiles = append(cnfFiles, cwdCnfFile)

// check config file existence
iniParser := flags.NewIniParser(parser)
for _, cnfFile := range cnfFiles {
// skip if missing
if _, err := os.Stat(cnfFile); err != nil {
return nil
continue
}
if err := iniParser.ParseFile(cnfFile); err != nil {
return err
}
}

iniParser := flags.NewIniParser(parser)
if err := iniParser.ParseFile(cnfFile); err != nil {
return err
}

return nil
Expand Down

0 comments on commit cfc5125

Please sign in to comment.