From b53a4b1dfb3349758a49978991554f09700243ab Mon Sep 17 00:00:00 2001 From: Phillip Miller Date: Wed, 13 Apr 2022 15:33:03 -0400 Subject: [PATCH] set default limit to 10, reduce code reuse --- .github/workflows/go.yml | 2 +- .goreleaser.yaml | 2 -- main.go | 64 +++++++++++++++++----------------------- main_test.go | 58 +++++++++++++++--------------------- 4 files changed, 52 insertions(+), 74 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 2535d05..bef5c43 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -23,7 +23,7 @@ jobs: # Setup Go - name: Setup Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v3 with: go-version: ${{ matrix.go-version }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 9665466..1e5d37f 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -26,8 +26,6 @@ builds: - "386" - arm - arm64 - ignore: - - goarch: arm64 archives: - id: tgz diff --git a/main.go b/main.go index ebda8d5..ca4f90b 100644 --- a/main.go +++ b/main.go @@ -94,7 +94,7 @@ func redOrGreen(num float64) tablewriter.Colors { func printTable(cmcData *CMCCoinData) error { table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"Rank", "Name", "Symbol", "Price (USD)", "Change 24H", "Change 7Day", "Change 30Day", "Market Cap", "Supply", "Volume 24H"}) + table.SetHeader([]string{"Rank", "Name", "Symbol", "Price (USD)", "Change 24H", "Change 7Day", "Change 30Day", "Market Cap", "Supply", "Circulating Supply", "Volume 24H"}) table.SetBorder(false) table.SetHeaderColor( @@ -108,6 +108,7 @@ func printTable(cmcData *CMCCoinData) error { tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiYellowColor, tablewriter.BgBlackColor}, tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiYellowColor, tablewriter.BgBlackColor}, tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiYellowColor, tablewriter.BgBlackColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiYellowColor, tablewriter.BgBlackColor}, ) table.SetColumnColor( @@ -121,6 +122,7 @@ func printTable(cmcData *CMCCoinData) error { tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiWhiteColor, tablewriter.BgBlackColor}, tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiWhiteColor, tablewriter.BgBlackColor}, tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiWhiteColor, tablewriter.BgBlackColor}, + tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiWhiteColor, tablewriter.BgBlackColor}, ) for _, row := range cmcData.Data { @@ -130,10 +132,11 @@ func printTable(cmcData *CMCCoinData) error { changePercent30Day, _ := formatFloat(row.Quote.Usd.PercentChange30D, true, false, false) marketCapUSD, _ := formatFloat(row.Quote.Usd.MarketCap, false, true, false) maxSupply, _ := formatFloat(row.MaxSupply, false, true, false) + circulatingSupply, _ := formatFloat(row.CirculatingSupply, false, true, true) volume24Hr, _ := formatFloat(row.Quote.Usd.Volume24H, false, true, false) rank := strconv.FormatInt(int64(row.CmcRank), 10) - colorData := []string{rank, row.Name, row.Symbol, "$" + price, changePercent24Hr, vwap7DayString, changePercent30Day, "$" + marketCapUSD, maxSupply, volume24Hr} + colorData := []string{rank, row.Name, row.Symbol, "$" + price, changePercent24Hr, vwap7DayString, changePercent30Day, "$" + marketCapUSD, maxSupply, circulatingSupply, volume24Hr} table.Rich(colorData, []tablewriter.Colors{ {}, @@ -146,6 +149,7 @@ func printTable(cmcData *CMCCoinData) error { {tablewriter.Normal}, {tablewriter.Normal}, {tablewriter.Normal}, + {tablewriter.Normal}, }) } @@ -161,21 +165,21 @@ func printTotalMarketCap(coinData *GlobalMetrics) error { return nil } -// getCoinMarketCapAPI ... -func getCoinMarketCapAPI(target interface{}, argv *argT) error { +// makeCoinMarketCapRequest ... +func makeCoinMarketCapRequest(uri, httpMethod string, target interface{}, params map[string]string) error { apiKey, _ := os.LookupEnv("COINMARKETCAP_API_KEY") if apiKey != "" { client := &http.Client{} - req, err := http.NewRequest("GET", "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest", nil) + req, err := http.NewRequest(httpMethod, fmt.Sprintf("https://pro-api.coinmarketcap.com/v1/%s", uri), nil) if err != nil { log.Print(err) os.Exit(1) } q := url.Values{} - q.Add("start", "1") - q.Add("limit", argv.Top) - q.Add("convert", "USD") + for k, v := range params { + q.Add(k, v) + } req.Header.Set("Accepts", "application/json") req.Header.Add("X-CMC_PRO_API_KEY", apiKey) @@ -213,49 +217,35 @@ type GlobalMetrics struct { } `json:"data"` } -// getTotalMarketCap ... -func getTotalMarketCap(target interface{}) error { - apiKey, _ := os.LookupEnv("COINMARKETCAP_API_KEY") - if apiKey != "" { - client := &http.Client{} - req, err := http.NewRequest("GET", "https://pro-api.coinmarketcap.com/v1/global-metrics/quotes/latest", nil) - if err != nil { - log.Print(err) - os.Exit(1) - } - - req.Header.Set("Accepts", "application/json") - req.Header.Add("X-CMC_PRO_API_KEY", apiKey) - - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error sending request to server") - os.Exit(1) - } - defer resp.Body.Close() - - return json.NewDecoder(resp.Body).Decode(target) - } - - return nil -} - func main() { os.Exit(cli.Run(new(argT), func(ctx *cli.Context) error { now := time.Now() fmt.Printf("%s\n", now.Format("01-02-2006 15:04 PM Monday")) argv := ctx.Argv().(*argT) + var top string + if argv.Top != "" { + top = argv.Top + } else { + top = "10" + } + cmcData := new(CMCCoinData) - if err := getCoinMarketCapAPI(cmcData, argv); err != nil { + listingParams := map[string]string{ + "start": "1", + "limit": top, + "convert": "USD", + } + if err := makeCoinMarketCapRequest("cryptocurrency/listings/latest", "GET", cmcData, listingParams); err != nil { log.Panic(err) } + if err := printTable(cmcData); err != nil { log.Panic(err) } totalMarketCapCoinData := new(GlobalMetrics) - if err := getTotalMarketCap(totalMarketCapCoinData); err != nil { + if err := makeCoinMarketCapRequest("global-metrics/quotes/latest", "GET", totalMarketCapCoinData, nil); err != nil { log.Panic(err) } diff --git a/main_test.go b/main_test.go index 8f9f8ee..8616e75 100644 --- a/main_test.go +++ b/main_test.go @@ -156,56 +156,46 @@ func Test_printTotalMarketCap(t *testing.T) { } } -func Test_getCoinMarketCapAPI(t *testing.T) { +func Test_makeCoinMarketCapRequest(t *testing.T) { cli.Run(new(argT), func(ctx *cli.Context) error { type args struct { - target interface{} - argv *argT + uri string + httpMethod string + target interface{} + params map[string]string } argv := ctx.Argv().(*argT) cmcData := new(CMCCoinData) + coinData := new(GlobalMetrics) tests := []struct { name string args args wantErr bool }{ - {name: "getCoinMarketCapAPI", args: args{ - target: cmcData, - argv: argv, - }}, + {name: "Test makeCoinMarketCapRequest Top Ten Coins", args: args{ + uri: "cryptocurrency/listings/latest", + httpMethod: "GET", + target: cmcData, + params: map[string]string{ + "start": "1", + "limit": argv.Top, + "convert": "USD", + }, + }, wantErr: false}, + {name: "Test makeCoinMarketCapRequest Total Market Cap", args: args{ + uri: "global-metrics/quotes/latest", + httpMethod: "GET", + target: coinData, + params: nil, + }, wantErr: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := getCoinMarketCapAPI(tt.args.target, tt.args.argv); (err != nil) != tt.wantErr { - t.Errorf("getCoinMarketCapAPI() error = %v, wantErr %v", err, tt.wantErr) + if err := makeCoinMarketCapRequest(tt.args.uri, tt.args.httpMethod, tt.args.target, tt.args.params); (err != nil) != tt.wantErr { + t.Errorf("makeCoinMarketCapRequest() error = %v, wantErr %v", err, tt.wantErr) } }) } return nil }) } - -func Test_getTotalMarketCap(t *testing.T) { - type args struct { - target interface{} - } - rawReader := strings.NewReader(totalMarketCapJSON) - coinData := new(GlobalMetrics) - if err := json.NewDecoder(rawReader).Decode(coinData); err != nil { - t.Errorf("couldnt decode data: %v", err) - } - tests := []struct { - name string - args args - wantErr bool - }{ - {name: "getTotalMarketCap", args: args{target: coinData}}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := getTotalMarketCap(tt.args.target); (err != nil) != tt.wantErr { - t.Errorf("getTotalMarketCap() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -}