How to create a CLI program in Go and host it on npm

Search for a command to run...

No comments yet. Be the first to comment.
Let's jump into it... fast. You got here because you want to setup Dokku and the other ways don't work... let's goooo I will setup for Dokku only Point your domain to the VPS of choice Spin up new VPS server here: Digital Ocean Linode Buy a dom...

So what is Dokku, another bit, another TL;DR; Let's jump into it. You might know Heroku, (my opinion) the greatest platform to ever make it easy to deploy server and client-side applications so fast and easy. Well Heroku is a business and they have t...

Okay for this one I highly recommend, the speeds is just amazing. I loved it. I am gonna do a comparison real quick, between browser-image-compression and react-image-file-resizer. browser-image-compressionreact-image-file-resizer Really fastCo...

I recently got interested in compressing images on the client-side for a couple of reasons: Reduce my cloudinary bandwidth and storage usage Users were complaining about long waits while uploading images So I ventured to look for a library that wil...

Recently I started building tools that will help me automate my app deployment process easier and cheaper, to do that I knew CLIs are definitely going to be involved one way or another. So I started building two CLIs:
Both CLIs were built with Golang but only one is hosted on npm here, this tutorial will guide you on how you can do the same.
Note: Am still new to Go
Let's jump into it
We are going to create a CLI that serves a directory over a HTTP server.
Create a new folder inside
$GOPATH/src/<github.com|gitea.com|gitlab.com|bitbucket.com>/<username>/html-server-cli
Next, we will create our go.mod file to track packages we are going to use
go mod init
I have my directory setup as below:
.
+-- cli
+-- cli.go
+-- helpers
+-- helpers.go
+-- server
+-- server.go
+-- go.mod
+-- go.sum
+-- html-server.go
Let add some code to our helpers/helpers.go
package helpers
import (
"math/rand"
"time"
)
// GeneratePortNumber handle generating port number
func GeneratePortNumber() int {
rand.Seed(time.Now().UnixNano())
min := 1000
max := 99999
port := rand.Intn(max-min+1) + min
return port
}
The block of code above enables us to generate a random port number, you can add more logic to see if a port is used.
Next, let's add some code to our server/server.go
package server
import (
"log"
"net/http"
"strconv"
"github.com/bywachira/html-server/helpers"
)
// Serve handles serving the directory
func Serve() {
// Generate our port number
port := helpers.GeneratePortNumber()
// Inform the user which port we are running
log.Println("We are running on port: " + strconv.Itoa(port))
// Exit to a live server
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(port), http.FileServer(http.Dir("."))))
}
Let's create a method to initialize our CLI
package cli
import (
"fmt"
"sort"
"github.com/bywachira/html-server/server"
"github.com/urfave/cli/v2"
)
// SetupCLI initialize cli
func SetupCLI() *cli.App {
app := &cli.App{
// List your commands here
Commands: []*cli.Command{
{
// Provide details about our cli flags
Name: "run",
Aliases: []string{"r"},
Usage: "Serve your HTML file",
Action: func(c *cli.Context) error {
// The logic to be called when this commad is ran
fmt.Println("We are serving this directory")
server.Serve()
return nil
},
},
},
}
sort.Sort(cli.FlagsByName(app.Flags))
sort.Sort(cli.CommandsByName(app.Commands))
// Return our cli
return app
}
Let's update our package main, which is html-server.go
package main
import (
"log"
"os"
"github.com/bywachira/html-server/cli"
)
func main() {
// Assign our cli to the app variable
app := cli.SetupCLI()
err := app.Run(os.Args)
// Exit program when we get an error and show error
if err != nil {
log.Fatal("Error: ", err)
}
}
Note: You don't have to use
github.com/urfave/cli/v2package by default, you can use whatever package you want because all we need to publish is the binary file.
Click here to continue reading this part
goreleaser to .gitignore fileI have web monetization enabled so you can support my work or give me feedback on this article on what I should improve on.