Interface en ligne de commande


1Présentation

Il est souvent utile d'écrire des scripts destinés à être exécutés en ligne de commande. C'est quelque chose de très facile à faire en PHP pur, mais vous devez alors initialiser manuellement le log, les sources de données, l'autoloader, l'injection de dépendances…

Temma propose donc la fonctionnalité Comma (COMmand-line MAnager), qui effectue toutes les initialisations nécessaires, avant d'exécuter le code demandé.

L'exécution d'un script se fait en appelant le programme bin/comma, en lui passant en paramètre le nom de l'objet et de la méthode à exécuter, ainsi que les éventuels paramètres supplémentaires attendus par cette méthode.
Le code qui s'exécute peut soit être complètement autonome (et faire son travail à partir des options qui lui auront été fournies), soit entrer dans une communication interactive avec l'utilisateur.

Quelques exemples :

$ bin/comma Cache clear
Cache cleared
$ bin/comma Data import --app=main
Veuillez saisir le chemin vers le fichier à importer : /tmp/import.json
Importation terminée

Commandes proposées par Temma

Temma fournit plusieurs commandes, dont la documentation est accessible dans la section "Helpers" :

  • Cache : Pour vider le cache.
  • User : Pour gérer les utilisateurs (compatible avec le contrôleur/plugin Auth, l'attribut Auth et le plugin Api).

2Documentation

En tapant bin/comma ou bin/comma help, vous pouvez voir la documentation générale de Comma :

En tapant bin/comma help suivi du nom d'un contrôleur, vous pourrez voir la liste des actions de ce contrôleur, avec la documentation associée :

Si vous ajoutez le nom d'une action, vous ne verrez que la documentation de celle-ci :


3Contrôleurs

Les objets exécutés par Comma sont des contrôleurs identiques à ceux utilisés par Temma en réponse aux requêtes HTTP, à ceci près qu'ils doivent être enregistrés dans le répertoire cli/ (et non pas controllers/).

Il y a de nombreuses similitudes :

  • Les actions peuvent prendre un nombre variable de paramètres, avec éventuellement des paramètres optionnels (possédant une valeur par défaut).
  • Les méthodes d'initialisation __wakeup() et de finalisation __sleep() sont exécutées respectivement avant et après l'exécution de l'action.
  • Si aucun nom de méthode n'est fourni en ligne de commande, c'est l'action racine __invoke() qui est appelée. Cette action ne peut pas prendre de paramètres.
  • Si une action par défaut __call() est définie dans le contrôleur, elle sera exécutée pour toutes les actions demandées qui n'ont pas de méthode équivalente.
  • Si une action proxy __proxy() est définie dans le contrôleur, elle sera toujours exécutée, quelle que soit l'action appelée.
  • Les attributs positionnés sur les contrôleurs et les actions sont exécutés (pour autant qu'ils puissent fonctionner dans un environnement en ligne de commande, et non un environnement web).
  • Le fichier de configuration etc/temma.php est lu et son contenu est disponible via l'objet $this->_config.
  • Le composant d'injection de dépendances est généré, et est disponible de la même manière (en écrivant $this->_loader).
  • Les sources de données sont générées et sont disponibles soit par écriture directe (par exemple $this->db), soit en passant par le composant d'injection de dépendance (par exemple $this->_loader->dataSources['db']).
  • Il est possible d'utiliser des DAO.

Mais il y a aussi plusieurs différences :

  • Il n'y a pas de système de routage, même simplifié (il n'est pas possible d'appeler un contrôleur par un autre nom que le sien).
  • Il n'y a pas d'exécution de plugins.
  • Il n'y a pas de vue.
  • L'objet $this->_request ne contient que les paramètres fournis sur la ligne de commande.

4Paramètres

Les paramètres attendus par les actions sont passés en ligne de commande en leur ajoutant le préfixe --, en leur ajoutant ensuite le signe égal (=) suivi de la valeur associée.

Si la valeur contient des espaces, il est possible de la placer entre guillemets (") ou entre apostrophes (').

Si un paramètre est passé sans valeur, il sera considéré comme un booléen de valeur true.


5Exemple

Prenons l'exemple d'un script servant à ajouter un utilisateur en base de données.

Ce script pourrait être appelé de la manière suivante :

$ bin/comma User add --name="Luke Skywalker" --email=luke@rebellion.org

On pourrait imaginer un paramètre optionnel, pour dire que l'utilisateur est une administrateur :

$ bin/comma User add --name=Yoda --email=yoda@rebellion.org --admin=1

Concrètement, Comma va instancier l'objet User, puis appeler sa méthode add() en lui passant les paramètres.

L'objet User doit être stocké dans un fichier nommé User.php, placé dans le répertoire cli/ du projet.
Cet objet doit hériter de l'objet \Temma\Web\Controller.

Le code de cet objet pourrait être :

class User extends \Temma\Web\Controller {
    /** Création de la DAO de connexion à la base de données. */
    protected $_temmaAutoDao = true;

    /**
     * Ajout d'utilisateur.
     * @param  string  $name   Nom de l'utilisateur.
     * @param  string  $email  Adresse mail de l'utilisateur.
     * @param  bool    $admin  (optionnel) Droit administrateur. Faux par défaut.
     */
    public function add(string $name, string $email, bool $admin=false) {
        // ajout de l'utilisateur en base de données
        $id = $this->dao->create([
            'name'  => $name,
            'email' => $email,
            'roles' => $admin ? 'admin' : '',
        ]);
        // message
        print("Utilisateur créé avec l'identfiant '$id'.\n");
    }
}

6Configuration

Par défaut, les scripts en ligne de commande chargent la configuration présente dans le fichier etc/temma.php. Il est possible de fournir le chemin vers un autre fichier en utilisant le paramètre conf.

Ce paramètre doit être placé avant le nom du contrôleur.

Par exemple :

$ bin/comma conf=etc/temma-test.php User add name=Yoda --email=yoda@rebellion.org

Attention, fournir un fichier placé en-dehors de l'arborescence du projet est possible, mais cela ne changera pas les chemins utilisés vers les différents répertoires. Par exemple, le plugin Language continuera à chercher ses fichier dans etc/lang/.


7Chemins d'inclusion

Les scripts exécutés avec Comma se voient ajouté à leurs chemins d'inclusion le répertoire lib/ du projet. Il est possible d'ajouter des chemins supplémentaires avec le paramètre inc.

Comme pour le paramètre conf, ce paramètre doit être placé avant le nom du contrôleur.

Par exemple :

$ bin/comma inc=/autre/projet/src Deploy start

8Log

Par défaut, les scripts en ligne de commande écrivent leur log sur la sortie d'erreur.

Si le fichier etc/temma.php le prévoit, les logs pourront aussi être écrits sur le fichier log/temma.log.

Pour désactiver l'écriture sur la sortie d'erreur, il faut utiliser le paramètre nostderr.

Comme pour les paramètres conf et inc, ce paramètre doit être placé avant le nom du contrôleur.

Exemple :

$ bin/comma nostderr User list

9Interface

L'interface utilisateur est complètement différente de celle des contrôleurs web. Les scripts en ligne de commande interagissent en écrivant sur leur sortie standard, et récupèrent ce que saisit l'utilisateur en lisant sur leur entrée standard.

Temma fournit deux helpers qui sont utiles dans ces conditions :

  • \Temma\Utils\Ansi : fournit des méthodes permettant d'améliorer l'affichage des informations écrite par votre code.
  • \Temma\Utils\Term : offre des fonctionnalités pour interagir plus facilement avec le terminal.