Introduzione a Go e alle applicazioni CLI
Go, noto anche come Golang, è un linguaggio di programmazione open-source progettato da Google. Enfatizza la semplicità, la sicurezza e le prestazioni, rendendolo una scelta eccellente per la creazione di applicazioni con interfaccia a riga di comando (CLI). Le applicazioni CLI sono strumenti con cui gli utenti possono interagire attraverso un'interfaccia basata sul testo, comunemente utilizzati per l'amministrazione del sistema, l'automazione e le attività di scripting. Go è adatto allo sviluppo di applicazioni CLI perché offre:
- Semplicità: La sintassi di Go è facile da capire e da scrivere, consentendo agli sviluppatori di creare e mantenere rapidamente le applicazioni CLI.
- Prestazioni: Go è un linguaggio compilato e tipizzato staticamente, il che significa che produce file binari ottimizzati, dando vita ad applicazioni CLI veloci ed efficienti.
- Supporto della concorrenza: Go dispone di primitive di concorrenza integrate, come goroutine e canali, che consentono un'elaborazione parallela senza soluzione di continuità e, in definitiva, applicazioni CLI più veloci e reattive.
- Compilazione binaria statica: Go compila le applicazioni in un singolo binario autonomo, senza dipendenze esterne, facilitando la distribuzione e il deployment delle applicazioni CLI.
- Potente libreria standard: La libreria standard di Go fornisce numerosi pacchetti integrati che semplificano le attività di sviluppo CLI più comuni, come il lavoro con i file, il networking e la gestione degli argomenti della riga di comando.
In questo articolo, imparerete gli elementi essenziali dello sviluppo di applicazioni CLI con Go, dalla configurazione dell'ambiente e la strutturazione dell'applicazione alla gestione degli argomenti della riga di comando e all'utilizzo di pacchetti di terze parti.
Per iniziare: Installare Go e configurare l'ambiente
Prima di iniziare a scrivere applicazioni CLI con Go, è necessario installare il linguaggio di programmazione Go sul proprio sistema.
- Visitate la pagina ufficiale di download di Go, selezionate il pacchetto binario appropriato per la vostra piattaforma (Windows, macOS o Linux) e seguite le istruzioni di installazione.
- Una volta completata l'installazione, verificare che Go sia stato installato correttamente eseguendo
go version
nel terminale. Questo comando dovrebbe visualizzare la versione di Go installata. - Configurare le variabili d'ambiente necessarie per Go, tra cui
GOPATH
, che determina la posizione dell'area di lavoro di Go (dove saranno memorizzati i progetti e le dipendenze di Go), eGOROOT
, che punta alla directory di installazione di Go. - Assicurarsi che il comando
go
sia presente nella variabilePATH
del sistema. Questo permette di eseguire i comandi Go da qualsiasi directory.
Con Go installato e l'ambiente configurato, si è pronti per iniziare a costruire la prima applicazione CLI.
Strutturare l'applicazione CLI: Pacchetti e moduli
Strutturare correttamente l'applicazione CLI è essenziale per la manutenibilità e la scalabilità, garantendo che il codice sia organizzato e facile da navigare. In Go, l'organizzazione del codice si ottiene attraverso pacchetti e moduli.
Pacchetti: I pacchetti sono il modo in cui Go organizza e compartimenta il codice. Un pacchetto è costituito da uno o più file sorgente (con estensione .go
) situati nella stessa directory. Ogni file di un pacchetto deve dichiarare il proprio nome, specificato con la parola chiave package
all'inizio del file. Una tipica applicazione Go CLI ha almeno due pacchetti:
main
: È il pacchetto predefinito per il punto di ingresso dell'applicazione. È il luogo in cui risiede la funzionemain()
e serve come punto di partenza dell'applicazione CLI. Tutta la logica e i comandi specifici della CLI devono essere inseriti nel pacchetto main.interno
opkg
: Questi pacchetti contengono codice riutilizzabile separato dalla logica della CLI. Si può usareinternal
per il codice che deve essere importato solo dal proprio codice Go all'interno del progetto epkg
per il codice che può essere importato da qualsiasi progetto Go.
Moduli: I moduli sono un mezzo per gestire le dipendenze e le versioni nelle applicazioni Go. Introdotti in Go 1.11, consentono agli sviluppatori di dichiarare le dipendenze dei pacchetti e di specificare la versione richiesta. Per creare un nuovo modulo Go, spostarsi nella directory principale del progetto ed eseguire il seguente comando:
go mod init your.module.name
Questo comando crea un file go.mod
nella directory principale, che elenca le dipendenze del progetto, e un file go.sum
, che contiene le checksum di ogni dipendenza. Quando si importano pacchetti o si utilizzano librerie di terze parti, Go terrà automaticamente traccia delle dipendenze nei file go.mod
e go.sum
.
Fonte dell'immagine: Il linguaggio di programmazione Go
Utilizzando pacchetti e moduli in modo efficace, è possibile mantenere una struttura di codice pulita ed efficiente per l'applicazione Go CLI, rendendo più semplice lo sviluppo, il debug e l'estensione del progetto in futuro.
Argomenti e flag della riga di comando
Gli argomenti e i flag della riga di comando sono componenti essenziali delle applicazioni CLI, che consentono agli utenti di controllare il comportamento dell'applicazione e di fornire gli input necessari. In Go è possibile lavorare con gli argomenti e i flag della riga di comando utilizzando i pacchetti flag
e os.Args
della libreria standard.
Uso di os.Args
Il pacchetto os.Args
fornisce un accesso diretto agli argomenti della riga di comando. Si tratta di una serie di stringhe, dove os.Args[0]
è il nome del programma in esecuzione e le altre voci rappresentano gli argomenti passati al programma.
Ecco un esempio di utilizzo di os.Args
:
package main import ( "fmt" "os" ) func main() { argCount := len(os.Args) fmt.Printf("Numero di argomenti: %d\n", argCount) fmt.Println("Argomenti:", os.Args) }
Eseguendo il programma, si vedrà il numero e l'elenco degli argomenti forniti.
Uso del pacchetto flag
Il pacchetto flag
è un modo più sofisticato e flessibile di lavorare con i flag della riga di comando. Permette di definire flag con vari tipi di dati e di analizzare comodamente l'input.
Di seguito è riportato un esempio di utilizzo del pacchetto flag
:
package main import ("flag" "fmt" ) func main() { var ( name string age int height float64 ) flag.StringVar(&name, "name", "John Doe", "Your name") flag.IntVar(&age, "age", 21, "Your age") flag.Float64Var(&height, "height", 180.0, "La tua altezza (in cm)") flag.Parse() fmt.Printf("Nome: %s\n", nome) fmt.Printf("Età: %d\n", età) fmt.Printf("Altezza: %.1f\n", altezza) }
Una volta definiti i flag, si invocherà flag.Parse()
per analizzare l'input da riga di comando fornito e popolare le variabili definite. È quindi possibile utilizzare queste variabili in tutta l'applicazione.
Creare comandi e sottocomandi
Per applicazioni CLI complesse, è possibile creare comandi e sottocomandi per organizzare meglio le funzionalità e le opzioni. Un popolare pacchetto di terze parti per lavorare con comandi e sottocomandi in Go è github.com/spf13/cobra
.
Iniziare con Cobra
Per iniziare, è necessario installare il pacchetto Cobra:
go get -u github.com/spf13/cobra/cobra
Una volta installato, è possibile creare una nuova applicazione CLI con Cobra:
cobra init my-cli --pkg-name=my-cli
Questo comando crea una nuova cartella denominata my-cli
con la struttura e i file necessari per un'applicazione CLI basata su Cobra.
Definizione dei comandi
In un'applicazione basata su Cobra, si creano comandi definendo istanze di cobra.Command
. Ogni comando ha un campo Use
(che indica l'utilizzo del comando), un campo Short
(che fornisce una breve descrizione) e un campo Long
(che fornisce una descrizione più dettagliata).
Inoltre, ogni comando dovrebbe avere un campo Esegui
, contenente una funzione che esegue la logica del comando. Spesso si definisce questa funzione come una chiusura, per catturare i flag e gli argomenti del comando.
Ecco un esempio di creazione di un semplice comando "greet":
greetCmd := &cobra.Command{ Use: "greet", Short: "Greet someone", Long: "Questo comando saluta qualcuno con un messaggio personalizzabile.", Run: func(cmd *cobra.Command, args []string) { // Logica per il comando greet }, }
Per creare un sottocomando, è possibile definire un'altra istanza di cobra.Command
e aggiungerla come figlio del comando padre utilizzando il metodo AddCommand
. Ad esempio, è possibile creare un sottocomando "goodbye" sotto il comando "greet":
goodbyeCmd := &cobra.Command{ Use: "goodbye", Short: "Say goodbye to someone", Long: "Questo sottocomando saluta qualcuno in una lingua specifica.", Run: func(cmd *cobra.Command, args []string) { // Logica per il sottocomando goodbye }, } greetCmd.AddCommand(goodbyeCmd)
Prompt interattivi e input dell'utente
I prompt interattivi possono migliorare l'esperienza utente dell'applicazione CLI, guidando gli utenti attraverso una serie di domande e raccogliendo input in base alle loro risposte. Un pacchetto di terze parti molto diffuso per lavorare con i prompt interattivi in Go è github.com/AlecAivazis/survey/v2
.
Come iniziare con Survey
Per prima cosa, è necessario installare il pacchetto Survey:
go get -u github.com/AlecAivazis/survey/v2
Usare Survey per i prompt interattivi
Survey fornisce una serie di tipi di prompt predefiniti, tra cui Input
, Select
, MultiSelect
, Confirm
e altri. Per creare un prompt, si istanzia il tipo di prompt desiderato e si chiama la funzione survey.Ask
.
package main import ( "fmt" "github.com/AlecAivazis/survey/v2" ) func main() { var name string namePrompt := &survey.Input{ Message: "Come ti chiami?", } err := survey.Ask([]*survey.Question{ Name: "nome", Prompt: namePrompt, Validate: survey.Required, }}, &nome) if err != nil { fmt.Println("Errore:", err) return } fmt.Printf("Ciao, %s!\n", nome) }
Questo frammento di codice dimostra l'uso del prompt Input
di Survey per raccogliere un nome e visualizzare un messaggio di saluto. Il campo Validate
può essere impostato per implementare una logica di validazione personalizzata per l'input dell'utente.
Lavorare con le librerie esterne
In molte applicazioni CLI, è comune affidarsi a librerie esterne per migliorare le funzionalità e semplificare il processo di sviluppo. Go offre un approccio moderno ed efficiente alla gestione delle dipendenze che consente agli sviluppatori di lavorare con librerie esterne senza problemi. Introdotti in Go 1.11, i moduli Go consentono di dichiarare le dipendenze dei pacchetti all'interno del progetto e di automatizzare il processo di download, creazione e installazione dei pacchetti richiesti. Per gestire le librerie esterne nella vostra applicazione CLI, seguite questi passaggi:
- Inizializzare un modulo Go: Nella directory principale dell'applicazione CLI, eseguire il comando
go mod init <nome modulo>,
sostituendo '<nome modulo>' con il nome del modulo desiderato. Questo comando creerà un nuovo file chiamatogo.mod
nella directory del progetto. - Aggiungere librerie esterne: Ogni volta che si desidera importare una libreria esterna, aggiungere le dichiarazioni di importazione necessarie nel codice sorgente. La prima volta che si costruisce o si esegue il progetto, Go scaricherà e installerà automaticamente le versioni necessarie di tali librerie e aggiornerà i file
go.mod
ego.sum
. - Aggiornare le librerie: Per aggiornare una libreria esterna, potete usare il comando
go get -u
seguito dal nome del pacchetto. Questo aggiorna il pacchetto alla versione più recente, riflettendo le modifiche apportate al filego.mod
. - Rimuovere le librerie inutilizzate: Per eliminare le librerie inutilizzate dal file
go.mod
, eseguire il comandogo mod tidy
. In questo modo si rimuovono le librerie che non sono più necessarie o che sono diventate obsolete durante lo sviluppo.
L'uso dei moduli Go offre diversi vantaggi quando si lavora con librerie esterne. Ad esempio, favorisce la leggibilità del codice e semplifica la gestione delle dipendenze, consentendo un'applicazione CLI più manutenibile e modulare.
Gestione degli errori e registrazione
Una corretta gestione degli errori e la registrazione sono fondamentali per garantire la robustezza dell'applicazione CLI. Go offre un approccio molto pratico ed ergonomico per lavorare con gli errori e i log. Per gestire gli errori in Go, si può utilizzare il pacchetto standard errors
. Ecco alcune buone pratiche per lavorare con gli errori nelle applicazioni CLI:
- Restituire errori anziché panico: Piuttosto che causare il panico e l'arresto dell'applicazione, restituite gli errori dalle funzioni e gestiteli in modo appropriato. Ciò consente di migliorare il flusso di controllo e i meccanismi di recupero dell'applicazione CLI.
- Utilizzare tipi di errore personalizzati: Create i vostri tipi di errore utilizzando la funzione
errors.New
o implementando l'interfacciaerror
. I tipi di errore personalizzati consentono di fornire informazioni più specifiche su ciò che è andato storto quando si verifica un errore. - Gestire gli errori vicino all'origine: Quando possibile, gestire gli errori il più vicino possibile alla loro origine. Questo aiuta a mantenere la semplicità del codice e rende più facile ragionare sulla gestione degli errori in situazioni complesse.
Per la registrazione, la libreria standard di Go offre il pacchetto log
, che fornisce un'interfaccia di registrazione semplice e flessibile. È possibile utilizzare il pacchetto per registrare i messaggi con diversi livelli di gravità e personalizzare il target di output. Per funzionalità di logging più avanzate, si può considerare l'utilizzo di un logging strutturato con il popolare pacchetto github.com/sirupsen/logrus
. Ecco alcuni suggerimenti per un logging efficace nella vostra applicazione CLI:
- Scegliere il giusto livello di registrazione: Utilizzate i livelli di registrazione per distinguere tra errori critici, avvertimenti e messaggi informativi regolari. In questo modo i log sono più fruibili e aiutano a identificare i problemi in modo più efficiente.
- Includere il contesto nei messaggi di log: Quando si registrano i messaggi di log, fornire un contesto pertinente, come i valori delle variabili e i nomi delle funzioni. In questo modo è più facile rintracciare i problemi durante la risoluzione dei problemi.
- Considerare la registrazione strutturata: Usare la registrazione strutturata per emettere i messaggi di log in un formato leggibile dalla macchina, come JSON. Questo è particolarmente utile per i sistemi di log centralizzati, l'aggregazione dei log e gli strumenti di analisi.
Test e benchmark delle applicazioni CLI
La garanzia di qualità è un altro aspetto fondamentale per lo sviluppo di applicazioni CLI affidabili. Il supporto integrato di Go per il testing e il benchmarking consente di scrivere test unitari efficaci e di misurare le prestazioni dell'applicazione CLI. Il pacchetto di test
di Go consente di scrivere test unitari, eseguirli in parallelo e generare rapporti sulla copertura dei test. Utilizzate le seguenti tecniche per migliorare le vostre pratiche di testing:
- Creare funzioni di test: Scrivete delle funzioni di test per i componenti della vostra applicazione CLI e anteponetele a
Test
, comeTestMyFunction
. Collocate queste funzioni in un file_test.go
separato, accanto al file sorgente da testare. - Usare le tabelle di test: Utilizzate le tabelle di test (note anche come test guidati da tabelle) per testare più combinazioni di input-output utilizzando un'unica funzione di test. Questo approccio semplifica il codice di test e lo rende più manutenibile.
- Eseguire i test in parallelo: Sfruttate la funzione
t.Parallel()
all'interno delle vostre funzioni di test per eseguire i test in parallelo. Ciò può accelerare l'esecuzione della suite di test, soprattutto quando si tratta di test che richiedono molte risorse. - Generare rapporti sulla copertura dei test: Utilizzate il comando
go test -cover
per generare rapporti sulla copertura del codice. Questo aiuta a identificare le aree del codice che necessitano di test più approfonditi e garantisce un maggior grado di copertura dei test.
Per misurare le prestazioni dei componenti dell'applicazione CLI, Go fornisce il supporto per il benchmarking attraverso lo stesso pacchetto di test
. Utilizzate i benchmark come segue:
- Creare funzioni di benchmark: Scrivete funzioni di benchmark con il prefisso
Benchmark
, comeBenchmarkMyFunction
. Inserite queste funzioni nello stesso file_test.go
che contiene le funzioni di test pertinenti. - Usare il parametro
testing.B
: Eseguite il codice di cui volete fare il benchmark all'interno di un ciclo controllato dal parametrotesting.B
(ad esempio,for i := 0; i < b.N; i++ { ... }
). Il parametrotesting.B
viene regolato automaticamente dal pacchetto ditest
per ottenere una misurazione statisticamente significativa. - Analizzare i risultati del benchmark: Usate il comando
go test -bench
per eseguire i vostri benchmark e analizzare i risultati. Questo può aiutare a determinare le aree dell'applicazione CLI che necessitano di ottimizzazione e a valutare l'impatto dei miglioramenti delle prestazioni.
In conclusione, la corretta gestione delle librerie esterne, la gestione degli errori, la registrazione, i test e i benchmark sono fondamentali per creare applicazioni CLI affidabili ed efficienti. Sfruttando i vari strumenti, le tecniche e le best practice descritte in questo articolo, potete assicurarvi che la vostra applicazione CLI basata su Go raggiunga un alto livello di qualità ed eccellenza. Inoltre, combinando la potenza di Go con piattaforme versatili come AppMaster, si possono accelerare notevolmente i processi di sviluppo del software, ottenendo così risultati eccezionali.
Distribuzione dell'applicazione CLI
Una volta completato lo sviluppo della vostra applicazione di interfaccia a riga di comando (CLI) in Go, il passo finale è quello di distribuirla e renderla accessibile agli utenti. Il linguaggio di programmazione Go e la sua toolchain di compilazione consentono di creare eseguibili standalone, collegati staticamente, facili da distribuire e condividere su tutte le piattaforme.
Creare l'eseguibile
Per costruire la vostra applicazione Go CLI, usate il comando go build
seguito dal pacchetto o dal file di destinazione:
go build ./path/to/your/package
Oppure:
go build main.go
Questo comando costruisce un file binario eseguibile per la piattaforma corrente (ad esempio, Windows, macOS, Linux) e lo colloca nella directory di lavoro corrente. Per impostazione predefinita, il nome del file binario corrisponde al nome del pacchetto o al nome del file sorgente senza l'estensione (ad esempio, main
).
Tuttavia, è possibile specificare i nomi dei file binari di output e puntare a piattaforme diverse usando il flag -o
e le variabili d'ambiente:
GOOS=linux GOARCH=amd64 go build -o custom-name ./path/to/your/package
Nell'esempio precedente, si impostano le variabili d'ambiente GOOS
e GOARCH
per indicare al processo di compilazione di Go di puntare a Linux con architettura AMD64 e si imposta il nome del file binario di output su custom-name
.
Compilazione incrociata per piattaforme diverse
Go semplifica la compilazione incrociata ed è possibile creare rapidamente eseguibili per diverse piattaforme senza complesse configurazioni di compilazione. Per compilare in modo incrociato la vostra applicazione Go CLI per più piattaforme, impostate le variabili d'ambiente GOOS
e GOARCH
di conseguenza. L'esempio seguente mostra come compilare in modo incrociato un'applicazione Go CLI per Windows, macOS e Linux:
# Per Windows 64-bit GOOS=windows GOARCH=amd64 go build -o mycli-windows.exe ./path/to/package # Per macOS 64-bit GOOS=darwin GOARCH=amd64 go build -o mycli-macos ./path/to/package # Per Linux 64-bit GOOS=linux GOARCH=amd64 go build -o mycli-linux ./path/to/package
Distribuire l'applicazione CLI
È possibile distribuire i file binari eseguibili della Go CLI fornendo opzioni di download diretto sul sito web del progetto o all'interno della documentazione README. In alternativa, si possono distribuire come pacchetti specifici per la piattaforma utilizzando sistemi di pacchettizzazione, repository o gestori di pacchetti. Alcuni popolari sistemi di gestione dei pacchetti sono:
- Homebrew - Un gestore di pacchetti per macOS e Linux con una sintassi facile da usare per installare e gestire i pacchetti.
- APT (sistemi basati su Debian) - Un gestore di pacchetti per distribuzioni Linux basate su Debian come Ubuntu.
- RPM (sistemi basati su Red Hat) - Un gestore di pacchetti per le distribuzioni Linux basate su Red Hat, come Fedora.
Riflessioni finali e risorse
Creare potenti applicazioni CLI con Go è un processo piacevole e gratificante. La semplicità, le prestazioni e i vantaggi della distribuzione binaria rendono Go un linguaggio di programmazione ideale per questo scopo. Mentre continuate a sviluppare le vostre applicazioni Go CLI, prendete in considerazione la possibilità di esplorare altre risorse per ampliare le vostre conoscenze e migliorare le vostre capacità:
- Documentazione ufficiale di Go - Una guida completa sul linguaggio di programmazione Go e sulla sua libreria standard.
- Risorse per l'apprendimento di Go - Un ampio elenco di risorse per l'apprendimento di Go, tra cui tutorial, libri e corsi.
- Awesome Go - Un elenco curato di pacchetti, librerie e risorse Go, suddivisi per argomento.
- Go by Example - Un approccio pratico a Go, con esempi concisi e spiegazioni di varie funzionalità di Go.
Inoltre, considerate l'opportunità di esplorare le piattaforme no-code come AppMaster.io che utilizzano Go (golang) come linguaggio di programmazione backend. AppMaster.io offre un'interfaccia intuitiva di tipo drag-and-drop che consente di sviluppare applicazioni web, mobili e backend senza scrivere una sola riga di codice. Conoscendo Go e le piattaforme no-code come AppMaster.io, sarete ben attrezzati per sviluppare soluzioni software ancora più sofisticate in futuro.