गो में कोबरा और वाइपर के साथ CLI ऐप्स बनाना

गो में कोबरा और वाइपर फ्रेमवर्क के साथ सीएलआई विकास

Page content

कमांड-लाइन इंटरफेस (CLI) एप्लिकेशन डेवलपर्स, सिस्टम एडमिनिस्ट्रेटर्स, और डेवॉप्स प्रोफेशनल्स के लिए आवश्यक उपकरण हैं। Go में CLI विकास के लिए दो लाइब्रेरी डि फैक्टो मानक बन गए हैं: Cobra कमांड संरचना के लिए और Viper कॉन्फ़िगरेशन प्रबंधन के लिए (https://www.glukhov.org/hi/post/2025/11/go-cli-applications-with-cobra-and-viper/ “Go में CLI विकास”)।

Go CLI उपकरणों के लिए एक उत्कृष्ट भाषा के रूप में उभरा है, इसकी प्रदर्शन क्षमता, सरल डिप्लॉयमेंट, और क्रॉस-प्लेटफॉर्म समर्थन के कारण।

टेट्रिस

Go के लिए CLI एप्लिकेशन का चयन क्यों करें

Go CLI विकास के लिए आकर्षक लाभ प्रदान करता है:

  • एकल बाइनरी वितरण: कोई रनटाइम निर्भरताएं या पैकेज मैनेजर की आवश्यकता नहीं
  • त्वरित निष्पादन: नेटिव कम्पाइलेशन उत्कृष्ट प्रदर्शन प्रदान करता है
  • क्रॉस-प्लेटफॉर्म समर्थन: लिनक्स, मैकओएस, विंडोज़, और अन्य के लिए आसान कम्पाइलेशन
  • मजबूत स्टैंडर्ड लाइब्रेरी: फाइल I/O, नेटवर्किंग, और टेक्स्ट प्रोसेसिंग के लिए समृद्ध टूलिंग
  • सहस्राब्दी: बिल्ट-इन गोरूटीन्स के लिए समानांतर ऑपरेशंस
  • स्टैटिक टाइपिंग: कम्पाइल टाइम पर त्रुटियों का पता लगाएं

Go में बनाए गए लोकप्रिय CLI उपकरणों में Docker, Kubernetes (kubectl), Hugo, Terraform, और GitHub CLI शामिल हैं। अगर आप Go के नए हैं या एक तेज़ संदर्भ की आवश्यकता है, तो हमारे Go चीत शीट के लिए देखें जिसमें आवश्यक Go सिंटैक्स और पैटर्न हैं।

Cobra का परिचय

Cobra एक लाइब्रेरी है जो शक्तिशाली आधुनिक CLI एप्लिकेशन बनाने के लिए एक सरल इंटरफेस प्रदान करता है। स्टीव फ्रांसिया (spf13) द्वारा बनाया गया, जो Hugo और Viper के पीछे भी लेखक हैं, Cobra कई सबसे लोकप्रिय Go प्रोजेक्ट्स में उपयोग किया जाता है।

प्रमुख Cobra विशेषताएं

कमांड संरचना: Cobra कमांड पैटर्न को लागू करता है, जिससे आप कमांड और सबकमांड्स (जैसे git commit या docker run) के साथ एप्लिकेशन बना सकते हैं।

फ्लैग हैंडलिंग: स्थानीय और स्थायी फ्लैग्स के साथ स्वचालित पार्सिंग और टाइप कन्वर्जन।

स्वचालित मदद: मदद टेक्स्ट और उपयोग जानकारी स्वचालित रूप से उत्पन्न करता है।

बुद्धिमान सुझाव: जब उपयोगकर्ता टाइपो करते हैं तो सुझाव प्रदान करता है (“क्या आपने ‘status’ का मतलब था?”).

शेल पूर्णताएं: बाश, zsh, फिश, और पावरशेल के लिए पूर्णता स्क्रिप्ट्स उत्पन्न करें।

लचीलापूर्ण आउटपुट: कस्टम फॉर्मेटर्स और आउटपुट स्टाइल्स के साथ आसानी से काम करें।

Viper का परिचय

Viper Go एप्लिकेशन्स के लिए एक पूर्ण कॉन्फ़िगरेशन समाधान है, जो Cobra के साथ आसानी से काम करता है। यह स्पष्ट प्राथमिकता क्रम के साथ कई स्रोतों से कॉन्फ़िगरेशन हैंडल करता है।

प्रमुख Viper विशेषताएं

कई कॉन्फ़िगरेशन स्रोत:

  • कॉन्फ़िगरेशन फाइलें (JSON, YAML, TOML, HCL, INI, envfile, Java प्रॉपर्टीज़)
  • पर्यावरण चर
  • कमांड-लाइन फ्लैग्स
  • रिमोट कॉन्फ़िगरेशन सिस्टम (etcd, Consul)
  • डिफ़ॉल्ट मान

कॉन्फ़िगरेशन प्राथमिकता क्रम:

  1. Set के लिए स्पष्ट कॉल
  2. कमांड-लाइन फ्लैग्स
  3. पर्यावरण चर
  4. कॉन्फ़िगरेशन फाइल
  5. की/वैल्यू स्टोर
  6. डिफ़ॉल्ट मान

लाइव वॉचिंग: कॉन्फ़िगरेशन फाइलें निगरानी करें और स्वचालित रूप से बदलाव होने पर रीलोड करें।

टाइप कन्वर्जन: विभिन्न Go टाइप्स (स्ट्रिंग, इंट, बूल, ड्यूरेशन, आदि) में स्वचालित रूपांतरण।

शुरू करने के लिए: इंस्टॉलेशन

पहले एक नया Go मॉड्यूल इनिशियलाइज़ करें और दोनों लाइब्रेरीज इंस्टॉल करें:

go mod init myapp
go get -u github.com/spf13/cobra@latest
go get -u github.com/spf13/viper@latest

वैकल्पिक रूप से, Cobra CLI जनरेटर को स्कैफोल्डिंग के लिए इंस्टॉल करें:

go install github.com/spf13/cobra-cli@latest

अपने पहले CLI एप्लिकेशन का निर्माण

चलिए एक व्यावहारिक उदाहरण बनाएं: एक टास्क प्रबंधन CLI उपकरण कॉन्फ़िगरेशन समर्थन के साथ।

प्रोजेक्ट संरचना

mytasks/
├── cmd/
│   ├── root.go
│   ├── add.go
│   ├── list.go
│   └── complete.go
├── config/
│   └── config.go
├── main.go
└── config.yaml

मुख्य एंट्री पॉइंट

// main.go
package main

import "mytasks/cmd"

func main() {
    cmd.Execute()
}

Viper इंटीग्रेशन के साथ रूट कमांड

// cmd/root.go
package cmd

import (
    "fmt"
    "os"
    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)

var cfgFile string

var rootCmd = &cobra.Command{
    Use:   "mytasks",
    Short: "एक सरल टास्क प्रबंधन CLI",
    Long: `MyTasks एक CLI टास्क मैनेजर है जो आपको आसानी से
अपने दैनिक टास्क्स को संगठित करने में मदद करता है। Cobra और Viper के साथ बनाया गया।`,
}

func Execute() {
    if err := rootCmd.Execute(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

func init() {
    cobra.OnInitialize(initConfig)

    rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "",
        "कॉन्फ़िगरेशन फाइल (डिफ़ॉल्ट $HOME/.mytasks.yaml है)")
    rootCmd.PersistentFlags().String("db",
        "डेटाबेस फाइल स्थान")

    viper.BindPFlag("database", rootCmd.PersistentFlags().Lookup("db"))
}

func initConfig() {
    if cfgFile != "" {
        viper.SetConfigFile(cfgFile)
    } else {
        home, err := os.UserHomeDir()
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
            os.Exit(1)
        }

        viper.AddConfigPath(home)
        viper.AddConfigPath(".")
        viper.SetConfigType("yaml")
        viper.SetConfigName(".mytasks")
    }

    viper.SetEnvPrefix("MYTASKS")
    viper.AutomaticEnv()

    if err := viper.ReadInConfig(); err == nil {
        fmt.Println("कॉन्फ़िगरेशन फाइल का उपयोग कर रहा हूँ:", viper.ConfigFileUsed())
    }
}

सबकमांड्स जोड़ना

// cmd/add.go
package cmd

import (
    "fmt"
    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)

var priority string

var addCmd = &cobra.Command{
    Use:   "add [टास्क विवरण]",
    Short: "एक नया टास्क जोड़ें",
    Args:  cobra.MinimumNArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
        task := args[0]
        db := viper.GetString("database")

        fmt.Printf("टास्क जोड़ रहा हूँ: %s\n", task)
        fmt.Printf("प्राथमिकता: %s\n", priority)
        fmt.Printf("डेटाबेस: %s\n", db)

        // यहाँ आप वास्तविक टास्क स्टोरेज लागू करेंगे
    },
}

func init() {
    rootCmd.AddCommand(addCmd)

    addCmd.Flags().StringVarP(&priority, "priority", "p", "medium",
        "टास्क प्राथमिकता (कम, मध्यम, उच्च)")
}

सूची कमांड

// cmd/list.go
package cmd

import (
    "fmt"
    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)

var showCompleted bool

var listCmd = &cobra.Command{
    Use:   "list",
    Short: "सभी टास्क सूचीबद्ध करें",
    Run: func(cmd *cobra.Command, args []string) {
        db := viper.GetString("database")

        fmt.Printf("टास्क सूचीबद्ध कर रहा हूँ: %s\n", db)
        fmt.Printf("पूर्ण टास्क दिखाएं: %v\n", showCompleted)

        // यहाँ आप वास्तविक टास्क सूचीबद्ध करने का कार्य लागू करेंगे
    },
}

func init() {
    rootCmd.AddCommand(listCmd)

    listCmd.Flags().BoolVarP(&showCompleted, "completed", "c", false,
        "पूर्ण टास्क दिखाएं")
}

डेटा स्थायित्व लागू करना

एक उत्पादन टास्क प्रबंधन CLI के लिए, आपको वास्तविक डेटा स्टोरेज लागू करने की आवश्यकता होगी। जबकि हम यहाँ एक सरल डेटाबेस पथ कॉन्फ़िगरेशन का उपयोग कर रहे हैं, आपके पास डेटा को स्थायी बनाने के लिए कई विकल्प हैं:

  • SQLite: CLI उपकरणों के लिए हल्का, सर्वरलेस डेटाबेस
  • PostgreSQL/MySQL: अधिक जटिल एप्लिकेशन्स के लिए पूर्ण-फीचर्ड डेटाबेस
  • JSON/YAML फाइलें: हल्के आवश्यकताओं के लिए सरल फाइल-आधारित स्टोरेज
  • एम्बेडेड डेटाबेस: BoltDB, BadgerDB के लिए की-वैल्यू स्टोरेज

अगर आप PostgreSQL जैसे रिलेशनल डेटाबेस के साथ काम कर रहे हैं, तो आपको एक ORM या क्वेरी बिल्डर का उपयोग करना चाहिए। Go डेटाबेस लाइब्रेरीज की एक व्यापक तुलना के लिए, हमारे गाइड पर देखें Go ORMs for PostgreSQL तुलना: GORM vs Ent vs Bun vs sqlc

Viper के साथ उन्नत कॉन्फ़िगरेशन

कॉन्फ़िगरेशन फाइल उदाहरण

# .mytasks.yaml
database: ~/.mytasks.db
format: table
colors: true

notifications:
  enabled: true
  sound: true

priorities:
  high: red
  medium: yellow
  low: green

नेटेड कॉन्फ़िगरेशन पढ़ना

func getNotificationSettings() {
    enabled := viper.GetBool("notifications.enabled")
    sound := viper.GetBool("notifications.sound")

    fmt.Printf("नोटिफिकेशन्स सक्षम: %v\n", enabled)
    fmt.Printf("साउंड सक्षम: %v\n", sound)
}

func getPriorityColors() map[string]string {
    return viper.GetStringMapString("priorities")
}

पर्यावरण चर

Viper स्वचालित रूप से कॉन्फ़िगर किए गए प्रीफिक्स के साथ पर्यावरण चर पढ़ता है:

export MYTASKS_DATABASE=/tmp/tasks.db
export MYTASKS_NOTIFICATIONS_ENABLED=false
mytasks list

लाइव कॉन्फ़िगरेशन रीलोड

func watchConfig() {
    viper.WatchConfig()
    viper.OnConfigChange(func(e fsnotify.Event) {
        fmt.Println("कॉन्फ़िगरेशन फाइल बदल गई:", e.Name)
        // कॉन्फ़िगरेशन-निर्भर घटकों को रीलोड करें
    })
}

सर्वोत्तम प्रथाएं

1. कॉन्सिस्टेंसी के लिए Cobra जनरेटर का उपयोग करें

cobra-cli init
cobra-cli add serve
cobra-cli add create

2. कमांड्स को अलग-अलग फाइलों में संगठित करें

संरक्षण के लिए हर कमांड को cmd/ डायरेक्टरी के तहत अपनी अपनी फाइल में रखें।

3. स्थायी फ्लैग्स का लाभ उठाएं

सभी सबकमांड्स के लिए लागू होने वाले विकल्पों के लिए स्थायी फ्लैग्स का उपयोग करें:

rootCmd.PersistentFlags().StringP("output", "o", "text",
    "आउटपुट फॉर्मेट (टेक्स्ट, जेसन, यामल)")

4. उचित त्रुटि हैंडलिंग लागू करें

var rootCmd = &cobra.Command{
    Use:   "myapp",
    Short: "मेरा एप्लिकेशन",
    RunE: func(cmd *cobra.Command, args []string) error {
        if err := doSomething(); err != nil {
            return fmt.Errorf("कुछ करने में विफल: %w", err)
        }
        return nil
    },
}

5. अर्थपूर्ण मदद टेक्स्ट प्रदान करें

var cmd = &cobra.Command{
    Use:   "deploy [environment]",
    Short: "एप्लिकेशन को निर्दिष्ट वातावरण में डिप्लॉय करें",
    Long: `डिप्लॉय बिल्ड और डिप्लॉय करता है
आपका एप्लिकेशन निर्दिष्ट वातावरण में। समर्थित वातावरण हैं:
  - विकास (dev)
  - स्टेजिंग
  - उत्पादन (prod)`,
    Example: `  myapp deploy staging
  myapp deploy production --version=1.2.3`,
}

6. बुद्धिमान डिफ़ॉल्ट सेट करें

func init() {
    viper.SetDefault("port", 8080)
    viper.SetDefault("timeout", "30s")
    viper.SetDefault("retries", 3)
}

7. कॉन्फ़िगरेशन वैलिडेशन करें

func validateConfig() error {
    port := viper.GetInt("port")
    if port < 1024 || port > 65535 {
        return fmt.Errorf("अमान्य पोर्ट: %d", port)
    }
    return nil
}

CLI अनुप्रयोगों का परीक्षण

कमांड का परीक्षण

// cmd/root_test.go
package cmd

import (
    "bytes"
    "testing"
)

func TestRootCommand(t *testing.T) {
    cmd := rootCmd
    b := bytes.NewBufferString("")
    cmd.SetOut(b)
    cmd.SetArgs([]string{"--help"})

    if err := cmd.Execute(); err != nil {
        t.Fatalf("command execution failed: %v", err)
    }
}

विभिन्न कॉन्फ़िगरेशन के साथ परीक्षण

func TestWithConfig(t *testing.T) {
    viper.Set("database", "/tmp/test.db")
    viper.Set("debug", true)

    // अपने परीक्षण चलाएं

    viper.Reset() // साफ़-सफाई करें
}

शेल पूर्णताओं का उत्पादन

Cobra विभिन्न शेल्स के लिए पूर्णता स्क्रिप्ट उत्पन्न कर सकता है:

// cmd/completion.go
package cmd

import (
    "os"
    "github.com/spf13/cobra"
)

var completionCmd = &cobra.Command{
    Use:   "completion [bash|zsh|fish|powershell]",
    Short: "पूर्णता स्क्रिप्ट उत्पन्न करें",
    Long: `पूर्णताओं को लोड करने के लिए:

Bash:
  $ source <(mytasks completion bash)

Zsh:
  $ source <(mytasks completion zsh)

Fish:
  $ mytasks completion fish | source

PowerShell:
  PS> mytasks completion powershell | Out-String | Invoke-Expression
`,
    DisableFlagsInUseLine: true,
    ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
    Args: cobra.ExactValidArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
        switch args[0] {
        case "bash":
            cmd.Root().GenBashCompletion(os.Stdout)
        case "zsh":
            cmd.Root().GenZshCompletion(os.Stdout)
        case "fish":
            cmd.Root().GenFishCompletion(os.Stdout, true)
        case "powershell":
            cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
        }
    },
}

func init() {
    rootCmd.AddCommand(completionCmd)
}

निर्माण और वितरण

कई प्लेटफॉर्म के लिए निर्माण

# Linux
GOOS=linux GOARCH=amd64 go build -o mytasks-linux-amd64

# macOS
GOOS=darwin GOARCH=amd64 go build -o mytasks-darwin-amd64
GOOS=darwin GOARCH=arm64 go build -o mytasks-darwin-arm64

# Windows
GOOS=windows GOARCH=amd64 go build -o mytasks-windows-amd64.exe

बाइनरी आकार कम करें

go build -ldflags="-s -w" -o mytasks

संस्करण जानकारी जोड़ें

// cmd/version.go
package cmd

import (
    "fmt"
    "github.com/spf13/cobra"
)

var (
    Version   = "dev"
    Commit    = "none"
    BuildTime = "unknown"
)

var versionCmd = &cobra.Command{
    Use:   "version",
    Short: "संस्करण जानकारी प्रिंट करें",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Version: %s\n", Version)
        fmt.Printf("Commit: %s\n", Commit)
        fmt.Printf("Built: %s\n", BuildTime)
    },
}

func init() {
    rootCmd.AddCommand(versionCmd)
}

संस्करण जानकारी के साथ निर्माण करें:

go build -ldflags="-X 'mytasks/cmd.Version=1.0.0' \
    -X 'mytasks/cmd.Commit=$(git rev-parse HEAD)' \
    -X 'mytasks/cmd.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)'" \
    -o mytasks

वास्तविक दुनिया के उदाहरण

Cobra और Viper के साथ बनाए गए लोकप्रिय ओपन-सोर्स टूल्स:

  • kubectl: Kubernetes कमांड-लाइन टूल
  • Hugo: स्टैटिक साइट जनरेटर
  • GitHub CLI (gh): GitHub का आधिकारिक CLI
  • Docker CLI: कंटेनर प्रबंधन
  • Helm: Kubernetes पैकेज मैनेजर
  • Skaffold: Kubernetes विकास वर्कफ्लो टूल
  • Cobra CLI: स्व-होस्टिंग - Cobra खुद का उपयोग करता है!

परंपरागत DevOps टूल्स के अलावा, Go के CLI क्षमताएं AI और मशीन लर्निंग अनुप्रयोगों तक फैली हुई हैं। यदि आप बड़े भाषा मॉडल्स के साथ काम करने वाले CLI टूल्स बनाना चाहते हैं, तो हमारे गाइड Constraining LLMs with Structured Output using Ollama and Go देखें, जो दिखाता है कि कैसे Go अनुप्रयोग बनाएं जो AI मॉडल्स के साथ काम करते हैं।

उपयोगी संसाधन

निष्कर्ष

Cobra और Viper मिलकर Go में पेशेवर CLI अनुप्रयोगों को बनाने के लिए एक शक्तिशाली आधार प्रदान करते हैं। Cobra कमांड संरचना, फ्लैग पार्सिंग, और हेल्प उत्पादन का प्रबंधन करता है, जबकि Viper कई स्रोतों से कॉन्फ़िगरेशन का प्रबंधन करता है जिसमें बुद्धिमान प्राथमिकता होती है।

इस संयोजन की अनुमति देता है कि आप CLI टूल्स बनाएं जो:

  • उपयोग में आसान होते हैं साथ ही स्वचालित हेल्प के साथ
  • कई कॉन्फ़िगरेशन स्रोतों के साथ लचीले होते हैं
  • शेल पूर्णताओं और उचित त्रुटि हैंडलिंग के साथ पेशेवर होते हैं
  • साफ़ कोड संगठन के साथ बनाए रखने योग्य होते हैं
  • विभिन्न प्लेटफॉर्मों के बीच पोर्टेबल होते हैं

चाहे आप डेवलपर टूल्स, सिस्टम यूटिलिटीज, या DevOps ऑटोमेशन बनाएं, Cobra और Viper आपको CLI अनुप्रयोगों को बनाने के लिए आवश्यक मजबूत आधार प्रदान करते हैं जो उपयोगकर्ताओं को पसंद आएंगे।