Skip to content

Commit

Permalink
fix output of cli
Browse files Browse the repository at this point in the history
- add test coverage for CLI tool
- move CLI commands into their own package

Signed-off-by: Steve Ellis <email@steveell.is>
  • Loading branch information
dimroc authored and se3000 committed Jan 10, 2018
1 parent 06ca9c2 commit 50e8bc0
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 69 deletions.
108 changes: 108 additions & 0 deletions commands/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package commands

import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"

"github.com/smartcontractkit/chainlink-go/logger"
"github.com/smartcontractkit/chainlink-go/services"
"github.com/smartcontractkit/chainlink-go/store"
"github.com/smartcontractkit/chainlink-go/store/models"
"github.com/smartcontractkit/chainlink-go/utils"
"github.com/smartcontractkit/chainlink-go/web"
"github.com/urfave/cli"
)

type Client struct {
io.Writer
}

func (self *Client) PrettyPrintJSON(v interface{}) error {
b, err := utils.FormatJSON(v)
if err != nil {
return err
}
if _, err = self.Write(b); err != nil {
return err
}
return nil
}

func (self *Client) cliError(err error) error {
if err != nil {
self.Write([]byte(err.Error()))
}
return err
}

func (self *Client) RunNode(c *cli.Context) error {
cl := services.NewApplication(store.NewConfig())
services.Authenticate(cl.Store)
r := web.Router(cl)

if err := cl.Start(); err != nil {
logger.Fatal(err)
}
defer cl.Stop()
logger.Fatal(r.Run())
return nil
}

func (self *Client) ShowJob(c *cli.Context) error {
cfg := store.NewConfig()
if !c.Args().Present() {
return self.cliError(fmt.Errorf("Must pass the job id to be shown"))
}
resp, err := utils.BasicAuthGet(
cfg.BasicAuthUsername,
cfg.BasicAuthPassword,
"http://localhost:8080/jobs/"+c.Args().First(),
)
if err != nil {
return self.cliError(err)
}
defer resp.Body.Close()
var job models.Job
err = deserializeResponse(resp, &job)
if err != nil {
return self.cliError(err)
}
return self.cliError(self.PrettyPrintJSON(job))
}

func deserializeResponse(resp *http.Response, dst interface{}) error {
if resp.StatusCode >= 300 {
return fmt.Errorf(resp.Status)
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
if err = json.Unmarshal(b, &dst); err != nil {
return err
}
return nil
}

func (self *Client) GetJobs(c *cli.Context) error {
cfg := store.NewConfig()
resp, err := utils.BasicAuthGet(
cfg.BasicAuthUsername,
cfg.BasicAuthPassword,
"http://localhost:8080/jobs",
)
if err != nil {
return self.cliError(err)
}
defer resp.Body.Close()

var jobs []models.Job
err = deserializeResponse(resp, &jobs)
if err != nil {
return self.cliError(err)
}
return self.cliError(self.PrettyPrintJSON(jobs))
}
43 changes: 43 additions & 0 deletions commands/commands_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package commands_test

import (
"flag"
"io/ioutil"
"testing"

"github.com/h2non/gock"
"github.com/smartcontractkit/chainlink-go/commands"
"github.com/smartcontractkit/chainlink-go/internal/cltest"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
)

func TestCommandShowJob(t *testing.T) {
defer cltest.CloseGock(t)
job := cltest.NewJob()
gock.New("http://localhost:8080").
Get("/jobs/" + job.ID).
Reply(200).
JSON(job)

client := commands.Client{ioutil.Discard}

set := flag.NewFlagSet("test", 0)
set.Parse([]string{job.ID})
c := cli.NewContext(nil, set, nil)
assert.Nil(t, client.ShowJob(c))
}

func TestCommandShowJobNotFound(t *testing.T) {
defer cltest.CloseGock(t)
gock.New("http://localhost:8080").
Get("/jobs/bogus-ID").
Reply(404)

client := commands.Client{ioutil.Discard}

set := flag.NewFlagSet("test", 0)
set.Parse([]string{"bogus-ID"})
c := cli.NewContext(nil, set, nil)
assert.NotNil(t, client.ShowJob(c))
}
66 changes: 5 additions & 61 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,91 +1,35 @@
package main

import (
"fmt"
"os"

"github.com/smartcontractkit/chainlink-go/logger"
"github.com/smartcontractkit/chainlink-go/services"
"github.com/smartcontractkit/chainlink-go/store"
"github.com/smartcontractkit/chainlink-go/utils"
"github.com/smartcontractkit/chainlink-go/web"
"github.com/smartcontractkit/chainlink-go/commands"
"github.com/urfave/cli"
)

func main() {
client := commands.Client{os.Stdout}
app := cli.NewApp()
app.Usage = "CLI for Chainlink"
app.Commands = []cli.Command{
{
Name: "node",
Aliases: []string{"n"},
Usage: "Run the chainlink node",
Action: runNode,
Action: client.RunNode,
},
{
Name: "jobs",
Aliases: []string{"j"},
Usage: "Get all jobs",
Action: getJobs,
Action: client.GetJobs,
},
{
Name: "show",
Aliases: []string{"s"},
Usage: "Show a specific job",
Action: showJob,
Action: client.ShowJob,
},
}
app.Run(os.Args)
}

func cliError(err error) error {
if err != nil {
fmt.Printf(err.Error())
}
return err
}

func runNode(c *cli.Context) error {
cl := services.NewApplication(store.NewConfig())
services.Authenticate(cl.Store)
r := web.Router(cl)

if err := cl.Start(); err != nil {
logger.Fatal(err)
}
defer cl.Stop()
logger.Fatal(r.Run())
return nil
}

func getJobs(c *cli.Context) error {
cfg := store.NewConfig()
resp, err := utils.BasicAuthGet(
cfg.BasicAuthUsername,
cfg.BasicAuthPassword,
"http://localhost:8080/jobs",
)
if err != nil {
return cliError(err)
}
defer resp.Body.Close()
return cliError(utils.PrettyPrintJSON(resp.Body))
}

func showJob(c *cli.Context) error {
cfg := store.NewConfig()
if !c.Args().Present() {
fmt.Println("Must pass the job id to be shown")
return nil
}
resp, err := utils.BasicAuthGet(
cfg.BasicAuthUsername,
cfg.BasicAuthPassword,
"http://localhost:8080/jobs/"+c.Args().First(),
)
if err != nil {
return cliError(err)
}
defer resp.Body.Close()
return cliError(utils.PrettyPrintJSON(resp.Body))
}
10 changes: 2 additions & 8 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"log"
"math/big"
"net/http"
"os"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -97,11 +96,6 @@ func BasicAuthGet(username, password, url string) (*http.Response, error) {
return resp, err
}

func PrettyPrintJSON(v interface{}) error {
b, err := json.MarshalIndent(v, "", " ")
if err != nil {
return err
}
_, err = os.Stdout.Write(b)
return err
func FormatJSON(v interface{}) ([]byte, error) {
return json.MarshalIndent(v, "", " ")
}

0 comments on commit 50e8bc0

Please sign in to comment.