Dalam dunia pengembangan perangkat lunak, antarmuka baris perintah (CLI) memainkan peran penting dalam mengotomatisasi tugas dan menyediakan cara yang nyaman bagi pengguna untuk berinteraksi dengan perangkat lunak melalui perintah berbasis teks.
Dalam postingan blog ini, kita akan mempelajari cara membuat alat CLI menggunakan bahasa pemrograman Go, memanfaatkan perpustakaan populer seperti "Cobra" dan "Viper".

Mengapa CLI ada di GO?

Go adalah bahasa pemrograman modern yang mendapatkan popularitas signifikan dalam beberapa tahun terakhir karena kesederhanaan, kinerja, dan dukungan kuat untuk konkurensi. Go adalah pilihan yang sangat baik untuk membangun CLI karena dapat dikompilasi dengan cepat, menghasilkan binari mandiri yang dapat berjalan di berbagai sistem operasi dan arsitektur, dan tidak memiliki ketergantungan eksternal atau persyaratan runtime.

Membuat CLI dengan Cara Tradisional

Sebelum kita mendalami pustaka Cobra dan Viper, mari kita jelajahi bagaimana kita bisa membuat alat CLI dasar menggunakan Go tanpa pustaka eksternal apa pun. Di bawah ini adalah contoh CLI sederhana yang mengambil masukan pengguna dan melakukan tindakan tertentu berdasarkan perintah yang diberikan.

func main() {
    command := flag.String("command", "", "Command to execute")
    flag.Parse()

    if *command == "" {
       fmt.Println("Please provide a command.")
       flag.Usage()
       return
    }

    switch *command {
    case "greet":
       fmt.Println("Hello, World!")
    case "time":
       fmt.Println("Current time:", time.Now().Format("15:04:05"))
    default:
       fmt.Println("Unknown command:", command)
    }
}

Ular untuk Diselamatkan…

Meskipun pendekatan di atas berfungsi untuk CLI sederhana, pendekatan ini dapat menjadi rumit dan sulit dipertahankan seiring dengan semakin kompleksnya aplikasi. Di sinilah perpustakaan seperti Cobra dan Viper berperan sebagai penyelamat.
Untuk memahami penggunaan perpustakaan ini, kami akan membangun aplikasi todo cli sederhana, tempat Anda dapat membuat, memperbarui, mencari, dan menghapus tugas todo.

Kobra

Cobra adalah perpustakaan yang kuat untuk membuat aplikasi CLI modern dan kaya fitur di Go. Ini memberikan kerangka kerja yang kuat untuk membangun perintah CLI, termasuk dukungan untuk sub-perintah bertingkat, tanda global dan lokal, perintah bantuan otomatis, dan tanda yang sepenuhnya sesuai dengan POSIX dengan versi pendek dan panjang.
Inisialisasi scaffolding cli untuk proyek menggunakan cobra init memerintah.

cobra-cli init gotodo

Ini akan menginisialisasi proyek gotodo dengan perpustakaan cobra. Anda dapat mengamati bahwa itu membuat beberapa file dalam proyek.
Selanjutnya, kita dapat menambahkan perintah tambahan ke CLI kita menggunakan perintah cobra add.

cobra add list

Perintah ini membuat file baru bernama list.go di bawah direktori cmd , yang berisi implementasi untuk perintah daftar. Kita dapat mengulangi langkah ini untuk menambahkan lebih banyak perintah sesuai kebutuhan

Menyiapkan Subperintah dengan Cobra

Cobra memungkinkan kita membuat subperintah bertingkat, yang dapat memberikan struktur hierarki ke CLI kita.
Misalnya, kita dapat menambahkan perintah pencarian dan sub-perintah yang dilengkapi di bawahnya menggunakan perintah berikut:

cobra add search
cobra add search completed

Perintah ini menghasilkan file yang diperlukan untuk perintah pencarian dan subperintahnya yang telah selesai. Kita sekarang dapat menentukan perilaku dan implementasi perintah-perintah ini di file masing-masing

Menyiapkan Bendera dengan Cobra

Bendera sangat penting untuk menyediakan opsi dan parameter pada perintah CLI kami. Cobra menawarkan dukungan untuk bendera lokal dan persisten.

Bendera Lokal
Bendera lokal khusus untuk satu perintah dan tidak berlaku untuk perintah atau subperintah lainnya. Kita dapat mendefinisikan flag lokal menggunakan metode Flags() pada sebuah perintah.
Misalnya, untuk menambahkan tanda kata kunci pada perintah pencarian, kita dapat menggunakan kode berikut:

searchCmd.Flags().StringP("keyword", "k", "", "Keyword for the task name to search for.")

Kode ini menambahkan tanda kata kunci — dengan singkatan -k ke perintah pencarian, memungkinkan pengguna menentukan kata kunci yang akan dicari dalam nama tugas.

gotodo search --keyword test

Bendera Persisten
Bendera persisten dibagikan antara perintah dan subperintahnya. Mereka memungkinkan kita untuk menentukan tanda yang berlaku untuk suatu perintah dan semua subperintahnya. Kita dapat mendefinisikan tanda persisten menggunakan metode PersistentFlags() pada sebuah perintah.
Misalnya, untuk menambahkan flag keluaran ke perintah pencarian, kita dapat menggunakan kode berikut:

searchCmd.PersistentFlags().StringP("output", "o", "", "Output format [table, json, yaml]")

Kode ini menambahkan tanda keluaran — dengan singkatan -o pada perintah pencarian, sehingga pengguna dapat menentukan format keluaran untuk hasil pencarian.

gotodo search --output yaml

Menyiapkan Argumen dengan Cobra

Selain flag, Cobra juga mendukung argumen, yaitu parameter yang diteruskan langsung ke suatu perintah. Argumen berguna untuk memberikan nilai masukan spesifik yang diperlukan oleh suatu perintah.
Misalnya, kita ingin menambahkan perintah lengkap yang menandai tugas selesai. Kita dapat mendefinisikan perintah ini dengan argumen yang mewakili ID tugas yang harus diselesaikan. Di bawah ini adalah contoh penerapannya:

var completeCmd = &cobra.Command{
    Use:   "complete",
    Short: "Complete a todo task",
    Long:  ``,
    Args:  cobra.ExactArgs(1),
    Run: func(cmd *cobra.Command, args []string) {
       // Reading Args 0
       taskID, err := strconv.Atoi(args[0])
       if err != nil {                     
          log.Fatal(err) 
       }

       err = service.CompleteTodoTask(taskID)
       if err != nil {
          log.Fatal(err)
       }
       fmt.Println("Task successfully completed.")
    }
}

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

Dalam contoh ini, kami memeriksa apakah jumlah argumen minimal satu. Jika tidak, kami menampilkan pesan kesalahan. Jika tidak, kami mengambil argumen pertama (ID tugas) dan melakukan operasi lengkap menggunakan ID tersebut.

gotodo complete 1

Ular berbisa

Viper adalah solusi konfigurasi yang kuat untuk aplikasi Go, termasuk CLI. Memungkinkan kita membaca dan mengelola pengaturan aplikasi dari berbagai format file konfigurasi seperti JSON, TOML, YAML, dan HCL. Viper juga mendukung pengaturan default dan penanganan variabel lingkungan, sehingga sangat fleksibel dan nyaman.
Di bawah ini adalah contoh bagaimana kita dapat memuat tugas JSON yang ada menggunakan Viper:

var loadCmd = &cobra.Command{
    Use:   "load",
    Short: "Load the existing todo task json",
    Long:  ``,
  
    Run: func(cmd *cobra.Command, args []string) {
       var existingTasks models.Todos

       viper.SetConfigFile(jsonFile) 
       err := viper.ReadInConfig()  
       if err != nil {              
          log.Fatal(err)
       } 

       err = viper.Unmarshal(&existingTasks) 
       if err != nil {                       
          log.Fatal(err) 
       } 

       err = service.LoadExistingJSON(existingTasks)
       if err != nil {
          log.Fatal(err)
       }
    }
}

func init() {
    rootCmd.AddCommand(loadCmd)
    loadFlags := loadCmd.Flags()

    loadFlags.StringVar(&jsonFile, "jsonFile", "", "json file for existing tasks"+
       "")
    cobra.MarkFlagRequired(loadFlags, "jsonFile")
}

Dalam contoh ini, kita mendefinisikan perintah load yang mengharapkan tanda — jsonFile yang mewakili file JSON untuk memuat tugas. Kami menggunakan Viper untuk mengikat nilai bendera ke pengaturan konfigurasi yang sesuai (jsonFile).

gotodo load --jsonFile storage.json

Kesimpulan

Dalam postingan blog ini, kami menjelajahi proses pembuatan alat CLI di Go menggunakan perpustakaan Cobra dan Viper. Kami mempelajari cara menyiapkan perintah, subperintah, flag, dan argumen menggunakan Cobra, sehingga memungkinkan kami membuat aplikasi CLI yang fleksibel dan kaya fitur. Selain itu, kami menemukan bagaimana Viper dapat digunakan untuk mengelola pengaturan aplikasi, memberikan pengalaman konfigurasi yang lancar.

Terima kasih atas waktu dan minatnya. Selamat Coding!
Kode sumber untuk contoh tersedia di mehulgohil/gotodo