← Back to Cecep Azhar
Cecep Azhar #golang#cli#cobra#command-line#tools

Go CLI Tools: Membuat Command Line yang Powerful

Cecep Saeful Azhar • 16 Oct 2026
Go CLI Tools: Membuat Command Line yang Powerful
Tutorial membuat CLI tools yang powerful dengan Go. Cobra library, flags, subcommands, dan best practices.

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

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 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.

← More articles from Cecep Azhar Central Content Hub Home →