Go: Bahasa Terbaik untuk CLI Tools
Go sudah menjadi bahasa pilihan untuk CLI tools Docker, Kubernetes, Terraform, Hugo, dan ribuan tools lainnya dibuat dengan Go. Kenapa? Binary standalone, cross-compile mudah, dan startup time instant.
Saya sendiri sudah build beberapa CLI tools untuk automasi workflow: database migration runner, deployment helper, dan code generator.
Setup dengan Cobra
Cobra adalah library CLI paling populer di Go. Hampir semua major Go CLI tool menggunakannya.
package main
import (
"fmt"
"os"
"github.com/spf13/cobra"
)
var rootCmd = &cobra.Command{
Use: "mytool",
Short: "My awesome CLI tool",
Long: `A CLI tool for managing my SaaS application.`,
}
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start the server",
Run: func(cmd *cobra.Command, args []string) {
port, _ := cmd.Flags().GetInt("port")
fmt.Printf("Starting server on port %d...\n", port)
},
}
var migrateCmd = &cobra.Command{
Use: "migrate",
Short: "Run database migrations",
Run: func(cmd *cobra.Command, args []string) {
direction, _ := cmd.Flags().GetString("direction")
fmt.Printf("Running %s migrations...\n", direction)
},
}
func init() {
serveCmd.Flags().IntP("port", "p", 8080, "Server port")
migrateCmd.Flags().StringP("direction", "d", "up", "Migration direction")
rootCmd.AddCommand(serveCmd)
rootCmd.AddCommand(migrateCmd)
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
Interactive Prompts
import "github.com/AlecAivazis/survey/v2"
func initProject() {
var answers struct {
Name string
DBType string
Port int
}
questions := []*survey.Question{
{Name: "name", Prompt: &survey.Input{Message: "Project name:"},
Validate: survey.Required},
{Name: "dbtype", Prompt: &survey.Select{Message: "Database type:",
Options: []string{"PostgreSQL", "MySQL", "SQLite"}},
{Name: "port", Prompt: &survey.Input{Message: "Server port:", Default: "8080"}},
}
survey.Ask(questions, &answers)
fmt.Printf("Creating project: %s with %s on port %d\n",
answers.Name, answers.DBType, answers.Port)
}
Cross-Compilation
# Build untuk Linux
GOOS=linux GOARCH=amd64 go build -o mytool-linux ./cmd/mytool
# Build untuk macOS ARM
GOOS=darwin GOARCH=arm64 go build -o mytool-mac ./cmd/mytool
# Build untuk Windows
GOOS=windows GOARCH=amd64 go build -o mytool.exe ./cmd/mytool
# Build untuk ARM (Raspberry Pi)
GOOS=linux GOARCH=arm64 go build -o mytool-arm ./cmd/mytool
Tips Membuat CLI yang Great
- --help harus jelas Setiap command harus punya deskripsi yang helpful
- Graceful error messages Jangan tampilkan stack trace ke user
- Colored output Gunakan library seperti lipgloss untuk output yang readable
- Shell completion Cobra punya built-in support untuk bash/zsh/fish completion
- Version info Inject build version dan commit hash via ldflags di CI/CD
Go CLI tools itu addictive. Sekali Anda merasakan binary kecil, cepat, dan cross-platform, Anda akan ingin membuat CLI untuk semua automasi. Trust me, saya sudah kecanduan.
Error Handling di CLI Tools
CLI tools yang baik harus punya error handling yang informative. Jangan biarkan user melihat stack trace:
import "github.com/mattn/go-isatty"
func handleError(err error) {
if err == nil { return }
if isatty.IsTerminal(os.Stdout.Fd()) {
// Interactive mode: show colored error
fmt.Fprintf(os.Stderr, "\033[31mError:\033[0m %v\n", err)
} else {
// CI/CD mode: plain text
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
}
os.Exit(1)
}
Saya juga selalu tambahkan --verbose flag untuk debugging. Di normal mode, tampilkan error message yang clean. Dengan --verbose, tampilkan full stack trace dan debug info.
Publishing dan Distributing CLI Tools
Untuk distribusi CLI tools, saya recommend beberapa approach:
- GoReleaser automate build, test, dan publish ke GitHub releases untuk semua platform
- Homebrew tap untuk macOS/Linux users, buat custom Homebrew tap
- npm/npx wrapper untuk JavaScript ecosystem users
- Docker image untuk containerized environments
GoReleaser adalah tool favorit saya karena bisa automate semua proses ini dalam satu command. Cukup jalankan goreleaser release dan semua binary akan di-build, test, dan publish ke GitHub dalam hitungan menit.