From f5f992ae94ecc7bdf530186d56195cd8e26242da Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 20 Apr 2026 12:51:50 -0600 Subject: [PATCH] refactor: move geoip setup into geoip.OpenDatabases, remove cmd/check-ip/geo.go OpenDatabases(confPath, cityPath, asnPath) handles conf discovery, cache dir setup, and Databases construction. DefaultConfPaths lists the standard GeoIP.conf locations. cmd/check-ip/geo.go deleted; main calls one function. --- cmd/check-ip/geo.go | 65 -------------------------------------------- cmd/check-ip/main.go | 3 +- net/geoip/geoip.go | 56 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 66 deletions(-) delete mode 100644 cmd/check-ip/geo.go diff --git a/cmd/check-ip/geo.go b/cmd/check-ip/geo.go deleted file mode 100644 index 43bbf8d..0000000 --- a/cmd/check-ip/geo.go +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/therootcompany/golib/net/geoip" -) - -// discoverConf looks for GeoIP.conf in the current directory and then -// at ~/.config/maxmind/GeoIP.conf. Returns the path or "". -func discoverConf() string { - if _, err := os.Stat("GeoIP.conf"); err == nil { - return "GeoIP.conf" - } - if home, err := os.UserHomeDir(); err == nil { - p := filepath.Join(home, ".config", "maxmind", "GeoIP.conf") - if _, err := os.Stat(p); err == nil { - return p - } - } - return "" -} - -// setupGeo returns a Databases ready to Init, or nil if geoip is not configured. -// -// - confPath="" → auto-discover GeoIP.conf from cwd and ~/.config/maxmind/ -// - conf found → auto-download; cityPath/asnPath override the default locations -// - conf absent → cityPath and asnPath must point to existing .mmdb files -// - no conf and no paths → geoip disabled (returns nil) -func setupGeo(confPath, cityPath, asnPath string) (*geoip.Databases, error) { - if confPath == "" { - confPath = discoverConf() - } - - if confPath != "" { - cfg, err := geoip.ParseConf(confPath) - if err != nil { - return nil, fmt.Errorf("geoip-conf: %w", err) - } - dbDir := cfg.DatabaseDirectory - if dbDir == "" { - if dbDir, err = geoip.DefaultCacheDir(); err != nil { - return nil, fmt.Errorf("geoip cache dir: %w", err) - } - } - if err := os.MkdirAll(dbDir, 0o755); err != nil { - return nil, fmt.Errorf("mkdir %s: %w", dbDir, err) - } - if cityPath == "" { - cityPath = filepath.Join(dbDir, geoip.CityEdition+".mmdb") - } - if asnPath == "" { - asnPath = filepath.Join(dbDir, geoip.ASNEdition+".mmdb") - } - return geoip.New(cfg.AccountID, cfg.LicenseKey).NewDatabases(cityPath, asnPath), nil - } - - if cityPath == "" && asnPath == "" { - return nil, nil - } - // Explicit paths only — no auto-download. Init will fail if files are absent. - return geoip.NewDatabases(cityPath, asnPath), nil -} diff --git a/cmd/check-ip/main.go b/cmd/check-ip/main.go index 859ab26..bb98e4d 100644 --- a/cmd/check-ip/main.go +++ b/cmd/check-ip/main.go @@ -10,6 +10,7 @@ import ( "time" "github.com/therootcompany/golib/net/dataset" + "github.com/therootcompany/golib/net/geoip" "github.com/therootcompany/golib/net/gitshallow" "github.com/therootcompany/golib/net/httpcache" "github.com/therootcompany/golib/net/ipcohort" @@ -97,7 +98,7 @@ func main() { // -- GeoIP (optional) -------------------------------------------------- - geo, err := setupGeo(*geoipConf, *cityDB, *asnDB) + geo, err := geoip.OpenDatabases(*geoipConf, *cityDB, *asnDB) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) diff --git a/net/geoip/geoip.go b/net/geoip/geoip.go index f76f2d4..482bc6f 100644 --- a/net/geoip/geoip.go +++ b/net/geoip/geoip.go @@ -34,6 +34,62 @@ type Downloader struct { Timeout time.Duration // 0 uses 5m } +// DefaultConfPaths returns the standard locations where GeoIP.conf is looked +// up: ./GeoIP.conf, then ~/.config/maxmind/GeoIP.conf. +func DefaultConfPaths() []string { + paths := []string{"GeoIP.conf"} + if home, err := os.UserHomeDir(); err == nil { + paths = append(paths, filepath.Join(home, ".config", "maxmind", "GeoIP.conf")) + } + return paths +} + +// OpenDatabases discovers credentials and paths, then returns a ready-to-Init +// Databases. Returns nil with no error when geoip is not configured. +// +// - confPath="" → auto-discover from DefaultConfPaths +// - conf found → auto-download; cityPath/asnPath override default locations +// - no conf → cityPath and asnPath must point to existing .mmdb files +// - no conf and no paths → geoip disabled (returns nil, nil) +func OpenDatabases(confPath, cityPath, asnPath string) (*Databases, error) { + if confPath == "" { + for _, p := range DefaultConfPaths() { + if _, err := os.Stat(p); err == nil { + confPath = p + break + } + } + } + + if confPath != "" { + cfg, err := ParseConf(confPath) + if err != nil { + return nil, fmt.Errorf("geoip-conf: %w", err) + } + dbDir := cfg.DatabaseDirectory + if dbDir == "" { + if dbDir, err = DefaultCacheDir(); err != nil { + return nil, fmt.Errorf("geoip cache dir: %w", err) + } + } + if err := os.MkdirAll(dbDir, 0o755); err != nil { + return nil, fmt.Errorf("mkdir %s: %w", dbDir, err) + } + if cityPath == "" { + cityPath = filepath.Join(dbDir, CityEdition+".mmdb") + } + if asnPath == "" { + asnPath = filepath.Join(dbDir, ASNEdition+".mmdb") + } + return New(cfg.AccountID, cfg.LicenseKey).NewDatabases(cityPath, asnPath), nil + } + + if cityPath == "" && asnPath == "" { + return nil, nil + } + return NewDatabases(cityPath, asnPath), nil +} + // DefaultCacheDir returns the OS cache directory for MaxMind databases, // e.g. ~/.cache/maxmind on Linux or ~/Library/Caches/maxmind on macOS. func DefaultCacheDir() (string, error) {