Mostrando entradas con la etiqueta Composer. Mostrar todas las entradas
Mostrando entradas con la etiqueta Composer. Mostrar todas las entradas

Los scripts de Composer

ETIQUETA ,

Los scripts de Los scripts de Composer

Los scripts de Composer consisten en callbacks de PHP (definidos como métodos estáticos) o en comandos ejecutables en la consola. Los scripts son muy útiles para ejecutar código o comandos propios del paquete durante la ejecución de Composer.
Ten en cuenta que solamente se ejecutan los scripts del paquete principal, por lo que los scriptsdefinidos en los archivos composer.json de las dependencias no se ejecutan.

Eventos de Composer

Los scripts se ejecutan al producirse alguno de los siguientes eventos definidos por Composer:
  • pre-install-cmd: se notifica antes de ejecutar el comando install.
  • post-install-cmd: se notifica después de ejecutar el comando install.
  • pre-update-cmd: se notifica antes de ejecutar el comando update.
  • post-update-cmd: se notifica después de ejecutar el comando update.
  • pre-package-install: se notifica antes de instalar un paquete.
  • post-package-install: se notifica después de instalar un paquete.
  • pre-package-update: se notifica antes de actualizar un paquete.
  • post-package-update: se notifica después de actualizar un paquete.
  • pre-package-uninstall: se notifica antes de desinstalar un paquete.
  • post-package-uninstall: se notifica antes de desinstalar un paquete.
  • pre-autoload-dump: se notifica antes de regenerar la información del cargador automático de clases, tanto durante la ejecución de los comandos install/update como durante la ejecución del comando dump-autoload.
  • post-autoload-dump: se notifica después de regenerar la información del cargador automático de clases, tanto durante la ejecución de los comandos install/update como durante la ejecución del comando dump-autoload.
  • post-root-package-install: se notifica después de que se haya instalado el paquete principal, durante la ejecución del comando create-project.
  • post-create-project-cmd: se notifica después de la ejecución del comando create-project.

Creando scripts de Composer

Para ejecutar uno o más scripts durante la ejecución de Composer, añade una propiedad llamadascripts en el archivo de configuración composer.json del proyecto. El valor de esta propiedad es un array asociativo que relaciona eventos de Composer con los scripts que se ejecutan durante ese evento. Los scripts se indican mediante una cadena de texto o un array, dependiendo de si ejecutas uno o más scripts para ese evento.
Cuando definas scripts, ten en cuenta que:
  • Los scripts se ejecutan en el mismo orden en el que se definen (siempre y cuando se notifique el evento al que están suscritos).
  • Si asocias más de un script a un mismo evento, puedes mezclar indistintamente callbacks de PHP y comandos de consola.
  • Las clases que contienen los callbacks deben poder cargarse mediante el sistema de carga automática de clases de Composer.
Ejemplo de archivo de configuración composer.json con scripts:
{
    "scripts": {
        "post-update-cmd": "MyVendor\\MyClass::postUpdate",
        "post-package-install": [
            "MyVendor\\MyClass::postPackageInstall"
        ],
        "post-install-cmd": [
            "MyVendor\\MyClass::warmCache",
            "phpunit -c app/"
        ]
    }
}
A continuación se muestra un ejemplo de cómo podría ser la clase MyVendor\MyClass definida en el archivo de configuración anterior:
namespace MyVendor;
 
use Composer\Script\Event;
 
class MyClass
{
    public static function postUpdate(Event $event)
    {
        $composer = $event->getComposer();
        // ...
    }
 
    public static function postPackageInstall(Event $event)
    {
        $installedPackage = $event->getOperation()->getPackage();
        // ...
    }
 
    public static function warmCache(Event $event)
    {
        // ...
    }
}
Cuando se notifica un evento, Composer pasa un objeto de tipo Composer\Script\Event como primer argumento de tu callback. Este objeto dispone de varios getters para obtener fácilmente otros objetos útiles:
  • getComposer(): devuelve una instancia de la clase Composer\Composer.
  • getName(): devuelve una cadena de texto con el nombre del evento que se ha notificado.
    • getIO(): devuelve un objeto que implementa la interfaz Composer\IO\IOInterface y que permite escribir y leer en la consola de comandos.

Auto De Tutorial sowertec16:09

Los archivos binarios de Composer

ETIQUETA

Los archivos binarios de Composer

¿Qué es un archivo binario de Composer?

Los archivos ejecutables o "archivos binarios" de Composer están formados por cualquier script de línea de comandos que el paquete quiera poner a disposición de sus usuarios.
Los scripts que no están pensados para los usuarios del paquete, como por ejemplo scripts de instalación o de compilación del propio paquete, no se consideran archivos binarios de Composer.

Cómo definir un archivo binario

Añade la propiedad bin en el archivo composer.json del proyecto e indica en un array la ruta del archivo binario o las rutas de todos ellos si tu paquete define más de un archivo binario:
{
    "bin": ["bin/my-script", "bin/my-other-script"]
}
La configuración anterior le indica a Composer que debe copiar esos dos archivos ejecutables (llamados comúnmente archivos binarios) en el directorio vendor/bin/ del proyecto.
La idea de los binarios es que los paquetes pongan a disposición del usuario de forma fácil scripts y utilidades que de otra forma estarían "enterrados" dentro de la jerarquía de directorios de vendor/.

Funcionamiento

Cuando tu proyecto define dependencias con paquetes que disponen de archivos binarios, Composer analiza en primer lugar todos los binarios de todas las dependencias. Después, crea un enlace simbólico a cada uno de ellos dentro del directorio vendor/bin.
Imagina que un paquete llamado my-vendor/project-a define los siguientes archivos binarios:
{
    "name": "my-vendor/project-a",
    "bin": ["bin/project-a-bin"]
}
Si ejecutas el comando composer install con este archivo composer.json, los archivos binarios se ignoran y no se crea ningún enlace simbólico. El motivo es que los archivos binarios no se tienen en cuenta cuando se instala el paquete principal.
Si ahora por ejemplo otro paquete llamado my-vendor/project-b declara una dependencia con el paquete my-vendor/project-a anterior:
{
    "name": "my-vendor/project-b",
    "requires": {
        "my-vendor/project-a": "*"
    }
}
Cuando ejecutes ahora el comando composer install con este archivo composer.json, Composer buscará los archivos binarios definidos por las dependencias del paquete project-b y las instalará en el directorio vendor/bin.
De esta forma, el archivo vendor/my-vendor/project-a/bin/project-a-bin se podrá ejecutar simplemente como vendor/bin/project-a-bin. Si tu servidor es de tipo Linux, en vez de copiar los archivos binarios se crean enlaces simbólicos.

¿Qué sucede con los sistemas Windows y los archivos .bat?

Los paquetes gestionados con Composer no tienen que crear archivos de tipo .bat para mantener la compatibilidad con Windows. El motivo es que Composer gestiona la instalación de los archivos binarios en Windows de una forma especial:
  • Composer crea un archivo .bat automáticamente para ejecutar el archivo binario en Windows.
  • Composer crea un archivo con el mismo nombre que el archivo binario original y similar a los enlaces simbólicos de Linux, por si utilizas Composer a través de herramientas como Cygwin.
Si un paquete tiene requerimientos especiales más allá de los que proporciona Composer, puedes crear tus propios archivos .bat. En este caso, no es necesario que incluyas el archivo .bat como binario en la definición del paquete.

Cómo cambiar el directorio de instalación de los binarios

Composer define dos formas diferentes para modificar el directorio en el que se instalan los archivos binarios:
  • Utilizando la propiedad bin-dir del archivo composer.json
  • Estableciendo la variable de entorno COMPOSER_BIN_DIR
A continuación se muestra un ejemplo de la primera opción:
{
    "config": {
        "bin-dir": "scripts"
    }
}
Con esta configuración, al ejecutar el comando composer install, los archivos binarios de los paquetes se instalarán en el directorio scripts/ del proyecto, en vez del tradicional directoriovendor/bin/.

Auto De Tutorial sowertec16:08

Los instaladores propios de Composer

ETIQUETA

Los instaladores propios de Composer

En ocasiones, los paquetes instalados mediante Composer necesitan realizar algunas tareas durante su instalación, como por ejemplo instalar elementos fuera del directorio vendor/ por defecto.
Composer permite crear instaladores propios para definir toda esta lógica específica de cada paquete.

Ejecutando un instalador propio

Suponiendo que ya hayas definido un instalador propio tal y como se explica en la siguiente sección, utilizarlo es tan sencillo como definir el valor adecuado en la propiedad type del archivo composer.jsondel paquete.
Como cada instalador propio define el tipo de paquete que es capaz de instalar, en cuanto Composer encuentra un instalador capaz de instalar un tipo concreto de paquete, se descarta el instalador normal y se ejecuta el instalador propio.
Un ejemplo práctico de la utilidad de los instaladores propios es la librería phpDocumentor, que contiene varias plantillas que deben instalarse fuera del tradicional directorio vendor/. Para ello, sus creadores han decidido definir un tipo especial de paquete llamado phpdocumentor-template y crear un instalador propio que instale las plantillas en el directorio correcto.
El siguiente ejemplo muestra el archivo composer.json de un paquete de este tipo que contenga plantillas:
{
    "name": "phpdocumentor/template-responsive",
    "type": "phpdocumentor-template",
    "require": {
        "phpdocumentor/template-installer": "*"
    }
}
Para asegurarte de que el instalador propio está disponible al instalar un paquete de ese tipo, es muy importante que el paquete añada a su instalador como dependencia mediante la propiedad require.

Creando un instalador propio

Los instaladores propios son simplemente clases que implementan la interfazComposer\Installer\InstallerInterface y se encuentran dentro de algún paquete de Composer de tipo composer-installer.
Por lo tanto, un instalador sencillo está compuesto por dos archivos:
  1. El archivo composer.json que define el paquete.
  2. La clase del instalador, como por ejemplo My\Project\Composer\Installer.php (y que implementa la interfaz Composer\Installer\InstallerInterface).

El archivo composer.json

El archivo composer.json es igual que el de cualquier otro paquete normal de Composer, salvo por las dos siguientes restricciones:
  1. La propiedad type debe ser composer-installer.
  2. La propiedad extra debe contener una propiedad llamada class y cuyo valor define el nombre completo de la clase del instalador (también es necesario incluir el namespace de la clase). Si el paquete define varios instaladores propios, este valor debe ser un array de nombres de clases.
Ejemplo:
{
    "name": "phpdocumentor/template-installer",
    "type": "composer-installer",
    "license": "MIT",
    "autoload": {
        "psr-0": {"phpDocumentor\\Composer": "src/"}
    },
    "extra": {
        "class": "phpDocumentor\\Composer\\TemplateInstaller"
    }
}

La clase del instalador

La clase que define el instalador propio debe implementar la interfazComposer\Installer\InstallerInterface o extender de algún otro instalador que implemente esa interfaz.
Puedes utilizar cualquier nombre para esta clase y puedes colocarla en cualquier directorio, siempre que se pueda cargar de forma automática y su namespace sea el que se indica en la propiedadextra.class del archivo composer.json.
En esta clase también se define el tipo concreto de paquete (en este caso, tipo de instalador) mediante la comprobación que se realiza en el método supports().
Ten mucho cuidado al elegir el valor de la propiedad type, ya que podría entrar en conflicto con los tipos definidos por otros paquetes ajenos a tí. Para evitar posibles colisiones, se recomienda que su valor siga el formato vendor-type (primero el nombre de la persona o empresa que hace el paquete y después, el tipo de paquete concreto), como por ejemplo: phpdocumentor-template.
La clase InstallerInterface define los siguientes métodos (no olvides consultar su código fuente para ver en detalle los parámetros de cada método):
  • supports(), permite comprobar si el valor de la propiedad type coincide con el tipo de paquete definido en el archivo composer.json (observa cómo se realiza esta comprobación en el ejemplo siguiente).
  • isInstalled(), indica si el paquete ya se encuentra instalado o no.
  • install(), este es el método más importante, ya que incluye toda la lógica propia que se debe ejecutar al instalar el paquete.
  • update(), este es el segundo método más importante, ya que incluye la lógica propia que se ejecuta cuando Composer se invoca con el comando update en vez de install.
  • uninstall(), define la lógica que se ejecuta cuando se desinstala el paquete. Asegúrate de borrar y eliminar cualquier archivo o directorio propio de este paquete para dejar el proyecto tal y como estaba antes de instalar este paquete.
  • getInstallPath(), devuelve la ruta donde se va a instalar el paquete. Esta ruta es relativa respecto del directorio donde se encuentr el archivo composer.json.
Ejemplo:
namespace phpDocumentor\Composer;
 
use Composer\Package\PackageInterface;
use Composer\Installer\LibraryInstaller;
 
class TemplateInstaller extends LibraryInstaller
{
    /**
     * {@inheritDoc}
     */
    public function getInstallPath(PackageInterface $package)
    {
        $prefix = substr($package->getPrettyName(), 0, 23);
        if ('phpdocumentor/template-' !== $prefix) {
            throw new \InvalidArgumentException(
                'Unable to install template, phpdocumentor templates '
                .'should always start their package name with '
                .'"phpdocumentor/template-"'
            );
        }
 
        return 'data/templates/'.substr($package->getPrettyName(), 23);
    }
 
    /**
     * {@inheritDoc}
     */
    public function supports($packageType)
    {
        return 'phpdocumentor-template' === $packageType;
    }
}
Este ejemplo muestra lo sencillo que es extender el instalador LibraryInstaller para ajustarse a las necesidades particulares de una librería. En este caso, la librería elimina el prefijophpdocumentor/template- para instalar el paquete en un directorio completamente distinto al original.
El resultado es que en vez de instalarse en el directorio por defecto /vendor, cualquier paquete de este tipo se instalará en el directorio /data/templates/<nombre_corto>.

Auto De Tutorial sowertec16:06

SOWER TEC