Skip to content

Commit b30cf15

Browse files
authored
Merge pull request cli#1295 from cli/path-error
Raise more informative path error when reading config file
2 parents 17c4eee + 4827ffb commit b30cf15

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

internal/config/config_file.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io/ioutil"
88
"os"
99
"path"
10+
"syscall"
1011

1112
"github.com/mitchellh/go-homedir"
1213
"gopkg.in/yaml.v3"
@@ -32,7 +33,7 @@ func ParseDefaultConfig() (Config, error) {
3233
var ReadConfigFile = func(filename string) ([]byte, error) {
3334
f, err := os.Open(filename)
3435
if err != nil {
35-
return nil, err
36+
return nil, pathError(err)
3637
}
3738
defer f.Close()
3839

@@ -47,7 +48,7 @@ var ReadConfigFile = func(filename string) ([]byte, error) {
4748
var WriteConfigFile = func(filename string, data []byte) error {
4849
err := os.MkdirAll(path.Dir(filename), 0771)
4950
if err != nil {
50-
return err
51+
return pathError(err)
5152
}
5253

5354
cfgFile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) // cargo coded from setup
@@ -172,3 +173,28 @@ func ParseConfig(filename string) (Config, error) {
172173

173174
return NewConfig(root), nil
174175
}
176+
177+
func pathError(err error) error {
178+
var pathError *os.PathError
179+
if errors.As(err, &pathError) && errors.Is(pathError.Err, syscall.ENOTDIR) {
180+
if p := findRegularFile(pathError.Path); p != "" {
181+
return fmt.Errorf("remove or rename regular file `%s` (must be a directory)", p)
182+
}
183+
184+
}
185+
return err
186+
}
187+
188+
func findRegularFile(p string) string {
189+
for {
190+
if s, err := os.Stat(p); err == nil && s.Mode().IsRegular() {
191+
return p
192+
}
193+
newPath := path.Dir(p)
194+
if newPath == p || newPath == "/" || newPath == "." {
195+
break
196+
}
197+
p = newPath
198+
}
199+
return ""
200+
}

0 commit comments

Comments
 (0)