-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
153 lines (123 loc) · 3.48 KB
/
config.go
File metadata and controls
153 lines (123 loc) · 3.48 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package config
import (
"fmt"
"os"
"time"
"gopkg.in/yaml.v3"
)
// Duration represents a time duration that can be parsed from strings
type Duration struct {
time.Duration
}
// UnmarshalYAML implements custom unmarshaling for duration strings
func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
var value interface{}
if err := unmarshal(&value); err != nil {
return err
}
switch v := value.(type) {
case string:
duration, err := time.ParseDuration(v)
if err != nil {
return fmt.Errorf("invalid duration format '%s': %w", v, err)
}
d.Duration = duration
case int:
// Backward compatibility: treat as seconds
d.Duration = time.Duration(v) * time.Second
case int64:
// Backward compatibility: treat as seconds
d.Duration = time.Duration(v) * time.Second
default:
return fmt.Errorf("duration must be a string (e.g., '60s', '1h') or integer (seconds)")
}
return nil
}
// Seconds returns the duration in seconds
func (d *Duration) Seconds() int {
return int(d.Duration.Seconds())
}
type Config struct {
Server ServerConfig `yaml:"server"`
Logging LoggingConfig `yaml:"logging"`
Metrics MetricsConfig `yaml:"metrics"`
GitHub GitHubConfig `yaml:"github"`
Packages []PackageGroup `yaml:"packages"`
}
type GitHubConfig struct {
Token string `yaml:"token"`
}
type ServerConfig struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Debug bool `yaml:"debug"`
}
type LoggingConfig struct {
Level string `yaml:"level"`
Format string `yaml:"format"` // "json" or "text"
}
type MetricsConfig struct {
Collection CollectionConfig `yaml:"collection"`
}
type CollectionConfig struct {
DefaultInterval Duration `yaml:"default_interval"`
// Track if the value was explicitly set
DefaultIntervalSet bool `yaml:"-"`
}
// UnmarshalYAML implements custom unmarshaling to track if the value was set
func (c *CollectionConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
// Create a temporary struct to unmarshal into
type tempCollectionConfig struct {
DefaultInterval Duration `yaml:"default_interval"`
}
var temp tempCollectionConfig
if err := unmarshal(&temp); err != nil {
return err
}
c.DefaultInterval = temp.DefaultInterval
c.DefaultIntervalSet = true
return nil
}
type PackageGroup struct {
Owner string `yaml:"owner"`
Repo string `yaml:"repo,omitempty"` // Optional - if not provided, will discover all repos for owner
}
// GetName returns a unique name for this package group
func (p PackageGroup) GetName() string {
if p.Repo == "" {
return p.Owner + "-all"
}
return p.Owner + "-" + p.Repo
}
// GetPackageInterval returns the interval for a package group
func (c *Config) GetPackageInterval(group PackageGroup) int {
if c.Metrics.Collection.DefaultIntervalSet {
return c.Metrics.Collection.DefaultInterval.Seconds()
}
return 60 // Default to 60 seconds
}
// LoadConfig loads configuration from a file
func LoadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
var config Config
if err := yaml.Unmarshal(data, &config); err != nil {
return nil, fmt.Errorf("failed to parse config file: %w", err)
}
// Set defaults
if config.Server.Host == "" {
config.Server.Host = "0.0.0.0"
}
if config.Server.Port == 0 {
config.Server.Port = 8080
}
if config.Logging.Level == "" {
config.Logging.Level = "info"
}
if config.Logging.Format == "" {
config.Logging.Format = "json"
}
return &config, nil
}