Skip to content

Commit 569645a

Browse files
committed
Support hosts.yml existing while config.yml does not
After a person copies `hosts.yml` to a headless system, they will still be forced to go through re-authentication flow unless they copy or initialize a `config.yml` as well. This fixes respecting authentication info from `hosts.yml` even if `config.yml` is missing.
1 parent 15a7ab6 commit 569645a

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

internal/config/config_file.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ func migrateConfig(filename string) error {
138138
func ParseConfig(filename string) (Config, error) {
139139
_, root, err := parseConfigFile(filename)
140140
if err != nil {
141-
return nil, err
141+
if os.IsNotExist(err) {
142+
root = NewBlankRoot()
143+
} else {
144+
return nil, err
145+
}
142146
}
143147

144148
if isLegacy(root) {

internal/config/config_file_test.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,36 @@ github.com:
110110
}
111111

112112
func Test_parseConfigFile(t *testing.T) {
113-
fileContents := []string{"", " ", "\n"}
114-
for _, contents := range fileContents {
115-
t.Run(fmt.Sprintf("contents: %q", contents), func(t *testing.T) {
116-
defer StubConfig(contents, "")()
113+
tests := []struct {
114+
contents string
115+
wantsErr bool
116+
}{
117+
{
118+
contents: "",
119+
wantsErr: true,
120+
},
121+
{
122+
contents: " ",
123+
wantsErr: false,
124+
},
125+
{
126+
contents: "\n",
127+
wantsErr: false,
128+
},
129+
}
130+
131+
for _, tt := range tests {
132+
t.Run(fmt.Sprintf("contents: %q", tt.contents), func(t *testing.T) {
133+
defer StubConfig(tt.contents, "")()
117134
_, yamlRoot, err := parseConfigFile("config.yml")
118-
eq(t, err, nil)
119-
eq(t, yamlRoot.Content[0].Kind, yaml.MappingNode)
120-
eq(t, len(yamlRoot.Content[0].Content), 0)
135+
if tt.wantsErr != (err != nil) {
136+
t.Fatalf("got error: %v", err)
137+
}
138+
if tt.wantsErr {
139+
return
140+
}
141+
assert.Equal(t, yaml.MappingNode, yamlRoot.Content[0].Kind)
142+
assert.Equal(t, 0, len(yamlRoot.Content[0].Content))
121143
})
122144
}
123145
}

internal/config/config_type.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ func NewConfig(root *yaml.Node) Config {
123123
}
124124

125125
func NewBlankConfig() Config {
126-
return NewConfig(&yaml.Node{
126+
return NewConfig(NewBlankRoot())
127+
}
128+
129+
func NewBlankRoot() *yaml.Node {
130+
return &yaml.Node{
127131
Kind: yaml.DocumentNode,
128132
Content: []*yaml.Node{
129133
{
@@ -168,7 +172,7 @@ func NewBlankConfig() Config {
168172
},
169173
},
170174
},
171-
})
175+
}
172176
}
173177

174178
// This type implements a Config interface and represents a config file on disk.

internal/config/testing.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ func StubConfig(main, hosts string) func() {
4242
ReadConfigFile = func(fn string) ([]byte, error) {
4343
switch path.Base(fn) {
4444
case "config.yml":
45-
return []byte(main), nil
45+
if main == "" {
46+
return []byte(nil), os.ErrNotExist
47+
} else {
48+
return []byte(main), nil
49+
}
4650
case "hosts.yml":
4751
if hosts == "" {
4852
return []byte(nil), os.ErrNotExist

0 commit comments

Comments
 (0)