Introduzione
In Go, un build tag, o una build constraint, è un identificatore aggiunto a un pezzo di codice che determina quando il file dovrebbe essere incluso in un pacchetto durante il processo di build
. Questo consente di costruire diverse versioni della tua applicazione Go dallo stesso codice sorgente e di passare tra di loro in modo rapido e organizzato. Molti sviluppatori utilizzano i build tag per migliorare il flusso di lavoro della creazione di applicazioni compatibili con piattaforme multiple, come programmi che richiedono modifiche al codice per gestire le variazioni tra diversi sistemi operativi. I build tag vengono anche utilizzati per test di integrazione, permettendo di passare rapidamente tra il codice integrato e il codice con un servizio mock o stub, nonché per livelli diversi di funzionalità all’interno di un’applicazione.
Prendiamo come esempio il problema delle diverse caratteristiche dei clienti. Durante la scrittura di alcune applicazioni, potresti voler controllare quali funzionalità includere nel binario, come un’applicazione che offre livelli di Free, Pro e Enterprise. Man mano che il cliente aumenta il proprio livello di abbonamento in queste applicazioni, vengono sbloccate e rese disponibili più funzionalità. Per risolvere questo problema, potresti mantenere progetti separati e cercare di sincronizzarli tra di loro tramite l’uso di statements import
. Anche se questa approccio funzionerebbe, nel tempo diventerebbe noioso e suscettibile di errori. Un approccio alternativo sarebbe utilizzare le build tags.
In questo articolo, userai le build tags in Go per generare diversi eseguibili binari che offrono le caratteristiche Free, Pro e Enterprise di un’applicazione campione. Ogni版本 avrà una diversa serie di funzionalità disponibili, con la versione Free come predefinita.
Prerequisiti
Per seguire l’esempio in questo articolo, avrai bisogno di:
- Un workspace Go configurato seguendo Come installare Go e configurare un ambiente di programmazione locale.
Creazione della versione gratuita
Inizieremo creando la versione gratuita dell’applicazione, poiché sarà quella predefinita quando si eseguirà go build
senza alcun tag di compilazione. Successivamente, useranno i tag di compilazione per aggiungere selettivamente altre parti al nostro programma.
Nella directory src
, creare una cartella con il nome dell’applicazione. Questo tutorial userà app
:
Spostarsi in questa cartella:
Successivamente, creare un nuovo file di testo nel tuo editor di testo preferito chiamato main.go
:
Ora, definiremo la versione gratuita dell’applicazione. Aggiungere il seguente contenuto in main.go
:
In questo file, abbiamo creato un programma che dichiara una slice chiamata features
, che contiene due stringhe che rappresentano le caratteristiche dell’applicazione gratuita. La funzione main()
nell’applicazione utilizza un for
loop per range
attraverso la features
slice e stampa tutte le caratteristiche disponibili sullo schermo.
Salva e esci dal file. Ora che questo file è salvato, non dovremo più modificarlo per il resto dell’articolo. Invece, utilizzeremo le etichette di compilazione per cambiare le caratteristiche dei binari che costruiremo da esso.
Compila e esegui il programma:
Riceverai il seguente output:
Output> Free Feature #1
> Free Feature #2
Il programma ha stampato le nostre due funzionalità gratuite, completando la versione gratuita della nostra app.
Fin’ora, hai creato un’applicazione con un set di funzionalità molto basilare. Prossimamente, creerai un modo per aggiungere più funzionalità all’applicazione al momento della compilazione.
Aggiunta delle funzionalità Pro con go build
Fino ad ora abbiamo evitato di apportare modifiche a main.go
, simulando un ambiente di produzione comune in cui è necessario aggiungere codice senza modificare e possibilmente rompere il codice principale. Dato che non possiamo modificare il file main.go
, dovremo utilizzare un altro meccanismo per iniettare più funzionalità nella slice features
utilizzando le etichette di compilazione.
Crea un nuovo file chiamato pro.go
che utilizzerà una funzione init()
per aggiungere più funzionalità alla slice features
:
Una volta che l’editor ha aperto il file, aggiungi le seguenti righe:
Nell’codice usiamo init()
per eseguire il codice prima della funzione main()
dell’applicazione, seguito da append()
per aggiungere le caratteristiche Pro al slice features
. Salva e esiti il file.
Compila e esegui l’applicazione usando go build
:
Dato che ora ci sono due file nel nostro direttorio corrente (pro.go
e main.go
), go build
creerà un binario dai due file. Esegui questo binario:
Questo ti darà il seguente insieme di caratteristiche:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
L’applicazione ora include sia le caratteristiche Pro che quelle Free. Tuttavia, questo non è desiderabile: poiché non c’è distinzione tra le versioni, la versione Free ora include le caratteristiche che sono destinate solo alla versione Pro. Per risolvere questo problema, potresti includere più codice per gestire i differenti livelli dell’applicazione, oppure potresti usare i tag di compilazione per informare il compilatore Go che file .go
da costruire e quale ignorare. Lasciaci fare questo passaggio successivo.
Aggiungendo i Tag di Compilazione
Puoi ora usare i tag di compilazione per distinguere la versione Pro dell’applicazione dalla versione Free.
Cominciamo ad esaminare come si presenta un tag di compilazione:
Inseriscendo questa riga di codice come prima riga del tuo package e sostituendo tag_name
con il nome del tuo tag di costruzione, sei contrassegnato questo package come codice che può essere incluso selettivamente nel binario finale. Vediamo questo in azione aggiungendo un tag di costruzione al file pro.go
per dirigere al comando go build
a ignorare il file a meno che il tag non sia specificato. Apri il file nel tuo editor di testo:
Poi aggiungi la riga selezionata seguente:
// +build pro
package main
func init() {
features = append(features,
"Pro Feature #1",
"Pro Feature #2",
)
}
Altop della pagina del file pro.go
, abbiamo aggiunto // +build pro
seguito da una riga vuota. Questa riga vuota è obbligatoria, altrimenti Go la interpreta come un commento. Le dichiarazioni di tag di costruzione devono anche essere in alto in un file .go
. Niente, nemmeno i commenti, può essere sopra i tag di costruzione.
La dichiarazione +build
informa il comando go build
che questo non è un commento, ma invece è un tag di costruzione. La seconda parte è il tag pro
. Aggiungendo questo tag in alto nel file pro.go
, il comando go build
ora includerà solo il file pro.go
se il tag pro
è presente.
Compila e esegui l’applicazione di nuovo:
Riceverai l’output seguente:
Output> Free Feature #1
> Free Feature #2
Dato che il file pro.go
richiede un tag pro
per essere presente, il file viene ignorato e l’applicazione viene compilata senza di esso.
Quando si esegue il comando go build
, possiamo usare lo switch -tags
per includere codice nel sorgente compilato condizionalmente aggiungendo il tag stesso come argomento. Facciamo questo per il tag pro
:
Questo produrrà il seguente:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
Ora otteniamo solo le funzionalità extra quando costruiamo l’applicazione utilizzando il tag di compilazione pro
.
Questo è bene se ci sono solo due versioni, ma le cose si complicano quando aggiungi più tag. Per aggiungere la versione Enterprise della nostra app al passo successivo, utilizzeremo più tag di compilazione uniti insieme con la logica booleana.
Logica Booleana dei Tag di Compilazione
Quando ci sono più tag di compilazione in un pacchetto Go, i tag interagiscono tra loro utilizzando la logica booleana. Per dimostrare questo, aggiungeremo il livello Enterprise della nostra applicazione utilizzando sia il tag pro
che il tag enterprise
.
Per costruire un binario Enterprise, dovremo includere sia le funzionalità predefinite, sia le funzionalità del livello Pro, sia un nuovo set di funzionalità per Enterprise. Prima, apri un editor e crea un nuovo file, enterprise.go
, che aggiungerà le nuove funzionalità Enterprise:
Il contenuto di enterprise.go
sarà quasi identico a pro.go
ma conterrà nuove funzionalità. Aggiungi le seguenti righe al file:
Salva e esci dal file.
Attualmente il file enterprise.go
non ha alcun tag di compilazione, e come hai imparato aggiungendo pro.go
, questo significa che queste funzionalità saranno aggiunte alla versione gratuita quando viene eseguito go build
. Per pro.go
, hai aggiunto // +build pro
e un nuovo record in cima al file per informare go build
che questo deve essere incluso solo quando viene utilizzato -tags pro
. In questa situazione, hai solo bisogno di un solo tag di compilazione per raggiungere l’obiettivo. Tuttavia, quando si aggiungono le nuove funzionalità Enterprise, prima devi anche avere le funzionalità Pro.
Aggiungiamo prima supporto per il tag di compilazione pro
a enterprise.go
. Apri il file con il tuo editor di testo:
Aggiungi il tag di compilazione prima della dichiarazione di package main
e assicurati di includere un nuovo record dopo il tag di compilazione:
// +build pro
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Salva e uscire dal file.
Compila e esegui l’applicazione senza alcun tag:
riceverai il seguente output:
Output> Free Feature #1
> Free Feature #2
Le funzionalità Enterprise non appariranno più nella versione gratuita. Ora aggiungi il tag di compilazione pro
e compila e esegui l’applicazione di nuovo:
riceverai il seguente output:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
Questo ancora non è esattamente ciò che serve: le funzionalità Enterprise ora appaiono quando provi a compilare la versione Pro. Per risolvere questo, serve utilizzare un altro tag di compilazione. Tuttavia, ora devi assicurarti che sia disponibile sia il tag pro
che le funzionalità Enterprise.
Il sistema di compilazione Go considera questa situazione permettendo l’uso di un semplice logica booleana nel sistema di tag di compilazione.
Apriremo di nuovo enterprise.go
:
Aggiungiamo un’altra etichetta di costruzione, enterprise
, nella stessa riga dell’etichetta pro
:
// +build pro enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Salva e chiudi il file.
Ora compiliamo e eseguiamo l’applicazione con la nuova etichetta di costruzione enterprise
.
Questo genererà il seguente risultato:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
Adesso abbiamo perso le funzionalità Pro. Questo perché quando mettiamo più etichette di costruzione nella stessa riga in un file .go
, go build
le interpreta come logiche OR. Con l’aggiunta della riga // +build pro enterprise
, il file enterprise.go
sarà compilato sesia presente l’etichetta di costruzione pro
o l’etichetta enterprise
. Dobbiamo impostare le etichette di costruzione correttamente per richiedereentrambe e utilizzare logica AND invece di OR.
Invece di mettere entrambe le etichette nella stessa riga, se le mettiamo in righe separate, allora go build
interpreterà queste etichette usando logica AND.
Apri di nuovo enterprise.go
e separiamo le etichette di costruzione in righe diverse.
// +build pro
// +build enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Ora compiliamo e eseguiamo l’applicazione con la nuova etichetta di costruzione enterprise
.
riceverai l’output seguente:
Output> Free Feature #1
> Free Feature #2
Ancora non proprio lì: Poiché una dichiarazione AND richiede entrambi gli elementi per essere considerati come veri, abbiamo bisogno di usare entrambe le etichette di costruzione pro
e enterprise
.
Prova di nuovo:
Il nostro applicazione può essere costruita da diverse fonti dallo stesso albero di sorgenti, sbloccando le funzionalità dell’applicazione corrispondentemente.
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
Nell’esempio usato abbiamo utilizzato un nuovo tag // +build
per indicare la logica booleana, ma ci sono altri modi di rappresentare la logica booleana con i tag di compilazione. La seguente tabella contiene alcuni esempi di formattazione sintatica alternativa per i tag di compilazione, oltre alla loro equivalenza booleana:
Build Tag Syntax | Build Tag Sample | Boolean Statement |
---|---|---|
Space-separated elements | // +build pro enterprise |
pro OR enterprise |
Comma-separated elements | // +build pro,enterprise |
pro AND enterprise |
Exclamation point elements | // +build !pro |
NOT pro |
Conclusione
Nel presente tutorial, hai usato i tag di compilazione per consentire ai tuoi codici di essere compilati nel binario. In primo luogo, hai dichiarato i tag di compilazione e li hai usati con go build
, poi hai combinato più tag con la logica booleana. Poi hai costruito un programma che rappresentava le diverse caratteristiche della versione Gratuita, Pro, e Enterprise del software, mostrando il livello di controllo potenziale che i tag di compilazione possono dare ai tuoi progetti.
Se vuoi imparare più sui tag di compilazione, guarda la documentazione di Golang sul tema, o continua a esplorare la nostra serie Come scrivere in Go.
Source:
https://www.digitalocean.com/community/tutorials/customizing-go-binaries-with-build-tags