@@ -38,7 +38,7 @@ type Config struct {
3838// GetConfigPath returns the OS-appropriate config file path for tblogs
3939const defaultConfigFile = "data.yml"
4040
41- func GetConfigPath () (string , error ) {
41+ func getConfigPath () (string , error ) {
4242 configDir , err := os .UserConfigDir ()
4343 if err != nil {
4444 return "" , err
@@ -52,42 +52,17 @@ func GetConfigPath() (string, error) {
5252 return filepath .Join (tblogsDir , defaultConfigFile ), nil
5353}
5454
55- func loadDefaultBlogsYAML (path string ) ([]Blog , error ) {
56- f , err := os .Open (path )
55+ // LoadConfig loads the YAML config from the given path (or default path if empty) and returns a Config struct
56+ func LoadConfig () (* Config , error ) {
57+ path , err := getConfigPath ()
5758 if err != nil {
5859 return nil , err
5960 }
6061
61- defer func () {
62- if err := f .Close (); err != nil {
63- log .Printf ("failed to close file: %v" , err )
64- }
65- }()
66-
67- var blogs []Blog
68-
69- decoder := yaml .NewDecoder (f )
70- if err := decoder .Decode (& blogs ); err != nil {
71- return nil , err
72- }
73-
74- return blogs , nil
75- }
76-
77- // LoadConfig loads the YAML config from the given path (or default path if empty) and returns a Config struct
78- func LoadConfig (path string ) (* Config , error ) {
79- if path == "" {
80- var err error
81- path , err = GetConfigPath ()
82- if err != nil {
83- return nil , err
84- }
85- }
86-
8762 f , err := os .Open (path )
8863 if err != nil {
8964 if os .IsNotExist (err ) {
90- blogs , err := loadDefaultBlogsYAML ( "internal/config/default-blogs.yml" )
65+ blogs , err := loadDefaultBlogs ( )
9166 if err != nil {
9267 return nil , err
9368 }
@@ -103,7 +78,7 @@ func LoadConfig(path string) (*Config, error) {
10378 }
10479
10580 // Save the default config
106- if err := SaveConfig (cfg , path ); err != nil {
81+ if err := SaveConfig (cfg ); err != nil {
10782 return nil , err
10883 }
10984
@@ -126,22 +101,68 @@ func LoadConfig(path string) (*Config, error) {
126101 return nil , err
127102 }
128103
104+ // Sync blogs with defaults
105+ if err := cfg .syncBlogs (); err != nil {
106+ log .Printf ("warning: failed to sync blogs: %v" , err )
107+ // Don't fail the load, just log the warning
108+ }
109+
129110 cfg .App .CurrentLogin = time .Now ()
130111
131112 return & cfg , nil
132113}
133114
134- // SaveConfig writes the config struct to the given YAML file path (or default path if empty)
135- func SaveConfig (cfg * Config , path string ) error {
136- if path == "" {
137- var err error
115+ func loadDefaultBlogs () ([]Blog , error ) {
116+ f , err := os .Open ("internal/config/default-blogs.yml" )
117+ if err != nil {
118+ return nil , err
119+ }
138120
139- path , err = GetConfigPath ()
140- if err != nil {
141- return err
121+ defer func () {
122+ if err := f .Close (); err != nil {
123+ log .Printf ("failed to close file: %v" , err )
124+ }
125+ }()
126+
127+ var blogs []Blog
128+
129+ decoder := yaml .NewDecoder (f )
130+ if err := decoder .Decode (& blogs ); err != nil {
131+ return nil , err
132+ }
133+
134+ return blogs , nil
135+ }
136+
137+ func (cfg * Config ) syncBlogs () error {
138+ defaultBlogs , err := loadDefaultBlogs ()
139+ if err != nil {
140+ return err
141+ }
142+
143+ // Create a map of existing blogs by name for quick lookup
144+ existingBlogs := make (map [string ]Blog )
145+ for _ , blog := range cfg .Blogs {
146+ existingBlogs [blog .Name ] = blog
147+ }
148+
149+ // Add missing blogs from default
150+ for _ , defaultBlog := range defaultBlogs {
151+ if _ , exists := existingBlogs [defaultBlog .Name ]; ! exists {
152+ cfg .Blogs = append (cfg .Blogs , defaultBlog )
142153 }
143154 }
144155
156+ return nil
157+ }
158+
159+ // SaveConfig writes the config struct to the given YAML file path (or default path if empty)
160+ func SaveConfig (cfg * Config ) error {
161+ path , err := getConfigPath ()
162+ if err != nil {
163+ return err
164+ }
165+
145166 f , err := os .Create (path )
146167 if err != nil {
147168 return err
0 commit comments