Abort startup on a config file pixa cannot read (closes #176)
check / check (push) Failing after 4s
check / check (push) Failing after 4s
Of the places pixa looks for its config file on its own, it passed over any place where os.Stat failed, so a file in a directory pixa may not enter was skipped without a word and pixa started on a later file or on the environment and defaults. Now only a path that does not exist, or that runs through a file (such as under a HOME of /dev/null), is passed over; any other error aborts startup naming the file, as a file that does not parse already did. README.md says so where it gives the search order. A config.yml that links to itself tests this as root too. Model: opus-5-5
This commit was merged in pull request #181.
This commit is contained in:
+21
-11
@@ -4,6 +4,7 @@ package config
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"math"
|
||||
"net/netip"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"git.eeqj.de/sneak/smartconfig"
|
||||
@@ -778,19 +780,27 @@ func loadConfigFile(log *slog.Logger, appName string) (*smartconfig.Config, erro
|
||||
for _, path := range configPaths {
|
||||
cleanPath := filepath.Clean(path)
|
||||
|
||||
// Only a config file that does not exist is skipped, including
|
||||
// one whose path runs through a file, such as under a HOME of
|
||||
// /dev/null. One that cannot be read or does not parse is a
|
||||
// fatal startup error.
|
||||
_, statErr := os.Stat(cleanPath)
|
||||
if statErr == nil {
|
||||
// A config file that exists but does not parse is a fatal
|
||||
// startup error, never something to skip over.
|
||||
sc, err := smartconfig.NewFromConfigPath(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config file %s: %w", path, err)
|
||||
}
|
||||
|
||||
log.Info("loaded config file", "path", path)
|
||||
|
||||
return sc, nil
|
||||
if errors.Is(statErr, fs.ErrNotExist) || errors.Is(statErr, syscall.ENOTDIR) {
|
||||
continue
|
||||
}
|
||||
|
||||
if statErr != nil {
|
||||
return nil, fmt.Errorf("failed to read config file %s: %w", path, statErr)
|
||||
}
|
||||
|
||||
sc, err := smartconfig.NewFromConfigPath(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse config file %s: %w", path, err)
|
||||
}
|
||||
|
||||
log.Info("loaded config file", "path", path)
|
||||
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
return nil, nil //nolint:nilnil // nil config is valid (use defaults)
|
||||
|
||||
Reference in New Issue
Block a user