From d7a7bc98f75482b68bd61fb5291814c3ff3f41cf Mon Sep 17 00:00:00 2001 From: Jules Cisek Date: Mon, 26 Jan 2026 22:55:27 -0800 Subject: [PATCH 1/2] irfetch: configuration from irfetch.yaml --- examples/irfetch/irfetch.go | 82 +++++++++++++++++++++++++++++++++++-- go.mod | 2 +- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/examples/irfetch/irfetch.go b/examples/irfetch/irfetch.go index 2f01f27..af07c74 100644 --- a/examples/irfetch/irfetch.go +++ b/examples/irfetch/irfetch.go @@ -7,9 +7,12 @@ import ( "fmt" "log" "os" + "path/filepath" + "strings" "time" "github.com/popmonkey/irdata" + "gopkg.in/yaml.v3" ) const toolName = "irfetch" @@ -36,14 +39,65 @@ func init() { flag.StringVar(&authTokenFile, "authtoken", "", "path to file to store/load auth token") } +type fetchConfig struct { + AuthTokenFile string `yaml:"authtoken"` + KeyFile string `yaml:"key"` + CredsFile string `yaml:"creds"` + CacheDir string `yaml:"cachedir"` +} + +func expandPath(path string) string { + if strings.HasPrefix(path, "~/") || strings.HasPrefix(path, "~\\") { + if home, err := os.UserHomeDir(); err == nil { + return filepath.Join(home, path[2:]) + } + } + return path +} + func main() { var err error + var cfg fetchConfig + + if home, err := os.UserHomeDir(); err == nil { + configFiles := []string{ + filepath.Join(home, ".irfetch.yaml"), + filepath.Join(home, "irfetch.yaml"), + } + for _, fn := range configFiles { + if _, err := os.Stat(fn); err == nil { + f, err := os.Open(fn) + if err == nil { + decoder := yaml.NewDecoder(f) + if err := decoder.Decode(&cfg); err == nil { + // Config loaded successfully + } + f.Close() + break + } + } + } + } + + if cfg.CacheDir != "" { + cacheDir = expandPath(cfg.CacheDir) + } + if cfg.AuthTokenFile != "" { + authTokenFile = expandPath(cfg.AuthTokenFile) + } + if cfg.KeyFile != "" { + cfg.KeyFile = expandPath(cfg.KeyFile) + } + if cfg.CredsFile != "" { + cfg.CredsFile = expandPath(cfg.CredsFile) + } flag.Parse() flag.Usage = func() { w := flag.CommandLine.Output() fmt.Fprintf(w, "Usage: %s [options] \n", toolName) + fmt.Fprintf(w, " %s [options] (if key/creds configured in .irfetch.yaml)\n", toolName) flag.PrintDefaults() } @@ -64,24 +118,44 @@ Note that the api request should be in the form of a URI, not a full URL. %[1]s can optionally cache results from iRacing's /data API. Subsequent requests to the same URI will return data from this cache until it is expired. See --help. +Configuration: +%[1]s checks for a configuration file in your home directory: + - .irfetch.yaml (or irfetch.yaml) + +Example config: + authtoken: ~/.irdata_token + key: ~/my.key + creds: ~/ir.creds + cachedir: .irfetch_cache + +If configured, you can omit the key and creds arguments. + (%[1]s is built in Go using the irdata library at https://github.com/popmonkey/irdata) Example: %[1]s -c -cachettl 60m ~/my.key ~/ir.creds /data/member/info %[1]s --authtoken ~/.irdata_token ~/my.key ~/ir.creds /data/member/info +%[1]s /data/member/info `, toolName) flag.Usage() os.Exit(0) } - if len(flag.Args()) != 3 { + args := flag.Args() + var keyFn, credsFn, apiUri string + + if len(args) == 3 { + keyFn, credsFn, apiUri = args[0], args[1], args[2] + } else if len(args) == 1 && cfg.KeyFile != "" && cfg.CredsFile != "" { + keyFn = cfg.KeyFile + credsFn = cfg.CredsFile + apiUri = args[0] + } else { flag.Usage() os.Exit(1) } - keyFn, credsFn, apiUri := flag.Arg(0), flag.Arg(1), flag.Arg(2) - api := irdata.Open(context.Background()) defer api.Close() @@ -140,4 +214,4 @@ Example: } fmt.Println() -} +} \ No newline at end of file diff --git a/go.mod b/go.mod index 3759a06..49434c4 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 golang.org/x/term v0.21.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -18,5 +19,4 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect golang.org/x/sys v0.21.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) From 6279c00b87659d33d20ef63fd85484ef76e8bd04 Mon Sep 17 00:00:00 2001 From: Jules Cisek Date: Mon, 26 Jan 2026 23:02:07 -0800 Subject: [PATCH 2/2] irfetch: don't panic --- examples/irfetch/irfetch.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/irfetch/irfetch.go b/examples/irfetch/irfetch.go index af07c74..b9b2113 100644 --- a/examples/irfetch/irfetch.go +++ b/examples/irfetch/irfetch.go @@ -5,7 +5,6 @@ import ( "context" "flag" "fmt" - "log" "os" "path/filepath" "strings" @@ -177,12 +176,14 @@ Example: if _, err := os.Stat(credsFn); err != nil { err = api.AuthAndSaveProvidedCredsToFile(keyFn, credsFn, irdata.CredsFromTerminal{}) if err != nil { - log.Panic(err) + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) } } else { err = api.AuthWithCredsFromFile(keyFn, credsFn) if err != nil { - log.Panic(err) + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) } } @@ -198,19 +199,22 @@ Example: data, err = api.Get(apiUri) } if err != nil { - log.Panic(err) + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) } writer := bufio.NewWriter(os.Stdout) _, err = writer.Write(data) if err != nil { - log.Panic(err) + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) } err = writer.Flush() if err != nil { - log.Panic(err) + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) } fmt.Println()