powerful but friendly backup program that runs in your tray, powered by restic devins.page/restray
go restic system-tray
2

Configure Feed

Select the types of activity you want to include in your feed.

fix: proper data dirs

also add version flag ig

intergrav (Jun 29, 2026, 1:11 PM EDT) 71c151be 808a5a6f

+35 -5
+4
cmd/restray/cli.go
··· 313 313 cliUsage() 314 314 return 0 315 315 316 + case "-V", "--version", "version": 317 + fmt.Println("restray", version) 318 + return 0 319 + 316 320 default: 317 321 fmt.Fprintf(os.Stderr, "unknown command: %s\n", args[0]) 318 322 cliUsage()
+23 -2
cmd/restray/config.go
··· 176 176 return filepath.Join(configDir(), name+".env") 177 177 } 178 178 179 - func logPath() string { return filepath.Join(configDir(), "restray.log") } 180 - func lockPath() string { return filepath.Join(configDir(), "restray.lock") } 179 + func dataDir() string { 180 + switch runtime.GOOS { 181 + case "darwin": 182 + if home, err := os.UserHomeDir(); err == nil { 183 + return filepath.Join(home, "Library", "Application Support", "restray") 184 + } 185 + case "windows": 186 + if dir := os.Getenv("LOCALAPPDATA"); dir != "" { 187 + return filepath.Join(dir, "Restray") 188 + } 189 + default: 190 + if dir := os.Getenv("XDG_STATE_HOME"); dir != "" { 191 + return filepath.Join(dir, "restray") 192 + } 193 + if home, err := os.UserHomeDir(); err == nil { 194 + return filepath.Join(home, ".local", "state", "restray") 195 + } 196 + } 197 + return configDir() 198 + } 199 + 200 + func logPath() string { return filepath.Join(dataDir(), "restray.log") } 201 + func lockPath() string { return filepath.Join(dataDir(), "restray.lock") } 181 202 182 203 func loadConfig() Config { 183 204 cfg := Config{}
+6 -1
cmd/restray/main.go
··· 22 22 } 23 23 24 24 os.MkdirAll(configDir(), 0700) 25 + os.MkdirAll(dataDir(), 0700) 25 26 26 27 lock, err := os.OpenFile(lockPath(), os.O_CREATE|os.O_RDWR, 0600) 27 28 if err != nil || lockFile(lock) != nil { ··· 29 30 } 30 31 defer lock.Close() 31 32 32 - f, err := os.OpenFile(logPath(), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600) 33 + lp := logPath() 34 + if info, err := os.Stat(lp); err == nil && info.Size() > 1<<20 { 35 + os.Truncate(lp, 0) 36 + } 37 + f, err := os.OpenFile(lp, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) 33 38 if err == nil { 34 39 if verbose { 35 40 log.SetOutput(io.MultiWriter(f, os.Stderr))
+2 -2
cmd/restray/manage_windows.go
··· 24 24 var downloading sync.Mutex 25 25 26 26 func managedRestic() string { 27 - p := filepath.Join(configDir(), "restic.exe") 27 + p := filepath.Join(dataDir(), "restic.exe") 28 28 if _, err := os.Stat(p); err == nil { 29 29 return p 30 30 } ··· 116 116 } 117 117 118 118 func installBinary(r io.Reader) error { 119 - p := filepath.Join(configDir(), "restic.exe") 119 + p := filepath.Join(dataDir(), "restic.exe") 120 120 tmp, err := os.CreateTemp(filepath.Dir(p), "restic-download-*") 121 121 if err != nil { 122 122 return err