Uno de los productos que desarrolla mi equipo en el trabajo, tiene actualizaciones muy frecuentes, tanto así que el número de versión se incrementa hasta niveles que resultan poco útiles, sobre todo para rastrear cambios a través del tiempo.
El problema es el siguiente: el producto en cuestión empezó con el número de versión “1.0.0”, luego del primer cambio, la versión aumento a “1.0.1” y después de un tiempo terminamos con la versión “1.0.135”. Uno de mis compañeros ha sugerido que en lugar de incrementar los número así nada mas, dotemos a los campos de la versión de un significado, y dado que no seguimos ningún esquema en particular, podríamos usar el año y el mes en que la versión es publicada, incrementando solamente el último campo, de esta manera, al cambiar de mes reiniciaríamos este último contador a cero. Es decir empezaremos en la versión “21.04.0”, y la siguiente versión será “21.04.1” si esta es liberada en abril de 2021 o “21.05.0” si la versión es liberada hasta el mes de mayo, dándonos una referencia mas útil sobre el contenido de la versión.
Dicho esto, y como muchos programadores me gusta automatizar tareas repetitivas escribí un script que actualice el número de versión por mi.
El proyecto del que te he estado platicando es una biblioteca de componentes de React, por lo que el proyecto es descrito en un archivo package.json
.
El script es el siguiente:
#!/bin/bash package=${1:-package.json} this_month=$(date +%m) this_year=$(date +%y) current_version=$(jq -r '.version' $package) IFS='.' read -r year month n <<< "$current_version" [ $this_month -ne $month ] && year=$this_year && month=$this_month && n=0 || let n++ new_version="$year.$month.$n" echo $(jq ".version = \"$new_version\"" $package) > $package
Es un script pequeño pero que utiliza suficientes recursos como para que valga la pena explicarlos, con la esperanza de que algunas de estas ideas te sirvan para tus proyectos. Veamos en que consiste línea por línea:
Para empezar, la variable $package
está definida tomando el primer argumento desde la línea de comandos (representada por la variable especial $1
, la notación entre llaves sirve para designar un valor por defecto, en este caso: la cadena "package.json"
.
Las siguientes variables $this_month
y $this_year
se definen a partir de la salida del comando date
utilizando una subshell $()
.
this_month=$(date +%m) this_year=$(date +%y)
El siguiente paso consiste en averiguar el valor actual de la versión del paquete, para lo cual nos valemos de dos herramientas: primero el programa jq
que es un poderoso procesador de texto en formato JSON, entre otras cosas jq
te permite consultar porciones de un documento JSON y transformar ese contenido en otro documento JSON con la estructura que tu quieras (comenta si te interesaría una nota explicando a fondo como explotar esta herramienta). En este caso, utilizamos jq
para extraer el valor actual de la versión del paquete, guardando dicho valor en una variable a través de otro subshell.
current_version=$(jq -r '.version' $package)
Acto seguido utilizamos el comando read
que es parte de BASH para dividir la versión del paquete en los tres campos que nos interesan, para conseguir ese resultado, debemos indicarle a BASH que queremos utilizar el caracter punto .
como separador y, asignando ese valor a la variable especial $IFS
, luego utilizamos read
para leer el contenido de la variable $current_version
, guardando los tres campos leídos en las variables $year
, $month
y $n
respectivamente. Recuerda que lo que buscamos es otorgarle significado a cada campo del número de versión, es por ello que elegí esos nombres para estas variables.
IFS='.' read -r year month n <<< "$current_version"
Ahora viene la que realmente es el motivo de existir de este programa: calcular el siguiente número de versión. Para ello, el criterio que utilizo es fijarme en el valor de $month
, y compararlo con el mes actual $this_month
, ya que este será su nuevo significado. Si estos valores no son iguales (-ne
), lo que toca es asignar el año y mes actuales a las variables $year
y $month
así como fijar en cero a la variable $n
; en caso contrario únicamente hace falta incrementar el valor de $n
en uno. Todo ello se consigue en una sola línea gracias a nuestros amigos: los operadores &&
y ||
(comenta si quisieras leer una nota explicando estos operadores).
[ $this_month -ne $month ] && year=$this_year && month=$this_month && n=0 || let n++
Con todos los campos calculados, lo que sigue es construir el nuevo número de versión para finalmente guardarlo en el archivo $package
, para esto nos valemos de los programas echo
y nuevamente jq
.
new_version="$year.$month.$n" echo $(jq ".version = \"$new_version\"" $package) > $package
Lo que sucede aquí es que jq
recibe la orden de cambiar el valor del campo .version
dentro del documento $package
, como resultado jq
imprime el nuevo documento en la salida estándar, pero en lugar de eso nuestro script toma ese texto mediante una subshell a partir de este construye una cadena de texto, y le da la oportunidad a la computadora de cerrar el archivo $package
. Esto es importante porque lo que queremos que haga el programa echo
es sobre escribir el archivo original con el documento modificado que tenemos en memoria.
Suponiendo que todo el código que hemos visto en esta nota lo guardamos en un archivo update.sh
podemos ejecutarlo desde una terminal mediante el comando:
➜ bash update.sh
O bien, dándole permisos de ejecución:
➜ chmod +x update.sh ➜ ./update.sh
En todo caso, el resultado final se debe ver así:
Eso es todo por esta ocasión, espero que esta nota te aporte ideas que te sirvan para tu propios proyectos, nos vemos en la siguiente nota.
Genial
me dijeron que comente. me encanta la bash
no es como creeme hacker.
pero si parametrizar unas instrucciones. con una secuencia logica
pues es lo que estoy aprendiendo . me sale . pero no lo interiorizo
gracias por dejarme el blog. creo que estare tambien pendiente de la serie de VIM
y manejo unas tablas de webscraping. por que el sitio . lo subo un poco manual . y debo comprobar datos
entonces. me gusta el comando column -t, grep , sed , tail, if, while read line ;do ;done, for , crear algunas funciones,. y con algo parecido a tesseract. automatizo la leida y extraida de pdfs. con festival .
que parece a spd-say «el compu me habla», que leyendo el log. podria manejar un mensaje como hola. y mi propia cortana . usando algo de alias.
les comparto mi sacador de libros . poniendo de uso . el script y primer parametro algo de la palabra que es el nombre de el archivo para leer.
prueba.sh
#! /bin/bash
buscado=$(echo «ls | grep $1» && ls | grep $1) && echo $buscado && less $buscado|iconv -f utf-8 -t iso-8859-1|festival –tts
less elartedelaintrusion|iconv -f utf-8 -t iso-8859-1|festival –tts | text2wave
text2wave Mytxt.txt -o MyWav.wav
sed -i ‘s/á/a/g’ «latraduccion.txt»
sed -i ‘s/é/e/g’ «latraduccion.txt»
sed -i ‘s/í/i/g’ «latraduccion.txt»
sed -i ‘s/ó/o/g’ «latraduccion.txt»
sed -i ‘s/ú/u/g’ «latraduccion.txt»
sed -i ‘s/ñ/n/g’ «latraduccion.txt»
tr ‘\n’ ‘ ‘ < input_filename
text2wave latraduccion.txt -o latraduccion.wav && xdg-open $_
sh prueba.sh latraduc
———————————-
la no recuerdo que ocrofeeder . era el que necesitaba.
los amo gracias