First start: create the config file and open the Config view

Without a config file arr-tui refused to start. It now creates an empty
one (private, with its directory) and opens the Config view. A service
with neither address nor key is "not configured", which validation
allows: its client returns ErrNotConfigured without a request, its
indicator stays grey, it is logged once as information, and its lists
say so instead of showing errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019reK4DUGYqDUjniWYJvwUW
This commit is contained in:
2026-10-21 15:16:08 +02:00
co-authored by Claude Opus 5.5
parent 12d572757e
commit b259e22458
15 changed files with 193 additions and 13 deletions
+24 -1
View File
@@ -18,6 +18,24 @@ type Service struct {
APIKey string `json:"apikey"`
}
// Configured reports whether the service is set up at all (address or key
// given). Validate checks that a configured service has both.
func (s Service) Configured() bool { return s.URL != "" || s.APIKey != "" }
// AnyConfigured reports whether at least one service is set up.
func (c *Config) AnyConfigured() bool {
return c.Radarr.Configured() || c.Sonarr.Configured() || c.SABnzbd.Configured()
}
// Create writes an empty configuration to path, creating its directory
// (private, like the file). Every service is not set up yet.
func Create(path string) error {
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
return fmt.Errorf("creating config directory: %w", err)
}
return Save(path, &Config{})
}
// Arr is a Radarr or Sonarr instance, with optional defaults for the add form.
type Arr struct {
Service
@@ -246,7 +264,9 @@ func (c *Config) applyDefaults() {
c.SABnzbd.URL = strings.TrimRight(c.SABnzbd.URL, "/")
}
// Validate checks that every service has a usable URL and API key.
// Validate checks that every service that is set up has a usable URL and API
// key. A service with neither is not set up, which is allowed: the program
// starts without it and says so, and the Config view can fill it in.
func (c *Config) Validate() error {
var errs []error
for _, s := range []struct {
@@ -257,6 +277,9 @@ func (c *Config) Validate() error {
{"sonarr", c.Sonarr.Service},
{"sabnzbd", c.SABnzbd},
} {
if !s.svc.Configured() {
continue // not set up (yet); the program says so where it is needed
}
if s.svc.APIKey == "" {
errs = append(errs, fmt.Errorf("%s: apikey is required", s.name))
}