Go Programming

تسلط بر ترمینال: ساخت ابزارهای قدرتمند CLI با Cobra در Go

رابط‌های خط فرمان (CLI) همچنان ستون فقرات DevOps مدرن، گردش‌کارهای توسعه و مدیریت سیستم هستند. در حالی که پایتون و Node.js جایگاه خود را در دنیای اسکریپت‌نویسی دارند، Go به عنوان زبان انتخابی برای ساخت ابزارهای CLI سریع، با تایپ ایستا و قابل حمل ظهور کرده است. با این حال، نوشتن یک CLI از صفر—مدیریت فلگ‌ها، زیردستورات و متن راهنما—می‌تواند به سرعت به کدهای تکراری و مستعد خطا تبدیل شود. اینجا Cobra وارد میدان می‌شود.

Cobra تنها یک کتابخانه نیست؛ بلکه یک کتابخانه ایدوماتیک (Idiomatic) برای Go است که برای ایجاد رابط‌های خط فرمان مدرن و قدرتمند، مشابه Git یا ابزارهای خود Go، طراحی شده است. در این پست، بررسی خواهیم کرد که چگونه می‌توان از Cobra برای ساخت برنامه‌های خط فرمانی مقیاس‌پذیر، قابل نگهداری و کاربرپسند استفاده کرد.

چرا Cobra را انتخاب کنیم؟

مزیت اصلی Cobra ساختار آن است. این کتابخانه یک الگوی سلسله‌مراتبی را تحمیل می‌کند: دستور ریشه (Root Command) نقطه ورود است و سایر دستورات فرزند آن محسوب می‌شوند. این امر سازماندهی برنامه‌های پیچیده را آسان می‌سازد. علاوه بر این، Cobra به طور یکپارچه با Viper ادغام می‌شود که یک راه‌حل کامل پیکربندی برای برنامه‌های Go است و پشتیبانی همزمان از فایل‌های پیکربندی، متغیرهای محیطی و فلگ‌ها را بسیار ساده می‌کند.

علاوه بر این، Cobra از موارد زیر به صورت پیش‌فرض پشتیبانی می‌کند:

  • زیردستورات (Subcommands)
  • فلگ‌های سراسری و محلی
  • تولید خودکار متن راهنما و اطلاعات استفاده
  • تکمیل خودکار در شل‌ها (zsh, bash, powershell و غیره)

راه‌اندازی پروژه

قبل از شروع کدنویسی، مطمئن شوید که Go نصب شده است. ماژول جدیدی برای پروژه خود راه‌اندازی کنید:

mkdir my-cli-tool
cd my-cli-tool
go mod init github.com/username/my-cli-tool
go get github.com/spf13/cobra

ما یک ابزار ساده به نام "status" ایجاد می‌کنیم که وضعیت یک سرویس را بررسی کند و دارای یک زیردستور برای "detail" (جزئیات) اجزای خاص باشد.

تعریف دستور ریشه

دستور ریشه لنگرگاه CLI شماست و نماینده خود برنامه است. در Cobra، این مورد با استفاده از cobra.Command تعریف می‌شود.

package main

import (
	"fmt"
	"log"

	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Use:   "mycli",
	Short: "توضیح کوتاهی از برنامه شما",
	Long: `My CLI یک ابزار قدرتمند است که برای کمک به شما در مدیریت 
کارآمد سرویس‌ها طراحی شده است. این ابزار رابطی ساده را برای 
بررسی وضعیت و مشاهده جزئیات فراهم می‌کند.`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Usage: mycli [command]")
		// اختیاری: نمایش راهنما در صورت عدم ارائه آرگومان
		cmd.Help()
	},
}

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

func main() {
	Execute()
}

به تابع Execute توجه کنید. این یک الگوی استاندارد در پروژه‌های Cobra است که اجازه می‌دهد درخت دستورات به صورت تمیز اجرا شود. تابع Run به عنوان پردازنده پیش‌فرض زمانی که هیچ زیردستوری مشخص نشده باشد عمل می‌کند.

افزودن زیردستورات

CLIهای پیچیده به زیردستورات وابسته هستند. بیایید یک دستور status اضافه کنیم. ما آن را جداگانه تعریف می‌کنیم تا کد ماژولار و خوانا باقی بماند.

var statusCmd = &cobra.Command{
	Use:   "status",
	Short: "بررسی وضعیت سرویس",
	Long:  `بررسی وضعیت فعلی تمام سرویس‌های در حال اجرا.`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("Service is UP")
		fmt.Println("Database: Connected")
		fmt.Println("Cache: Active")
	},
}

func init() {
	// افزودن دستور status به دستور ریشه
	rootCmd.AddCommand(statusCmd)
}

تابع init در اینجا حیاتی است. این تابع زیردستور را با والد خود ثبت می‌کند. زمانی که دستور go run main.go status را اجرا می‌کنید، Cobra به طور خودکار اجرای برنامه را به تابع Run متعلق به statusCmd هدایت می‌کند.

مدیریت فلگ‌ها و آرگومان‌ها

یکی از قوی‌ترین ویژگی‌های Cobra، مدیریت فلگ‌های آن است. این کتابخانه از فلگ‌های پایدار (Persistent) که در درخت دستورات گسترش می‌یابند و فلگ‌های محلی که فقط برای دستورات خاص اعمال می‌شوند، پشتیبانی می‌کند.

بیایید یک فلگ به دستور status خود اضافه کنیم تا خروجی verbose (پر توضیح) را فعال کند.

// این بخش را داخل تعریف statusCmd اضافه کنید
var verbose bool

statusCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "خروجی پر توضیح")

// به‌روزرسانی تابع Run
Run: func(cmd *cobra.Command, args []string) {
	if verbose {
		fmt.Println("DEBUG: Detailed status report generated at", time.Now())
	}
	// ... منطق وضعیت موجود
}

Cobra به طور خودکار متن راهنما را برای این فلگ‌ها تولید می‌کند. اگر کاربر دستور mycli status --help را اجرا کند، توضیحی را که در BoolVarP ارائه داده‌ایم، مشاهده خواهد کرد.

بهترین شیوه‌ها برای محیط تولید

  1. به جای Run از RunE استفاده کنید: RunE به شما امکان می‌دهد خطاها را برگردانید که Cobra آن‌ها را با چاپ خطا و خروج با کد وضعیت غیرصفر به صورت شایسته مدیریت می‌کند.
  2. دستورات را در فایل‌های جداگانه قرار دهید: با رشد CLI خود، دستوراتی مانند statusCmd را به فایل‌های مستقل در یک دایرکتوری cmd/ منتقل کنید.
  3. ادغام با Viper: از Viper برای اتصال فلگ‌ها به متغیرهای پیکربندی استفاده کنید تا کاربران بتوانند مقادیر پیش‌فرض را از طریق فایل‌های پیکربندی یا متغیرهای محیطی تنظیم کنند.
  4. تولید مستندات: Cobra می‌تواند به طور خودکار مستندات Markdown برای دستورات شما تولید کند که برای پروژه‌های متن‌باز بسیار ارزشمند است.

نتیجه‌گیری

ساخت ابزارهای CLI در Go با Cobra، کاری که می‌توانست خسته‌کننده باشد را به یک تجربه ساختاریافته و لذت‌بخش تبدیل می‌کند. با بهره‌گیری از تولید خودکار راهنما، تجزیه قدرتمند فلگ‌ها و معماری ماژولار آن، می‌توانید ابزارهایی بسازید که نه تنها کاربردی، بلکه حرفه‌ای و آسان برای استفاده باشند. چه در حال ساخت یک ابزار DevOps باشید و چه یک ابزار توسعه‌دهنده داخلی، Cobra پایه‌ای برای برنامه‌های خط فرمان مقیاس‌پذیر در Go فراهم می‌کند.

امروز شروع به آزمایش با Cobra کنید و بررسی اکوسیستم آن، به ویژه ادغام با Viper برای مدیریت پیکربندی را در نظر بگیرید تا ابزارهای CLI خود را به سطح بعدی ببرید.

Share: