Desarrollando una "version tag" basada en git y renderizada a través de un componente de Blade - Parte I > Blog | Josep Salvà - Desarrollo Web

La palabra de Wifft

Cuando se está desarrollando una aplicación web, hay ocasiones en las que puede ser necesario ofrecer información sobre la versión que está siendo utilizada, para que sea fácilmente cotejable con cierta entrada de un changelog, para facilitar al dev la redacción de este, para facilitar tareas de coworking (sobre todo en aplicaciones bastante modulares y complejas) etc.

En mi caso particular, en cierto momento me surgió esta necesidad en cierto proyecto. Al ser la primera vez que debía plantear algo así, no tenía ningun snipet que me resultara familiar al a hora de implementarlo, así que decidí escribir mi sistema de tagging de versiones desde cero (from scratch).

Dicho proyecto está desarrollado haciendo uso del framework Laravel, escrito en PHP. Desde su versión 6, Laravel permite la implementación de un método de renderizado del DOM en el servidor llamado "Blade Components". Tras consultar la documentación al respecto, procedí a empezar a desarrollar un componente que sirviera para el propósito que buscaba.

Decidí que mi esquema de versionado sería de la siguiente manera versionNumber.buildNumber#hash@branch.buildDate

Así pues, procedí a definir la clase que iría asociada al componente.

namespace App\View\Components;

use Illuminate\View\Component;

final class VersionLabel extends Component
{
    /**
     * @inheritDoc
     */
    public function render() : View
    {
        return view('components.version_label');
    }
}

Acto seguido, definí las propiedades a utilizar. Las propiedades públicas son las que se proporcionan a la vista especificada en el método render() y por tanto, pueden ser accedidas desde el DOM.

private const HEAD_FILENAME = 'HEAD';

private string $gitPath;
private string $branchPath;

public string $versionNumber;
public int $buildNumber;
public string $hash;
public string $branch;
public ?string $buildDate;

Tras esto, procedí a definir un constructor que dotara de valor a todas estas propiedades.

/**
 * Create the component instance.
 */
 public function __construct()
 {
    $this->gitPath = base_path() . '/.git';

    $this->branch = $this->getBranch();
    $this->branchPath = $this->getHead();

    $this->buildDate = null;

    $this->versionNumber = $this->getVersionNumber();
    $this->buildNumber = $this->getBuildNumber();

    $this->hash = substr($this->getHash(), 0, 7);
}

Procedamos a explicar el valor de cada una de ellas. En primer lugar, la propiedad $gitPath toma como valor la ruta absoluta del directorio .git (algo así como /var/www/html/.git), obtenida gracias al helper base_path() ofrecido por el propio Laravel.

$this->gitPath = base_path() . '/.git';

En segundo lugar, la propiedad $branch llama al método getBranch(), definido en el propio objeto, y cuya función es identificar el nombre de la rama de git activa en ese momento y retornar su nombre en forma de string.

/**
  * Gets the name of the current active branch.
  */
private function getBranch(): string
{
    /** @var string */
    $headData = $this->getHead();

    return self::getLastPathItem($headData);
}

Para ello el método llama a su vez a al método getHead(), definido también dentro del propio objeto, y cuya función es la de localizar el fichero HEAD, dentro del directorio .git y obtener su contenido, mediante la función file_get_contents() nativa de PHP.

Luego, únicamente obtiene el nombre de la rama (a partir del quinto carácter) y elimina posibles espacios en blanco al principio y al final de la línea mediante la funciónes nativas de PHP substr() y trim() respectivamente.

/**
 * Gets the HEAD file data.
 */
private function getHead(): string
{
    /** @var string */
    $branchString = file_get_contents($this->gitPath . '/' . self::HEAD_FILENAME);

    /** @var string */
    $branchPath = trim(substr($branchString, 4));

    return $this->gitPath . '/' . $branchPath;
}

Cómo acabamos de ver, el fichero que obtenemos mediante el método getHead() contiene la ruta relativa del directorio que almacena la información del a rama activa. Entonces, para la propiedad $branchPath, simplemente hay que invocarlo asignándolo como valor:

$this->branchPath = $this->getHead();

Y hasta aquí esta primera parte. Hemos visto la idea, sus fundamentos generales, qué funciones hemos utilizado para obtener información de las rama activa, y como se han definido / implementado.

En la segunda parte veremos como obtener los números de versión y compilación.