Skip to content
This repository has been archived by the owner on Jul 14, 2022. It is now read-only.

Commit

Permalink
✨ API Doc Generation (#23)
Browse files Browse the repository at this point in the history
* Add `gen` command and basic FE

* Add Headers and RawParams and Auth in FE

* Minor Updates

* 🔥 Moved the whole to markdown and docsify

* 📝 Add autobrowser open and Updated Readme

* Final Touches for Stuffing and deployment

Co-authored-by: Joice M. Joseph <joice@moolekkari.net>

* Minor Refactor to Code and Docs

* meaningful name for fstructm, renamed to FileTrunk. removed named variable definition in FileTrunk

* Add Flag for Auto Browser Open

* 📝 Updated Docs on Broswer Flag

Co-authored-by: Joice M. Joseph <joice@moolekkari.net>
  • Loading branch information
athul and joicemjoseph authored Nov 26, 2020
1 parent f1b75a1 commit 7bc2111
Show file tree
Hide file tree
Showing 12 changed files with 429 additions and 40 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
*.so
*.dylib
hopp-cli
hoop.bin
dist/

# Test binary, built with `go test -c`
*.test
Expand Down
14 changes: 5 additions & 9 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
before:
hooks:
# you may remove this if you don't use vgo
- go mod tidy
# you may remove this if you don't need go generate
- go get -v
env:
- RELEASE_BUILDS=dist/hopp-cli_darwin_amd64/hopp-cli dist/hopp-cli_linux_386/hopp-cli dist/hopp-cli_linux_amd64/hopp-cli dist/hopp-cli_windows_386/hopp-cli.exe dist/hopp-cli_windows_amd64/hopp-cli.exe
builds:
- env:
- CGO_ENABLED=0
ldflags:
- -s -w -X main.VERSION={{.Version}}
- -s -w -X main.buildVersion={{.Version}}
goos:
- darwin
- linux
- windows
goarch:
- 386
- amd64
hooks:
post: make pack-releases
ignore:
- goos: darwin
goarch: 386
Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
BIN:=hopp.bin
PREFIX?=/usr/local
BINDIR?=$(PREFIX)/bin
VERSION?=$(shell git tag | grep ^v | sort -V | tail -n 1)
GOFLAGS?=-ldflags '-X main.VERSION=${VERSION}'
STATIC := ./templates/index.html ./templates/template.md:/template.md

hopp-cli: cli.go go.mod go.sum
deps:
go get -u github.com/knadh/stuffbin/...

build: cli.go go.mod go.sum
@echo
@echo Building hopp-cli. This may take a minute or two.
@echo
go build $(GOFLAGS) -o $@
go build -o ${BIN} -ldflags="-s -w -X 'main.buildVersion=${VERSION}'" *.go
stuffbin -a stuff -in ${BIN} -out ${BIN} ${STATIC}
@echo
@echo ...Done\!

Expand Down Expand Up @@ -46,3 +51,6 @@ uninstall:
rm -f $(BINDIR)/hopp-cli
@echo
@echo ...Done\!
.PHONY: pack-releases
pack-releases:
$(foreach var,$(RELEASE_BUILDS),stuffbin -a stuff -in ${var} -out ${var} ${STATIC};)
86 changes: 60 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Hoppscotch CLI [![hoppscotch](https://img.shields.io/badge/Made_for-Hoppscotch-hex_color_code?logo=Postwoman)](https://hoppscotch.io) [![Go Report Card](https://goreportcard.com/badge/github.com/athul/pwcli)](https://goreportcard.com/report/github.com/athul/pwcli)
# Hoppscotch CLI [![hoppscotch](https://img.shields.io/badge/Made_for-Hoppscotch-hex_color_code?logo=Postwoman)](https://hoppscotch.io) [![Go Report Card](https://goreportcard.com/badge/github.com/athul/pwcli)](https://goreportcard.com/report/github.com/athul/pwcli)

Send HTTP requests from terminal. An alternative to cURL, httpie ⚡️
Send HTTP requests from terminal and Generate API Docs. An alternative to cURL, httpie ⚡️

# Installation
## Installation

### From Script

Expand Down Expand Up @@ -34,46 +34,80 @@ $ sudo make install
- Mac(x64)
- Windows(x64,x86)

> **IMPORTANT: Not tested on Windows, please leave your feedback/bugs in the Issues section**
### Homebrew

Install by `brew install athul/tap/hopp-cli`

> **IMPORTANT: Not tested on Windows, please leave your feedback/bugs in the Issues section**
# Usages
## Usages

Putting Simply: **Just pass the URL to the request method**
## Basic
- GET : `hopp-cli get <url> `
- POST: `hopp-cli post <url> `
- PATCH: `hopp-cli patch <url>`
- PUT : `hopp-cli put <url>`
- DELETE: `hopp-cli delete <url>`

Example for a POST request:
`hopp-cli post https://reqres.in/api/users/2 -c js -b '{"name": "morp","job": "zion resident"}`
### Basic Commands

- GET : `$ hopp-cli get <url> `
- POST: `$ hopp-cli post <url> `
- PATCH: `$ hopp-cli patch <url>`
- PUT : `$ hopp-cli put <url>`
- DELETE: `$ hopp-cli delete <url>`

Example for a POST request:

```shell
$ hopp-cli post https://reqres.in/api/users/2 -c js -b '{"name": "morp","job": "zion resident"}'

```

### Extra Commands

- `send` for testing multiple endpoints
- `gen` for generating API docs from Collection

**SEND**: This can be used to test multiple endpoints from the `hoppscotch-collection.json` file.

### Extra
> The output will only be the `statuscode`
**SEND**: This can be used to test multiple endpoints from the `hoppscotch-collection.json` file. The output will only be the `statuscode`.
Example : `hopp-cli send <PATH to hoppscotch collection.json>`
o/p:

Sample Output:
![](/assets/send.png)

---

**GEN**: Gen command Generates the API Documentation from `hoppscotch-collection.json` file and serves it as a Static Page on port `1341`
Example: `hopp-cli gen <PATH to hoppscotch collection.json>`

Sample Hosted site: https://hopp-docsify.surge.sh/

Powered by [Doscify](https://docsify.js.org)

Flags:

- `browser` or `b` to toggle whether the browser should open automatically [Boolean]
- `port` or `p` for specifying the port where the server should listen to [Integer]

### There are 3 Authentication Flags
*(optional)*

_(optional)_

- `-t` or `--token` for a Bearer Token for Authentication
- `-u` for the `Username` in Basic Auth
- `-p` for the `password` in Basic Auth

### There are 2 flags especially for the data management requests like POST,PUT,PATCH and DELETE
- `-c` or `--ctype` for the *Content Type*

- `-b` or `--body` for the Data Body, this can be of json, html or plain text based on the request.
> Enclose the body in Single Quotes(\')
- `-c` or `--ctype` for the _Content Type_

- `-b` or `--body` for the Data Body, this can be of json, html or plain text based on the request.

> Enclose the body in Single Quotes(\')
**Content Types can be of**

**Content Types can be of**
`html` : `text/html`
`js` : `application/json`
`xml` : `application/xml`
`plain` : `text/plain`
|Short Code|Content Type|
|:---:|:---:|
|`js`|`application/json`|
|`html`|`text/html`|
|`xml`|`application/xml`|
|`plain`|`text/plain`|
Binary file modified assets/send.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 24 additions & 2 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import (
)

// VERSION is set by `make` during the build to the most recent tag
var VERSION = ""
var buildVersion = "unknown"

func main() {
app := cli.NewApp()
app.Name = color.HiGreenString("Hoppscotch CLI")
app.Version = color.HiRedString(VERSION)
app.Version = color.HiRedString(buildVersion)
app.Usage = color.HiYellowString("Test API endpoints without the hassle")
app.Description = color.HiBlueString("Made with <3 by Hoppscotch Team")

Expand All @@ -36,6 +36,17 @@ func main() {
Usage: "Add the Password",
},
}
genFlags := []cli.Flag{
cli.IntFlag{
Name: "port, p",
Usage: "Port at which the server will open to",
Value: 1341,
},
cli.BoolFlag{
Name: "browser, b",
Usage: "Whether to open the browser automatically",
},
}
postFlags := []cli.Flag{
cli.StringFlag{
Name: "token, t",
Expand Down Expand Up @@ -124,6 +135,17 @@ func main() {
return nil
},
},
{
Name: "gen",
Usage: "Generate Documentation from the Hoppscotch Collection.json",
Flags: genFlags,
Action: func(c *cli.Context) error {
if err := mets.GenerateDocs(c); err != nil {
return err
}
return nil
},
},
}
cli.AppHelpTemplate = fmt.Sprintf(`%s
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ go 1.13

require (
github.com/fatih/color v1.9.0
github.com/knadh/stuffbin v1.1.0
github.com/olekukonko/tablewriter v0.0.4
github.com/pkg/browser v0.0.0-20201112035734-206646e67786
github.com/stretchr/testify v1.4.0 // indirect
github.com/tidwall/pretty v1.0.1
github.com/urfave/cli v1.22.2
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ 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/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/knadh/stuffbin v1.1.0 h1:f5S5BHzZALjuJEgTIOMC9NidEnBJM7Ze6Lu1GHR/lwU=
github.com/knadh/stuffbin v1.1.0/go.mod h1:yVCFaWaKPubSNibBsTAJ939q2ABHudJQxRWZWV5yh+4=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand All @@ -24,6 +26,8 @@ github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+tw
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/pkg/browser v0.0.0-20201112035734-206646e67786 h1:4Gk0Dsp90g2YwfsxDOjvkEIgKGh+2R9FlvormRycveA=
github.com/pkg/browser v0.0.0-20201112035734-206646e67786/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down
91 changes: 91 additions & 0 deletions methods/docs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package methods

import (
"bytes"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"

"github.com/knadh/stuffbin"
"github.com/pkg/browser"
"github.com/urfave/cli"
)

//FileTrunk handles the buffer for generated README.md File
type FileTrunk struct{ bytes.Buffer }

// Name holds the FileName, here README.md
func (f *FileTrunk) Name() string { return "README.md" }

// Size holds the size of the File
func (f *FileTrunk) Size() int64 { return int64(f.Len()) }

// Mode holds the file Mode
func (f *FileTrunk) Mode() os.FileMode { return 0755 }

// ModTime holds creation time of File
func (f *FileTrunk) ModTime() time.Time { return time.Now() }

// IsDir checks if True
func (f *FileTrunk) IsDir() bool { return false }

// Sys - I have no idea
func (f *FileTrunk) Sys() interface{} { return nil }

//GenerateDocs generates the Documentation site from the hoppscotch-collection.json
func GenerateDocs(c *cli.Context) error {
execPath, err := os.Executable() //get Executable Path for StuffBin
if err != nil {
return err
}
fs, err := initFileSystem(execPath) //Init Virtual FS
if err != nil {
return err
}

colls, err := ReadCollection(c.Args().Get(0))
if err != nil {
return err
}
// FuncMap for the HTML template
fmap := map[string]interface{}{
"html": func(val string) string { return val },
}

t, err := stuffbin.ParseTemplates(fmap, fs, "/template.md")

// f will be used to store rendered templates in memory.
var f FileTrunk

// Execute the template to the file.
if err = t.Execute(&f, colls); err != nil {
return err
}

if err := fs.Add(stuffbin.NewFile("/README.md", &f, f.Bytes())); err != nil {
return err
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
out, err := fs.Read("templates/index.html")
if err != nil {
log.Println(err)
}
w.Write(out)
})
PortStr := ":" + strconv.Itoa(c.Int("port"))
URL := fmt.Sprintf("http://localhost%s", PortStr)

http.Handle("/static/", http.StripPrefix("/static/", fs.FileServer()))

log.Printf("\033[1;36mServer Listening at %s\033[0m", URL)

if !c.Bool("browser") { //Check if User wants to open the Broswer
browser.OpenURL(URL) // AutoOpen the Broswer
}

http.ListenAndServe(PortStr, nil)
return nil
}
32 changes: 32 additions & 0 deletions methods/fs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package methods

import (
"log"

"github.com/knadh/stuffbin"
)

func initFileSystem(binPath string) (stuffbin.FileSystem, error) {
fs, err := stuffbin.UnStuff(binPath)
// If files are not stuffed with the binary,
// try to pick up files from local file system.
if err == stuffbin.ErrNoID {
// Running in local mode. Load the required static assets into
// the in-memory stuffbin.FileSystem.

files := []string{
"./templates/index.html",
"./templates/template.md:/template.md",
}

// mutates err object.
fs, err = stuffbin.NewLocalFS("/", files...)
if err != nil {
log.Println("Error in Virtual FS", err)
}
}

// Either unstuff or NewLocalFS throws error,
// mutated error value will be returned
return fs, err
}
Loading

0 comments on commit 7bc2111

Please sign in to comment.