Route scanner output through writer, fix S3 error handling, improve error messages
All checks were successful
check / check (push) Successful in 2m38s

Scanner now writes all user-facing output to an io.Writer (os.Stdout
when progress is enabled, io.Discard in --cron mode). This fixes the
long-standing issue where --cron still printed progress lines.

S3 HeadObject now properly distinguishes not-found from other errors
instead of swallowing all errors as not-found.

Config/CLI error messages include actionable hints (where to find the
config, how to generate keys, what storage options exist).
This commit is contained in:
2026-06-09 12:31:50 -04:00
parent 20d3a9ac8c
commit ebd6619638
6 changed files with 84 additions and 133 deletions

View File

@@ -236,11 +236,11 @@ func Load(path string) (*Config, error) {
// Returns an error describing the first validation failure encountered.
func (c *Config) Validate() error {
if len(c.AgeRecipients) == 0 {
return fmt.Errorf("at least one age_recipient is required")
return fmt.Errorf("at least one age_recipient is required (generate with: age-keygen)")
}
if len(c.Snapshots) == 0 {
return fmt.Errorf("at least one snapshot must be configured")
return fmt.Errorf("at least one snapshot must be configured (see config.example.yml)")
}
for name, snap := range c.Snapshots {
@@ -299,7 +299,7 @@ func (c *Config) validateStorage() error {
// Legacy S3 configuration
if c.S3.Endpoint == "" {
return fmt.Errorf("s3.endpoint is required (or set storage_url)")
return fmt.Errorf("storage not configured; set storage_url or provide s3.endpoint + s3.bucket + credentials")
}
if c.S3.Bucket == "" {