أطر CLI للغة Go: من الأدوات البسيطة إلى واجهات TUI
أصبحت لغة Go (Golang) اللغة رقم 1 لإنشاء أدوات وحدة التحكم وأدوات DevOps. بفضل التجميع السريع، والدعم المدمج للتوازي، والتوزيع البسيط (ملف ثنائي واحد)، فإن Go مثالية لـ CLI. ومع ذلك، فإن كتابة محلل الوسائط ومعالجة الأخطاء والإخراج الملون من الصفر هي مهمة شاقة. هنا تأتي أطر CLI للمساعدة. في هذه المقالة، سنحلل ثلاث أدوات رئيسية: Cobra وurfave/cli وBubble Tea.
1. Cobra — معيار الصناعة
Cobra (github.com/spf13/cobra) هو الإطار الأكثر شيوعًا للغة Go. تستخدمه Kubernetes وHugo وDocker وGitHub CLI. يوفر Cobra مولد أوامر قوي، وأوامر فرعية متداخلة، وإكمال تلقائي لـ bash/zsh/fish، والتكامل مع Viper (إدارة الإعدادات).
التثبيت
go get -u github.com/spf13/cobra/cobraمثال: تطبيق بسيط بأوامر فرعية
package main
import ( "fmt" "github.com/spf13/cobra")
func main() { var rootCmd = &cobra.Command{ Use: "app", Short: "مثال تطبيق على Cobra", Run: func(cmd *cobra.Command, args []string) { fmt.Println("تم تشغيل المعالج الجذري") }, }
var helloCmd = &cobra.Command{ Use: "hello [name]", Short: "تحية المستخدم", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { fmt.Printf("مرحبًا، %s!", args[0]) }, }
rootCmd.AddCommand(helloCmd) rootCmd.Execute()}الإمكانيات الرئيسية:
- توليد تلقائي للتعليمات (--help)
- دعم العلامات (الدائمة والمحلية)
- التحقق من صحة الوسائط
- توليد نصوص الإكمال التلقائي
- التكامل مع Viper للإعدادات
2. Urfave/cli — البساطة والمرونة
Urfave/cli (github.com/urfave/cli/v2) هو بديل خفيف لـ Cobra. الإطار تعريفي: تصف الأوامر والعلامات والإجراءات في هياكل. مثالي للأدوات الصغيرة والمتوسطة.
التثبيت
go get github.com/urfave/cli/v2مثال: أداة للعمل مع الملفات
package main
import ( "fmt" "log" "os" "github.com/urfave/cli/v2")
func main() { app := &cli.App{ Name: "fileutil", Usage: "أداة للعمل مع الملفات", Commands: []*cli.Command{ { Name: "read", Aliases: []string{"r"}, Usage: "قراءة ملف", Action: func(cCtx *cli.Context) error { if cCtx.NArg() == 0 { return fmt.Errorf("حدد اسم الملف") } data, _ := os.ReadFile(cCtx.Args().First()) fmt.Println(string(data)) return nil }, }, { Name: "write", Aliases: []string{"w"}, Usage: "كتابة سلسلة نصية إلى ملف", Flags: []cli.Flag{ &cli.StringFlag{ Name: "content", Aliases: []string{"c"}, Usage: "المحتوى المراد كتابته", }, }, Action: func(cCtx *cli.Context) error { content := cCtx.String("content") if content == "" { return fmt.Errorf("حدد --content") } return os.WriteFile(cCtx.Args().First(), []byte(content), 0644) }, }, }, }
if err := app.R