fuzzyworld

template / windows / files / config.go

Branch windows · default branch · all branches

config.go

2.6 KB · history · blame

1package main
2
3import (
4 "fmt"
5 "os"
6
7 "golang.org/x/exp/slices"
8 "gopkg.in/yaml.v3"
9)
10
11type Config struct {
12 Profiles []Profile
13}
14
15func validateConfig(config *Config) error {
16 if config.Profiles == nil || len(config.Profiles) == 0 {
17 return fmt.Errorf("no profiles found")
18 }
19
20 names := []string{}
21 foundDefault := false
22 for index, profile := range config.Profiles {
23 profile := profile
24
25 // check for duplicate names
26 if slices.Contains(names, profile.Name) {
27 return fmt.Errorf("duplicate profile name '%v'", profile.Name)
28 }
29 names = append(names, profile.Name)
30
31 // check for multiple default profiles
32 if profile.IsDefault {
33 if foundDefault {
34 return fmt.Errorf("multiple default profiles found")
35 }
36 foundDefault = true
37 }
38
39 // validate and possibly fix profile
40 err := validateProfile(&profile)
41 if err != nil {
42 return fmt.Errorf("error validating profile %s: %s", profile.Name, err)
43 }
44 config.Profiles[index] = profile
45 }
46 return nil
47}
48
49func loadConfig(path string) (Config, error) {
50 file, err := os.ReadFile(path)
51 if err != nil {
52 return Config{}, err
53 }
54
55 var config Config
56 err = yaml.Unmarshal(file, &config)
57 if err != nil {
58 return Config{}, err
59 }
60
61 err = validateConfig(&config)
62 if err != nil {
63 return Config{}, err
64 }
65
66 return config, nil
67}
68
69func saveConfig(path string, config Config) error {
70 err := validateConfig(&config)
71 if err != nil {
72 return err
73 }
74 file, err := os.Create(path)
75 if err != nil {
76 return err
77 }
78 defer file.Close()
79 encoder := yaml.NewEncoder(file)
80 err = encoder.Encode(config)
81 if err != nil {
82 return err
83 }
84
85 return nil
86}
87
88func mergeConfigs(a Config, b Config) (Config, error) {
89 err := validateConfig(&a)
90 if err != nil {
91 return Config{}, fmt.Errorf("error validating config a: %s", err)
92 }
93 err = validateConfig(&b)
94 if err != nil {
95 return Config{}, fmt.Errorf("error validating config b: %s", err)
96 }
97
98 merged := Config{
99 Profiles: a.Profiles,
100 }
101 for _, profile := range b.Profiles {
102 index, err := findProfileIndex(merged.Profiles, profile.Name)
103 if err == nil {
104 merged.Profiles[index] = profile
105 } else {
106 merged.Profiles = append(merged.Profiles, profile)
107 }
108 }
109 return merged, nil
110}
111
112func findDefaultProfile(profiles []Profile) (Profile, error) {
113 for _, p := range profiles {
114 if p.IsDefault {
115 return p, nil
116 }
117 }
118 return Profile{}, fmt.Errorf("unable to find default profile")
119}
120
121func findProfileIndex(profiles []Profile, profileName string) (int, error) {
122 for index, p := range profiles {
123 if p.Name == profileName {
124 return index, nil
125 }
126 }
127 return 0, fmt.Errorf("unable to find profile '%v'", profileName)
128}