-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
98 lines (88 loc) · 2.37 KB
/
Copy pathconfig.go
File metadata and controls
98 lines (88 loc) · 2.37 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
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"time"
)
type Config struct {
PollSeconds int `json:"poll_seconds"`
IdleSeconds int `json:"idle_seconds"`
Allotments map[string]string `json:"allotments"` // app -> duration ("2h", "90m")
Rules []Rule `json:"rules"` // classification rules, title rules before app rules
Repos []string `json:"repos"` // git repos scanned for commit yield
Weights Weights `json:"weights"` // score component weights, must sum to 100
}
// Weights are the score components; each component is a 0–1 ratio.
type Weights struct {
Focus int `json:"focus"` // productive / active
Depth int `json:"depth"` // deep-work / productive
Cohesion int `json:"cohesion"` // 1 - switches-per-hour penalty
Yield int `json:"yield"` // artifact-linked deep hours / deep hours
}
func defaultWeights() Weights {
return Weights{Focus: 35, Depth: 25, Cohesion: 15, Yield: 25}
}
func defaultConfig() Config {
return Config{
PollSeconds: 5,
IdleSeconds: 60,
Allotments: map[string]string{},
Rules: defaultRules(),
Weights: defaultWeights(),
}
}
func baseDir() string {
return filepath.Join(os.Getenv("LOCALAPPDATA"), "lacheisis")
}
func configPath() string {
return filepath.Join(baseDir(), "config.json")
}
func loadConfig() Config {
cfg := defaultConfig()
data, err := os.ReadFile(configPath())
if err != nil {
return cfg
}
json.Unmarshal(data, &cfg)
if cfg.PollSeconds <= 0 {
cfg.PollSeconds = 5
}
if cfg.IdleSeconds <= 0 {
cfg.IdleSeconds = 60
}
if cfg.Allotments == nil {
cfg.Allotments = map[string]string{}
}
if cfg.Rules == nil {
cfg.Rules = defaultRules()
}
if cfg.Weights == (Weights{}) {
cfg.Weights = defaultWeights()
}
return cfg
}
func saveConfig(cfg Config) error {
if err := os.MkdirAll(baseDir(), 0o755); err != nil {
return err
}
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
return os.WriteFile(configPath(), data, 0o644)
}
// allotmentFor returns the parsed daily allotment for an app, or 0 if none set.
func (c Config) allotmentFor(app string) time.Duration {
s, ok := c.Allotments[app]
if !ok {
return 0
}
d, err := time.ParseDuration(s)
if err != nil {
fmt.Fprintf(os.Stderr, "warning: bad allotment %q for %s\n", s, app)
return 0
}
return d
}