Skip to content

Commit 07b5813

Browse files
committed
feat(golang-rewrite): create settings and config structs for loading config
* rename commands package to cmd * add go-ini as a dependency * write code to parse asdfrc file into Settings struct * add go-envconfig as a dependency * add go-homedir as a dependency * implement first version of LoadConfig function to load environment variables into Config struct
1 parent f0cb04c commit 07b5813

File tree

9 files changed

+204
-4
lines changed

9 files changed

+204
-4
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ jobs:
1313
outputs:
1414
documentation: ${{ steps.filter.outputs.documentation }}
1515
cli: ${{ steps.filter.outputs.cli }}
16+
go: ${{ steps.filter.outputs.go }}
1617
steps:
1718
- uses: actions/checkout@v4
1819
with:

commands/commands.go renamed to cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package commands
1+
package cmd
22

33
import (
44
"fmt"

config.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"strings"
6+
7+
"github.com/mitchellh/go-homedir"
8+
"github.com/sethvargo/go-envconfig"
9+
"gopkg.in/ini.v1"
10+
)
11+
12+
// Not sure how best to represent this enum type
13+
//type PluginRepositoryLastCheckDuration struct {
14+
// Never bool
15+
// Every int
16+
//}
17+
18+
type Settings struct {
19+
LegacyVersionFile bool
20+
// I don't think this setting should be supported in the Golang implementation
21+
//UseReleaseCandidates bool
22+
AlwaysKeepDownload bool
23+
PluginRepositoryLastCheckDuration string
24+
DisablePluginShortNameRepository bool
25+
}
26+
27+
type Config struct {
28+
Home string
29+
ConfigFile string `env:"ASDF_CONFIG_FILE"`
30+
DefaultToolVersionsFilename string `env:"ASDF_DEFAULT_TOOL_VERSIONS_FILENAME"`
31+
// Unclear if this value will be needed with the golang implementation.
32+
//AsdfDir string
33+
DataDir string `env:"ASDF_DATA_DIR"`
34+
ForcePrepend bool `env:"ASDF_FORCE_PREPEND"`
35+
}
36+
37+
func LoadConfig() (Config, error) {
38+
config, err := loadConfigEnv()
39+
40+
if err != nil {
41+
return config, err
42+
}
43+
44+
homeDir, err := homedir.Dir()
45+
46+
if err != nil {
47+
return config, err
48+
}
49+
50+
config.Home = homeDir
51+
52+
return config, nil
53+
}
54+
55+
func loadConfigEnv() (Config, error) {
56+
context := context.Background()
57+
config := Config{}
58+
59+
err := envconfig.Process(context, &config)
60+
61+
return config, err
62+
}
63+
64+
func LoadSettings(asdfrcPath string) (Settings, error) {
65+
// asdfrc is effectively formatted as ini
66+
config, err := ini.Load(asdfrcPath)
67+
68+
if err != nil {
69+
return Settings{}, err
70+
}
71+
72+
mainConf := config.Section("")
73+
checkDuration := stringToCheckDuration(mainConf.Key("plugin_repository_last_check_duration").String(), "60")
74+
75+
return Settings{
76+
LegacyVersionFile: YesNoToBool(mainConf, "legacy_version_file", false),
77+
AlwaysKeepDownload: YesNoToBool(mainConf, "use_release_candidates", false),
78+
PluginRepositoryLastCheckDuration: checkDuration,
79+
DisablePluginShortNameRepository: YesNoToBool(mainConf, "disable_plugin_short_name_repository", false),
80+
}, nil
81+
}
82+
83+
func YesNoToBool(section *ini.Section, key string, defaultValue bool) bool {
84+
yesOrNo := section.Key(key).String()
85+
lcYesOrNo := strings.ToLower(yesOrNo)
86+
if lcYesOrNo == "yes" {
87+
return true
88+
}
89+
if lcYesOrNo == "no" {
90+
return false
91+
}
92+
93+
return defaultValue
94+
}
95+
96+
// Eventually this should return a custom type but I need to figure out how to
97+
// represent the (never string, duration int) type. For now it just returns a
98+
// string.
99+
func stringToCheckDuration(checkDuration string, defaultValue string) string {
100+
if checkDuration != "" {
101+
return checkDuration
102+
}
103+
104+
return defaultValue
105+
}

config_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestLoadConfig(t *testing.T) {
8+
config, err := LoadConfig()
9+
10+
assert(t, err == nil, "Returned error when building config")
11+
12+
assert(t, config.Home != "", "Expected Home to be set")
13+
}
14+
15+
func TestLoadConfigEnv(t *testing.T) {
16+
config, err := loadConfigEnv()
17+
18+
assert(t, err == nil, "Returned error when loading env for config")
19+
20+
assert(t, config.Home == "", "Shouldn't set Home property when loading config")
21+
}
22+
23+
func TestLoadSettings(t *testing.T) {
24+
t.Run("When given invalid path returns error", func(t *testing.T) {
25+
_, err := LoadSettings("./foobar")
26+
27+
if err == nil {
28+
t.Fatal("Didn't get an error")
29+
}
30+
})
31+
32+
t.Run("When given path to populated asdfrc returns populated settings struct", func(t *testing.T) {
33+
settings, err := LoadSettings("testdata/asdfrc")
34+
35+
refuteError(t, err)
36+
37+
assert(t, settings.LegacyVersionFile == true, "LegacyVersionFile field has wrong value")
38+
assert(t, settings.AlwaysKeepDownload == true, "AlwaysKeepDownload field has wrong value")
39+
assert(t, settings.PluginRepositoryLastCheckDuration == "never", "PluginRepositoryLastCheckDuration field has wrong value")
40+
assert(t, settings.DisablePluginShortNameRepository == true, "DisablePluginShortNameRepository field has wrong value")
41+
})
42+
43+
t.Run("When given path to empty file returns settings struct with defaults", func(t *testing.T) {
44+
settings, err := LoadSettings("testdata/empty-asdfrc")
45+
46+
refuteError(t, err)
47+
48+
assert(t, settings.LegacyVersionFile == false, "LegacyVersionFile field has wrong value")
49+
assert(t, settings.AlwaysKeepDownload == false, "AlwaysKeepDownload field has wrong value")
50+
assert(t, settings.PluginRepositoryLastCheckDuration == "60", "PluginRepositoryLastCheckDuration field has wrong value")
51+
assert(t, settings.DisablePluginShortNameRepository == false, "DisablePluginShortNameRepository field has wrong value")
52+
})
53+
}
54+
55+
func assert(t *testing.T, expr bool, message string) {
56+
if !expr {
57+
t.Error(message)
58+
}
59+
}
60+
61+
func refuteError(t *testing.T, err error) {
62+
if err != nil {
63+
t.Fatal("Returned unexpected error", err)
64+
}
65+
}

go.mod

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ module asdf
33
go 1.21.5
44

55
require (
6-
github.com/inconshreveable/mousetrap v1.1.0 // indirect
6+
github.com/mitchellh/go-homedir v1.1.0
7+
github.com/sethvargo/go-envconfig v1.0.0
78
github.com/spf13/cobra v1.8.0
9+
gopkg.in/ini.v1 v1.67.0
10+
)
11+
12+
require (
13+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
814
github.com/spf13/pflag v1.0.5 // indirect
15+
github.com/stretchr/testify v1.8.4 // indirect
916
)

go.sum

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
2+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
5+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
26
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
37
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
8+
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
9+
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
10+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
11+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
412
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
13+
github.com/sethvargo/go-envconfig v1.0.0 h1:1C66wzy4QrROf5ew4KdVw942CQDa55qmlYmw9FZxZdU=
14+
github.com/sethvargo/go-envconfig v1.0.0/go.mod h1:Lzc75ghUn5ucmcRGIdGQ33DKJrcjk4kihFYgSTBmjIc=
515
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
616
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
717
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
818
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
19+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
20+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
921
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
22+
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
23+
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
24+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
1025
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package main
22

33
import (
4-
"asdf/commands"
4+
"asdf/cmd"
55
)
66

77
// Placeholder for the real code
88
func main() {
9-
commands.Execute()
9+
cmd.Execute()
1010
}

testdata/asdfrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# This is a test asdfrc file containing all possible values. Each field to set
2+
# to a value that is different than the default.
3+
legacy_version_file = yes
4+
use_release_candidates = yes
5+
always_keep_download = yes
6+
plugin_repository_last_check_duration = never
7+
disable_plugin_short_name_repository = yes

testdata/empty-asdfrc

Whitespace-only changes.

0 commit comments

Comments
 (0)