feat: add local currency display support with auto-fetched exchange rates#1
Conversation
|
Great app @backstabslash ... a small addition that I think will be awesome |
There was a problem hiding this comment.
Pull request overview
Adds local-currency display support to goccc by introducing a currency config (~/.goccc.json) with auto-fetched USD exchange rates, optional CLI overrides, and optional currency metadata in JSON output (while keeping all cost calculations and JSON cost fields in USD for compatibility).
Changes:
- Add currency config/exchange-rate fetching + caching logic and a symbol table.
- Update terminal formatting to display converted costs when a currency is active and print an informational “Costs in …” line; add
currencymetadata object to JSON output. - Add CLI flags for one-off currency overrides and add unit tests + docs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| main.go | Adds -currency-symbol / -currency-rate flags and initializes currency handling at startup. |
| format.go | Makes fmtCost currency-aware; adds JSON currency metadata; updates summary output to include currency info. |
| currency.go | Implements config load/save, symbol lookup, rate fetching, and 24h caching. |
| currency_test.go | Adds unit tests for config parsing, symbol lookup, formatting, and cached-rate behavior. |
| README.md | Documents local currency configuration and CLI override flags. |
| CLAUDE.md | Updates module map and feature notes to include the new currency support. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
backstabslash
left a comment
There was a problem hiding this comment.
Nice feature, clean implementation! A few things to address:
1. No HTTP timeout on fetchExchangeRate (high priority)
http.Get uses the default client with no timeout — if the API is slow or unresponsive, the CLI hangs indefinitely. Use a client with a timeout:
var httpClient = &http.Client{Timeout: 5 * time.Second}
func fetchExchangeRate(currency string) (float64, error) {
resp, err := httpClient.Get("https://open.er-api.com/v6/latest/USD")2. initCurrency should return error, not string
Every other error path in the codebase returns error. Returning a string message is non-idiomatic Go:
func initCurrency(symbolFlag string, rateFlag float64) error {3. CLI override sets Code to the symbol value
When using -currency-symbol "€" -currency-rate 0.92, both Code and Symbol get set to "€", which makes the info line print Costs in € (1 USD = 0.9200 €). Code is meant for ISO codes like EUR.
Either leave Code empty and skip the info line for CLI overrides, or accept a separate flag for the ISO code.
4. Config write errors silently swallowed
saveCurrencyConfig ignores the os.WriteFile error. A stderr warning would be more helpful — consistent with how fetch failures are already handled a few lines below:
if err := os.WriteFile(path, append(data, '\n'), 0644); err != nil {
fmt.Fprintf(os.Stderr, "goccc: warning: failed to save currency config: %v\n", err)
}…n, CLI override code
|
Updated, I used 2s as the timeout as it felt more reasonable to not be blocking for the tool |
|
Thanks for the contribution! Merged and released as v0.1.5 🎉 |
Summary
~/.goccc.jsonconfig file — set"currency": "ZAR"(or any ISO 4217 code) and costs are automatically converted-currency-symboland-currency-rateflags for one-off use (both required together)Costs in AUD (1 USD = 1.4158 AUD))currencymetadata object when non-USD currency is activeConfig example
{ "currency": "AUD" }After first run, the file is updated with cached rate:
{ "currency": "AUD", "cached_rate": 1.4158, "rate_updated": "2026-03-05T08:44:04Z" }