diff --git a/README.md b/README.md index c588e48..f57f901 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Use Postwoman's CLI direct from your terminal. # Installation ### From Script ```bash -$ sh -c "$(curl -sL https://git.io/getwcli)" +$ sh -c "$(curl -sL https://git.io/getpwcli)" ``` ### From Source - Clone the repo diff --git a/cli.go b/cli.go index de5ad11..550d1c7 100644 --- a/cli.go +++ b/cli.go @@ -45,8 +45,7 @@ func main() { Usage: "Add the Password", }, cli.StringFlag{ - Name: "ctype, c", - //Value: "application/json", + Name: "ctype, c", //Content Type Flag Usage: "Change the Content Type", }, cli.StringFlag{ @@ -54,21 +53,13 @@ func main() { Usage: "Body of the Post Request", }, } - /* sendFlag := []cli.Flag{ - cli.StringFlag{ - Name: "pt", - Usage: "The Path of Postwoman Collection.json", - Required: true, - }, - } */ app.Commands = []cli.Command{ { Name: "get", Usage: "Send a GET request", Flags: getFlags, Action: func(c *cli.Context) error { - mets.Getbasic(c) - return nil + return mets.Getbasic(c) }, }, { @@ -76,8 +67,7 @@ func main() { Usage: "Send a POST Request", Flags: postFlags, Action: func(c *cli.Context) error { - mets.Postbasic(c) - return nil + return mets.Postbasic(c) }, }, { @@ -85,8 +75,7 @@ func main() { Usage: "Send a PUT Request", Flags: postFlags, Action: func(c *cli.Context) error { - mets.Putbasic(c) - return nil + return mets.Putbasic(c) }, }, { @@ -94,8 +83,7 @@ func main() { Usage: "Send a PATCH Request", Flags: postFlags, Action: func(c *cli.Context) error { - mets.Patchbasic(c) - return nil + return mets.Patchbasic(c) }, }, { @@ -103,17 +91,14 @@ func main() { Usage: "Send a DELETE Request", Flags: postFlags, Action: func(c *cli.Context) error { - mets.Deletebasic(c) - return nil + return mets.Deletebasic(c) }, }, { Name: "send", Usage: "Test all the Endpoints in the Postwoman Collection.json", - //Flags: sendFlag, Action: func(c *cli.Context) error { - mets.ReadCollection(c) - return nil + return mets.ReadCollection(c) }, }, } @@ -122,10 +107,12 @@ func main() { WE REALLY NEED YOUR FEEDBACK, CREATE A NEW ISSUE FOR BUGS AND FEATURE REQUESTS : < http://github.com/athul/pwcli > + `, cli.AppHelpTemplate) err := app.Run(os.Args) if err != nil { - log.Fatal(err) + l := log.New(os.Stderr, "", 0) + l.Println(color.HiRedString("\n%s", err.Error())) } } diff --git a/go.mod b/go.mod index 555bbbe..c11abe2 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/athul/pwcli go 1.13 require ( - github.com/TylerBrock/colorjson v0.0.0-20180527164720-95ec53f28296 github.com/fatih/color v1.9.0 - github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e // indirect + github.com/stretchr/testify v1.4.0 // indirect + github.com/tidwall/pretty v1.0.1 github.com/urfave/cli v1.22.2 github.com/yosssi/gohtml v0.0.0-20190915184251-7ff6f235ecaf golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect diff --git a/go.sum b/go.sum index e2b18d7..ff7e37e 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/TylerBrock/colorjson v0.0.0-20180527164720-95ec53f28296 h1:JYWTroLXcNzSCgu66NMgdjwoMHQRbv2SoOVNFb4kRkE= -github.com/TylerBrock/colorjson v0.0.0-20180527164720-95ec53f28296/go.mod h1:VSw57q4QFiWDbRnjdX8Cb3Ow0SFncRw+bA/ofY6Q83w= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e h1:0aewS5NTyxftZHSnFaJmWE5oCCrj4DyEXkAiMa1iZJM= -github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -18,6 +16,11 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8= +github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/yosssi/gohtml v0.0.0-20190915184251-7ff6f235ecaf h1:VA200mPTYh9FWY8zKX5ctXCtNk78HUez8ecTdsQGhoo= @@ -30,5 +33,7 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/methods/delete.go b/methods/delete.go index c54ae16..ef25a38 100644 --- a/methods/delete.go +++ b/methods/delete.go @@ -12,8 +12,7 @@ import ( func Deletebasic(c *cli.Context) error { url, err := checkURL(c.Args().Get(0)) if err != nil { - fmt.Printf("%s\n", err.Error()) - return nil + return fmt.Errorf("URL validation error: %s", err.Error()) } var jsonStr = []byte(c.String("body")) req, err := http.NewRequest("DELETE", url, bytes.NewBuffer(jsonStr)) @@ -31,10 +30,15 @@ func Deletebasic(c *cli.Context) error { client := &http.Client{} resp, err := client.Do(req) if err != nil { - panic(err) + return fmt.Errorf("Request error: %s", err.Error()) } - //defer resp.Body.Close() - s := formatresp(resp) + defer resp.Body.Close() + + s, err := formatresp(resp) + if err != nil { + return err + } + fmt.Println(s) return nil } diff --git a/methods/fns.go b/methods/fns.go index 5cdde46..bc4d4a7 100644 --- a/methods/fns.go +++ b/methods/fns.go @@ -2,56 +2,44 @@ package methods import ( "encoding/base64" - "encoding/json" "fmt" "io/ioutil" - "log" "net/http" "strings" - "github.com/TylerBrock/colorjson" "github.com/fatih/color" + "github.com/tidwall/pretty" "github.com/yosssi/gohtml" ) // Formatresp formats the Response with Indents and Colors -func formatresp(resp *http.Response) string { +func formatresp(resp *http.Response) (string, error) { var retbody string heads := fmt.Sprint(resp.Header) - c := color.New(color.FgCyan, color.Bold) + c := color.New(color.FgHiCyan) magenta := color.New(color.FgHiMagenta) - yellow := color.New(color.FgHiYellow) + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("Error reading response body: %s", err.Error()) + } + for key, value := range resp.Header { + c.Print(key, " : ") + magenta.Print(value, "\n") + } str := string(body) if strings.Contains(heads, "json") { - var obj map[string]interface{} - json.Unmarshal([]byte(str), &obj) - f := colorjson.NewFormatter() - f.Indent = 6 - s, _ := f.Marshal(obj) - for key, value := range resp.Header { - c.Print(key, " : ") - magenta.Print(value, "\n") - } - retbody = yellow.Sprintf("\nStatus:\t\t%s\n\nStatusCode:\t%d\n", resp.Status, resp.StatusCode) + fmt.Sprintf("\n%s\n", string(s)) + retbody = color.HiYellowString("\nStatus:\t\t%s\n\nStatusCode:\t%d\n", resp.Status, resp.StatusCode) + fmt.Sprintf("\n%s\n", string(pretty.Color(pretty.Pretty(body), nil))) } else if strings.Contains(heads, "xml") || strings.Contains(heads, "html") || strings.Contains(heads, "plain") { - for key, value := range resp.Header { - c.Print(key, " : ") - magenta.Print(value, "\n") + var s string + if strings.Contains(heads, "plain") { + s = str + } else { + s = c.Sprint(gohtml.Format(str)) } - var s string - if strings.Contains(heads, "plain") { - s = str - } else { - s = c.Sprint(gohtml.Format(str)) - } - retbody = yellow.Sprintf("\nStatus:\t\t%s\n\nStatusCode:\t%d\n", resp.Status, resp.StatusCode) + fmt.Sprintf("\n%s\n", s) - - } - if err != nil { - log.Println("Error on response.\n[ERRO] -", err) + retbody = color.HiYellowString("\nStatus:\t\t%s\n\nStatusCode:\t%d\n", resp.Status, resp.StatusCode) + fmt.Sprintf("\n%s\n", s) } - return retbody + return retbody, nil } func basicAuth(username, password string) string { diff --git a/methods/get.go b/methods/get.go index d3f97ca..84235d5 100644 --- a/methods/get.go +++ b/methods/get.go @@ -2,25 +2,20 @@ package methods import ( "fmt" - "log" "net/http" - "os" - "github.com/fatih/color" "github.com/urfave/cli" ) //Getbasic sends a simple GET request to the url with any potential parameters like Tokens or Basic Auth -func Getbasic(c *cli.Context) { +func Getbasic(c *cli.Context) error { var url, err = checkURL(c.Args().Get(0)) if err != nil { - fmt.Printf("%s\n", err.Error()) - os.Exit(0) + return err } req, err := http.NewRequest("GET", url, nil) if err != nil { - log.Println("Error on Request.\nDid you give a correct URL? Try giving that") - os.Exit(0) + return fmt.Errorf("Error creating request: %s", err.Error()) } if c.String("token") != "" { var bearer = "Bearer " + c.String("token") @@ -34,10 +29,15 @@ func Getbasic(c *cli.Context) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - log.Println(color.RedString("Error on response.\nDid you give a correct URL? Try giving that")) + return fmt.Errorf("Error sending request: %s", err.Error()) } + defer resp.Body.Close() - s := formatresp(resp) - fmt.Println(s) + s, err := formatresp(resp) + if err != nil { + return err + } + fmt.Println(s) + return nil } diff --git a/methods/patch.go b/methods/patch.go index e4f62de..b73436c 100644 --- a/methods/patch.go +++ b/methods/patch.go @@ -4,17 +4,15 @@ import ( "bytes" "fmt" "net/http" - "os" "github.com/urfave/cli" ) //Patchbasic sends a basic PATCH request -func Patchbasic(c *cli.Context) { +func Patchbasic(c *cli.Context) error { url, err := checkURL(c.Args().Get(0)) if err != nil { - fmt.Printf("%s\n", err.Error()) - os.Exit(0) + return err } var jsonStr = []byte(c.String("body")) req, err := http.NewRequest("PATCH", url, bytes.NewBuffer(jsonStr)) @@ -32,10 +30,15 @@ func Patchbasic(c *cli.Context) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - panic(err) + return fmt.Errorf("Error sending request: %s", err.Error()) } - //defer resp.Body.Close() - s := formatresp(resp) - fmt.Println(s) + defer resp.Body.Close() + s, err := formatresp(resp) + if err != nil { + return err + } + + fmt.Println(s) + return nil } diff --git a/methods/post.go b/methods/post.go index 7fbde1e..d80908f 100644 --- a/methods/post.go +++ b/methods/post.go @@ -4,17 +4,15 @@ import ( "bytes" "fmt" "net/http" - "os" "github.com/urfave/cli" ) //Postbasic sends a basic POST request -func Postbasic(c *cli.Context) { +func Postbasic(c *cli.Context) error { url, err := checkURL(c.Args().Get(0)) if err != nil { - fmt.Printf("%s\n", err.Error()) - os.Exit(0) + return err } var jsonStr = []byte(c.String("body")) req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) @@ -34,9 +32,14 @@ func Postbasic(c *cli.Context) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - panic(err) + return fmt.Errorf("Error sending request: %s", err.Error()) + } + defer resp.Body.Close() + + s, err := formatresp(resp) + if err != nil { + return err } - //defer resp.Body.Close() - s := formatresp(resp) fmt.Println(s) + return nil } diff --git a/methods/put.go b/methods/put.go index f11c993..9fddf08 100644 --- a/methods/put.go +++ b/methods/put.go @@ -12,8 +12,7 @@ import ( func Putbasic(c *cli.Context) error { url, err := checkURL(c.Args().Get(0)) if err != nil { - fmt.Printf("%s\n", err.Error()) - return nil + return err } var jsonStr = []byte(c.String("body")) req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonStr)) @@ -31,10 +30,15 @@ func Putbasic(c *cli.Context) error { client := &http.Client{} resp, err := client.Do(req) if err != nil { - panic(err) + return fmt.Errorf("Error sending request: %s", err.Error()) } - //defer resp.Body.Close() - s := formatresp(resp) + defer resp.Body.Close() + + s, err := formatresp(resp) + if err != nil { + return err + } + fmt.Println(s) return nil } diff --git a/methods/send.go b/methods/send.go index 12adaae..56b6918 100644 --- a/methods/send.go +++ b/methods/send.go @@ -5,9 +5,7 @@ import ( "encoding/json" "fmt" "io/ioutil" - "log" "net/http" - "os" "github.com/fatih/color" "github.com/urfave/cli" @@ -43,25 +41,27 @@ type Bpardata struct { } //ReadCollection reads the PostWoman Collection Json File and does the Magic Stuff -func ReadCollection(c *cli.Context) { +func ReadCollection(c *cli.Context) error { data, err := ioutil.ReadFile(c.Args().Get(0)) if string(data) == "" { - fmt.Print("PATH is needed") - os.Exit(0) + return fmt.Errorf("PATH is needed") } if err != nil { - fmt.Print(err) + return err } var jsondat []Colls err = json.Unmarshal([]byte(data), &jsondat) if err != nil { - fmt.Println(err) + return fmt.Errorf("Error parsing JSON: %s", err.Error()) } fmt.Println("Name:\t" + color.HiMagentaString(jsondat[0].Name)) for i := 0; i < len(jsondat[0].Request); i++ { - request(jsondat, i) + err := request(jsondat, i) + if err != nil { + return err + } } - + return nil } func request(c []Colls, i int) error { colors := color.New(color.FgHiRed, color.Bold) @@ -73,14 +73,14 @@ func request(c []Colls, i int) error { if c[0].Request[i].Method == "GET" { out, err := getsend(c, i, "GET") if err != nil { - fmt.Print(err) + return err } methods := color.HiYellowString(c[0].Request[i].Method) fmt.Printf("%s |\t%s |\t%s |\t%s", color.HiGreenString(c[0].Request[i].Name), fURL, methods, out) } else { out, err := sendpopa(c, i, c[0].Request[i].Method) if err != nil { - fmt.Print(err) + return err } methods := color.HiYellowString(c[0].Request[i].Method) fURL := colors.Sprintf(c[0].Request[i].URL + c[0].Request[i].Path) @@ -94,7 +94,7 @@ func getsend(c []Colls, ind int, method string) (string, error) { //fmt.Print(url + " ") req, err := http.NewRequest(method, url, nil) if err != nil { - return "", err + return "", fmt.Errorf("Error creating request: %s", err.Error()) } if c[0].Request[ind].Token != "" { var bearer = "Bearer " + c[0].Request[ind].Token @@ -108,9 +108,9 @@ func getsend(c []Colls, ind int, method string) (string, error) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - log.Println("Error on response.\n[ERRO] -", err) + return "", fmt.Errorf("Error sending request: %s", err.Error()) } - //defer resp.Body.Close() + defer resp.Body.Close() //fmt.Print(resp.Header) s := color.Sprintf("Status: %s\tStatusCode:\t%d\n", resp.Status, resp.StatusCode) return s, nil @@ -127,10 +127,10 @@ func sendpopa(c []Colls, ind int, method string) (string, error) { } req, err := http.NewRequest(method, url, bytes.NewBuffer(jsonStr)) - req.Header.Set("Content-Type", c[0].Request[ind].Ctype) if err != nil { - return "", err + return "", fmt.Errorf("Error creating request: %s", err.Error()) } + req.Header.Set("Content-Type", c[0].Request[ind].Ctype) if c[0].Request[ind].Token != "" { var bearer = "Bearer " + c[0].Request[ind].Token req.Header.Add("Authorization", bearer) @@ -143,9 +143,9 @@ func sendpopa(c []Colls, ind int, method string) (string, error) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - log.Println("Error on response.\n[ERRO] -", err) + return "", fmt.Errorf("Error sending request: %s", err.Error()) } - //defer resp.Body.Close() + defer resp.Body.Close() //fmt.Print(resp.Header) s := color.Sprintf("Status: %s\tStatusCode:\t%d\n", resp.Status, resp.StatusCode) return s, nil