Introducción
En Go, una etiqueta de compilación o una restricción de compilación, es un identificador añadido a una pieza de código que determina cuándo el archivo debe incluirse en un paquete durante el proceso de compilación
. Esto permite construir diferentes versiones de tu aplicación de Go a partir del mismo código fuente y alternar entre ellas de manera rápida y organizada. Muchos desarrolladores utilizan etiquetas de compilación para mejorar el flujo de trabajo de la construcción de aplicaciones compatible con múltiples plataformas, como programas que requieren cambios en el código para abordar las variaciones entre diferentes sistemas operativos. Las etiquetas de compilación también se utilizan para pruebas de integración, permitiendo alternar rápidamente entre el código integrado y el código con un servicio de simulación o stub, así como para diferentes niveles de conjuntos de características dentro de una aplicación.
Tomemos como ejemplo el problema de las diferencias en los conjuntos de características de los clientes. Al escribir algunas aplicaciones, es posible que desee controlar qué características incluir en el binario, como una aplicación que ofrece niveles de Free, Pro y Enterprise. A medida que el cliente aumenta su nivel de suscripción en estas aplicaciones, se desbloquean y se hacen disponibles más características. Para resolver este problema, podría mantener proyectos separados e intentar mantenerlos sincronizados entre sí mediante el uso de declaraciones import
. Si bien este enfoque funcionaría, con el tiempo se volvería aburrido y propenso a errores. Un enfoque alternativo sería usar etiquetas de compilación.
En este artículo, utilizará etiquetas de compilación en Go para generar diferentes binarios ejecutables que ofrecen los conjuntos de características Free, Pro y Enterprise de una aplicación de muestra. Cada uno tendrá un conjunto diferente de características disponibles, con la versión Free como predeterminada.
Requisitos previos
Para seguir el ejemplo en este artículo, necesitará:
- Un espacio de trabajo de Go configurado siguiendo Cómo instalar Go y configurar un entorno de programación local.
Construyendo la versión gratuita
Comencemos por construir la versión Gratuita de la aplicación, ya que será la predeterminada al ejecutar go build
sin ninguna etiqueta de compilación. Más tarde, utilizaremos etiquetas de compilación para añadir selectivamente otras partes a nuestro programa.
En el directorio src
, crea una carpeta con el nombre de tu aplicación. Este tutorial utilizará app
:
Entra en esta carpeta:
A continuación, crea un nuevo archivo de texto en tu editor de texto de elección llamado main.go
:
Ahora, definiremos la versión Gratuita de la aplicación. Añade los siguientes contenidos a main.go
:
En este archivo, hemos creado un programa que declara una rebanada llamada features
, que contiene dos cadeas que representan las características de nuestra aplicación Gratuita. La función main()
de la aplicación utiliza un bucle for
para range
a través de la rebanada features
e imprimir todas las características disponibles en la pantalla.
Guarda y sale del archivo. Ahora que este archivo está guardado, ya no tendremos que editarlo para el resto del artículo. En su lugar, utilizaremos etiquetas de construcción para cambiar las características de los binarios que construiremos a partir de él.
Construye y ejecuta el programa:
Recibirás la siguiente salida:
Output> Free Feature #1
> Free Feature #2
El programa ha impreso nuestras dos características gratuitas, completando la versión gratuita de nuestra aplicación.
Hasta ahora, has creado una aplicación que tiene un conjunto de características muy básicas. A continuación, construirás una manera de agregar más características a la aplicación en el momento de la construcción.
Agregar las características Pro con go build
Hasta ahora, hemos evitado hacer cambios en main.go
, simulando un entorno de producción común en el que se necesita agregar código sin cambiar y posiblemente romper el código principal. Dado que no podemos editar el archivo main.go
, necesitaremos utilizar otro mecanismo para inyectar más características en la rebanada features
utilizando etiquetas de construcción.
Creemos un nuevo archivo llamado pro.go
que utilizará una función init()
para anexar más características a la rebanada features
:
Una vez que el editor haya abierto el archivo, agrega las siguientes líneas:
En este código, utilizamos init()
para ejecutar código antes de la función main()
de nuestra aplicación, seguido de append()
para agregar las características Pro a la rebanada features
. Guarda y sale del archivo.
Compila y ejecuta la aplicación utilizando go build
:
Dado que ahora hay dos archivos en nuestro directorio actual (pro.go
y main.go
), go build
creará un binario a partir de ambos. Ejecuta este binario:
Esto te proporcionará el siguiente conjunto de características:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
La aplicación ahora incluye tanto las características Pro como las Free. Sin embargo, esto no es deseable: dado que no hay distinción entre versiones, la versión Free ahora incluye las características que se suponen que solo están disponibles en la versión Pro. Para arreglar esto, podrías incluir más código para gestionar los diferentes niveles de la aplicación, o podrías utilizar etiquetas de compilación para indicar a la cadena de herramientas de Go qué archivos .go
compilar y cuáles ignorar. Añadamos etiquetas de compilación en el siguiente paso.
Añadiendo Etiquetas de Compilación
Ahora puedes utilizar etiquetas de compilación para distinguir la versión Pro de tu aplicación de la versión Free.
Comencemos examinando cómo se ve una etiqueta de compilación:
Al colocar esta línea de código como la primera línea de su paquete y reemplazar nombre_etiqueta
con el nombre de su etiqueta de compilación, marcará este paquete como código que se puede incluir selectivamente en el binario final. Vamos a ver esto en acción al agregar una etiqueta de compilación al archivo pro.go
para indicar al comando go build
que lo ignore a menos que se especifique la etiqueta. Abra el archivo en su editor de texto:
Agregar luego la siguiente línea resaltada:
// +build pro
package main
func init() {
features = append(features,
"Pro Feature #1",
"Pro Feature #2",
)
}
En la parte superior del archivo pro.go
, añadimos // +build pro
seguido de una nueva línea en blanco. Esta nueva línea al final es obligatoria, de lo contrario Go la interpreta como un comentario. Las declaraciones de etiquetas de compilación también deben estar al principio de un archivo .go
. Nada, ni siquiera los comentarios, pueden estar por encima de las etiquetas de compilación.
La declaración +build
indica al comando go build
que esto no es un comentario, sino una etiqueta de compilación. La segunda parte es la etiqueta pro
. Al agregar esta etiqueta en la parte superior del archivo pro.go
, el comando go build
ahora solo incluirá el archivo pro.go
si la etiqueta pro
está presente.
Compile y ejecute la aplicación nuevamente:
Recibirá la siguiente salida:
Output> Free Feature #1
> Free Feature #2
Dado que el archivo pro.go
requiere que la etiqueta pro
esté presente, el archivo se ignora y la aplicación se compila sin él.
Al ejecutar el comando go build
, podemos usar la bandera -tags
para incluir condicionalmente el código en el fuente compilado al añadir la propia etiqueta como argumento. Hagamos esto para la etiqueta pro
:
Saldrá lo siguiente:
Output> Free Feature #1
> Free Feature #2
> Pro Feature #1
> Pro Feature #2
Ahora solo obtenemos las características adicionales cuando construimos la aplicación utilizando la etiqueta de compilación pro
.
Esto está bien si solo hay dos versiones, pero las cosas se complican cuando añades más etiquetas. Para añadir la versión Enterprise de nuestra aplicación en el siguiente paso, utilizaremos múltiples etiquetas de compilación unidas sammen con lógica booleana.
Lógica Booleana de Etiqueta de Compilación
Cuando hay múltiples etiquetas de compilación en un paquete Go, las etiquetas interactúan entre sí utilizando lógica booleana. Para demostrar esto, añadiremos el nivel Enterprise de nuestra aplicación utilizando tanto la etiqueta pro
como la etiqueta enterprise
.
Para construir un binario Enterprise, necesitaremos incluir tanto las características por defecto y las características de nivel Pro, como un nuevo conjunto de características para Enterprise. Primero, abre un editor y crea un nuevo archivo, enterprise.go
, que añadirá las nuevas características de Enterprise:
El contenido de enterprise.go
será casi idéntico al de pro.go
pero contendrá nuevas características. Añade las siguientes líneas al archivo:
Guarda y sale del archivo.
Actualmente el archivo enterprise.go
no tiene ninguna etiqueta de compilación, y como aprendiste al agregar pro.go
, esto significa que estas características se agregarán a la versión gratuita al ejecutar go.build
. Para pro.go
, agregaste // +build pro
y una nueva línea en la parte superior del archivo para indicarle a go build
que solo debe incluirse cuando se utilice -tags pro
. En esta situación, solo necesitabas una etiqueta de compilación para lograr el objetivo. Sin embargo, al agregar las nuevas características de Enterprise, primero también debes tener las características de Pro.
Vamos a agregar soporte para la etiqueta de compilación pro
en enterprise.go
primero. Abre el archivo con tu editor de texto:
A continuación, agrega la etiqueta de compilación antes de la declaración package main
y asegúrate de incluir una nueva línea después de la etiqueta de compilación:
// +build pro
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Guarda y sale del archivo.
Compila y ejecuta la aplicación sin ninguna etiqueta:
Recibirás la siguiente salida:
Output> Free Feature #1
> Free Feature #2
Las características de Enterprise ya no aparecen en la versión gratuita. Ahora vamos a agregar la etiqueta de compilación pro
y compile y ejecute la aplicación nuevamente:
Recibirás la siguiente salida:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
Esto aún no es exactamente lo que necesitamos: Las características de Enterprise ahora aparecen cuando intentamos compilar la versión Pro. Para resolver esto, necesitamos usar otra etiqueta de compilación. A diferencia de la etiqueta pro
, sin embargo, ahora debemos asegurarnos de que estén disponibles tanto las características de pro
como las de enterprise
.
El sistema de compilación de Go se ocupa de esta situación permitiendo el uso de lógica booleana básica en el sistema de etiquetas de compilación.
Volvamos a abrir enterprise.go
:
Añadamos otra etiqueta de compilación, enterprise
, en la misma línea que la etiqueta pro
:
// +build pro enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Guardamos y cerramos el archivo.
Ahora compilamos y ejecutamos la aplicación con la nueva etiqueta de compilación enterprise
.
Esto nos dará lo siguiente:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
Ahora hemos perdido las características Pro. Esto es porque cuando colocamos múltiples etiquetas de compilación en la misma línea en un archivo .go
, go build
las interpreta como un uso de lógica OR
. Con la adición de la línea // +build pro enterprise
, el archivo enterprise.go
se construirá si cualquiera de las etiquetas de compilación pro
o enterprise
está presente. Necesitamos configurar las etiquetas de compilación correctamente para requerir ambas y usar lógica AND
en su lugar.
En lugar de poner ambas etiquetas en la misma línea, si las colocamos en líneas separadas, entonces go build
interpretará esas etiquetas usando lógica AND
.
Abra nuevamente enterprise.go
y separamos las etiquetas de compilación en múltiples líneas.
// +build pro
// +build enterprise
package main
func init() {
features = append(features,
"Enterprise Feature #1",
"Enterprise Feature #2",
)
}
Ahora compile y ejecute la aplicación con la nueva etiqueta de compilación enterprise
.
Recibirá la siguiente salida:
Output> Free Feature #1
> Free Feature #2
Aún no estamos allí: Dado que una declaración AND
requiere que ambos elementos se consideren true
, necesitamos usar ambas etiquetas de compilación pro
y enterprise
.
Volvamos a intentarlo:
Recibirás la siguiente salida:
Output> Free Feature #1
> Free Feature #2
> Enterprise Feature #1
> Enterprise Feature #2
> Pro Feature #1
> Pro Feature #2
Ahora nuestra aplicación puede construirse desde el mismo árbol de fuentes de múltiples maneras, desbloqueando las características de la aplicación en consecuencia.
En este ejemplo, utilizamos una nueva etiqueta // +build
para significar la lógica AND
, pero hay formas alternativas para representar la lógica booleana con etiquetas de construcción. La siguiente tabla contiene algunos ejemplos de otros formatos sintácticos para etiquetas de construcción, junto con su equivalente booleano:
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 |
Conclusión
En este tutorial, utilizaste etiquetas de construcción para permitirte controlar qué parte de tu código se compila en el binario. Primero, declaraste etiquetas de construcción y las utilizaste con go build
, luego combinaste múltiples etiquetas con lógica booleana. Luego construiste un programa que representaba los diferentes conjuntos de características de una versión Free, Pro y Enterprise, mostrando el poderoso nivel de control que las etiquetas de construcción pueden darle a tu proyecto.
Si deseas aprender más sobre las etiquetas de construcción, echa un vistazo a la documentación de Golang sobre el tema, o continúa explorando nuestra serie How To Code in Go.
Source:
https://www.digitalocean.com/community/tutorials/customizing-go-binaries-with-build-tags