-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathini.go
More file actions
67 lines (58 loc) · 1.84 KB
/
Copy pathini.go
File metadata and controls
67 lines (58 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package resolver
import (
"errors"
"fmt"
"io/fs"
"os"
"strings"
"gopkg.in/ini.v1"
)
// INIResolver resolves a value by loading an INI file and extracting a section.key pair.
// Format: "ini:/path/file.ini//Section.Key" or "ini:/path/file.ini//Key" (default section).
// If no key is provided, returns the entire INI file as a string.
type INIResolver struct{}
func (r *INIResolver) Resolve(value string) (string, error) {
filePath, keyPath := splitFileAndKey(value)
filePath = os.ExpandEnv(filePath)
cfg, err := ini.Load(filePath)
if err != nil {
// ini.Load wraps os.Open errors; try to map to sentinels.
if errors.Is(err, fs.ErrNotExist) {
return "", fmt.Errorf("%w: %s", ErrNotFound, filePath)
}
if errors.Is(err, fs.ErrPermission) {
return "", fmt.Errorf("%w: %s", ErrForbidden, filePath)
}
return "", fmt.Errorf("failed to read INI file %q: %w", filePath, err)
}
if keyPath == "" {
// No key path means return the entire INI file
data, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("failed to read INI file %q: %w", filePath, err)
}
return strings.TrimSpace(string(data)), nil
}
// KeyPath can be "Section.Key" or just "Key" (default section)
parts := strings.Split(keyPath, ".")
var sectionName, keyName string
if len(parts) == 1 {
sectionName = "DEFAULT"
keyName = parts[0]
} else {
sectionName = parts[0]
keyName = strings.Join(parts[1:], ".")
}
if strings.TrimSpace(keyName) == "" {
return "", fmt.Errorf("%w: empty key in %q", ErrBadPath, keyPath)
}
section, err := cfg.GetSection(sectionName)
if err != nil {
return "", fmt.Errorf("%w: section %q in %q", ErrNotFound, sectionName, filePath)
}
k, err := section.GetKey(keyName)
if err != nil {
return "", fmt.Errorf("%w: key %q in section %q of %q", ErrNotFound, keyName, sectionName, filePath)
}
return k.String(), nil
}