1package repo
2
3import (
4 "fmt"
5 "os"
6
7 "github.com/BurntSushi/toml"
8)
9
10type Config struct {
11 Storage StorageConfig `toml:"storage"`
12 User UserConfig `toml:"user"`
13 UI UIConfig `toml:"ui"`
14 Serve ServeConfig `toml:"serve"`
15 Hooks HooksConfig `toml:"hooks"`
16 Git GitConfig `toml:"git"`
17 Sign SignConfig `toml:"sign"`
18 Snap SnapConfig `toml:"snap"`
19 Remotes []RemoteConfig `toml:"remote"`
20}
21
22type StorageConfig struct {
23 PackThreshold int `toml:"pack_threshold"`
24 PackSealSize int `toml:"pack_seal_size"`
25 Compression string `toml:"compression"`
26}
27
28type UserConfig struct {
29 Name string `toml:"name"`
30 Email string `toml:"email"`
31}
32
33type UIConfig struct {
34 Port int `toml:"port"`
35}
36
37type ServeConfig struct {
38 Port int `toml:"port"`
39 Token string `toml:"token"`
40}
41
42type RemoteConfig struct {
43 Name string `toml:"name"`
44 URL string `toml:"url"`
45 Token string `toml:"token"`
46}
47
48type HooksConfig struct {
49 PreSnap []string `toml:"pre-snap"`
50 PostSnap []string `toml:"post-snap"`
51}
52
53type GitConfig struct {
54 Enabled bool `toml:"enabled"`
55 Remote string `toml:"remote"`
56}
57
58type SignConfig struct {
59 Auto bool `toml:"auto"`
60 KeyFile string `toml:"key"`
61}
62
63type SnapConfig struct {
64 AutoAdvanceBookmarks bool `toml:"auto_advance_bookmarks"`
65}
66
67func DefaultConfig() *Config {
68 return &Config{
69 Storage: StorageConfig{
70 PackThreshold: 128 * 1024,
71 Compression: "zstd",
72 },
73 User: UserConfig{
74 Name: gitConfigValue("user.name", "Unknown User"),
75 Email: gitConfigValue("user.email", "unknown@example.com"),
76 },
77 UI: UIConfig{Port: 7070},
78 Serve: ServeConfig{Port: 8765},
79 Snap: SnapConfig{AutoAdvanceBookmarks: true},
80 }
81}
82
83func loadConfig(path string) (*Config, error) {
84 cfg := DefaultConfig()
85 if _, err := os.Stat(path); os.IsNotExist(err) {
86 return cfg, nil
87 }
88 _, err := toml.DecodeFile(path, cfg)
89 return cfg, err
90}
91
92func writeConfig(path string, cfg *Config) error {
93 f, err := os.Create(path)
94 if err != nil {
95 return err
96 }
97 defer f.Close()
98 fmt.Fprintln(f, "# Arche repository configuration")
99 return toml.NewEncoder(f).Encode(cfg)
100}
101
102func gitConfigValue(key, fallback string) string {
103 switch key {
104 case "user.name":
105 if v := os.Getenv("GIT_AUTHOR_NAME"); v != "" {
106 return v
107 }
108 if v := os.Getenv("USER"); v != "" {
109 return v
110 }
111 case "user.email":
112 if v := os.Getenv("GIT_AUTHOR_EMAIL"); v != "" {
113 return v
114 }
115 if host, _ := os.Hostname(); host != "" {
116 user := os.Getenv("USER")
117 if user != "" {
118 return user + "@" + host
119 }
120 }
121 }
122 return fallback
123}