• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

demdxx / goconfig / 11571767257

29 Oct 2024 10:00AM UTC coverage: 73.171% (-3.1%) from 76.316%
11571767257

push

github

web-flow
Merge pull request #3 from demdxx/optional-file

optional file

7 of 12 new or added lines in 1 file covered. (58.33%)

1 existing line in 1 file now uncovered.

60 of 82 relevant lines covered (73.17%)

1.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.17
/loader.go
1
package goconfig
2

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "io"
7
        "os"
8
        "path/filepath"
9
        "strings"
10

11
        env "github.com/caarlos0/env/v6"
12
        "github.com/gravitational/configure"
13
        "github.com/hashicorp/hcl"
14
        defaults "github.com/mcuadros/go-defaults"
15
)
16

17
type configFilepath interface {
18
        ConfigFilepath() string
19
}
20

21
type config any
22

23
type options struct {
24
        defaults bool
25
        args     bool
26
        file     bool
27
        filePath string
28
        env      bool
29
}
30

31
// WithDefaults set defaults for config
32
func WithDefaults() func(*options) {
×
33
        return func(o *options) {
×
34
                o.defaults = true
×
35
        }
×
36

37
}
38

39
// WithArgs parse command line arguments
40
func WithArgs() func(*options) {
×
41
        return func(o *options) {
×
42
                o.args = true
×
43
        }
×
44
}
45

46
// WithFile parse config from file
NEW
47
func WithFile(path string) func(*options) {
×
48
        return func(o *options) {
×
49
                o.file = true
×
NEW
50
                o.filePath = path
×
UNCOV
51
        }
×
52
}
53

54
// WithEnv parse environment variables
55
func WithEnv() func(*options) {
2✔
56
        return func(o *options) {
4✔
57
                o.env = true
2✔
58
        }
2✔
59
}
60

61
// Load data from file
62
func Load(cfg config, opts ...func(*options)) (err error) {
2✔
63
        o := &options{}
2✔
64
        if opts == nil {
4✔
65
                o.env = true
2✔
66
                o.args = true
2✔
67
                o.file = true
2✔
68
                o.defaults = true
2✔
69
        } else {
4✔
70
                for _, opt := range opts {
4✔
71
                        opt(o)
2✔
72
                }
2✔
73
        }
74

75
        // Set defaults for config
76
        if o.defaults {
4✔
77
                defaults.SetDefaults(cfg)
2✔
78
        }
2✔
79

80
        // parse command line arguments
81
        if o.args {
4✔
82
                if len(os.Args) > 1 {
4✔
83
                        if err = configure.ParseCommandLine(cfg, os.Args[1:]); err != nil {
4✔
84
                                return err
2✔
85
                        }
2✔
86
                }
87
        }
88

89
        // parse config from file
90
        if o.file {
4✔
91
                if o.filePath != "" {
2✔
NEW
92
                        if err = loadFile(cfg, o.filePath); err != nil {
×
NEW
93
                                return err
×
NEW
94
                        }
×
95
                } else {
2✔
96
                        if configFile, _ := cfg.(configFilepath); configFile != nil {
4✔
97
                                if filepath := configFile.ConfigFilepath(); len(filepath) > 0 {
4✔
98
                                        if err = loadFile(cfg, filepath); err != nil {
4✔
99
                                                return err
2✔
100
                                        }
2✔
101
                                }
102
                        }
103
                }
104
        }
105

106
        // parse environment variables
107
        if o.env {
4✔
108
                if err = env.Parse(cfg); err != nil {
4✔
109
                        return err
2✔
110
                }
2✔
111
        }
112

113
        return err
2✔
114
}
115

116
// loadFile config from file path
117
func loadFile(cfg config, file string) error {
2✔
118
        f, err := os.Open(file)
2✔
119
        if err != nil {
4✔
120
                return err
2✔
121
        }
2✔
122
        defer f.Close()
2✔
123

2✔
124
        data, err := io.ReadAll(f)
2✔
125
        if err != nil {
2✔
126
                return err
×
127
        }
×
128

129
        ext := strings.ToLower(filepath.Ext(file))
2✔
130
        switch ext {
2✔
131
        case ".yml", ".yaml":
2✔
132
                return configure.ParseYAML(data, cfg)
2✔
133
        case ".json":
2✔
134
                return json.Unmarshal(data, cfg)
2✔
135
        case ".hcl":
2✔
136
                var root any
2✔
137
                // For some specific HCL module not always work as expected
2✔
138
                // so this is a hack to fix it
2✔
139
                if err = hcl.Unmarshal(data, &root); err != nil {
2✔
140
                        return err
×
141
                }
×
142
                if data, err = json.Marshal(root); err != nil {
2✔
143
                        return err
×
144
                }
×
145
                // Skip the error because of HCL converts structures into arrays of structs
146
                _ = json.Unmarshal(data, cfg)
2✔
147
                return hcl.Unmarshal(data, cfg)
2✔
148
        }
149
        return fmt.Errorf("unsupported config ext: %s", ext)
2✔
150
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc