Facebook propose en open source son framework Hack Codegen
Pour générer automatiquement du code Hack

Le , par Stéphane le calme, Chroniqueur Actualités
Facebook a publié en open source CodeGen, une bibliothèque qu'il utilise pour générer du code, fournissant un moyen aux développeurs d’automatiser une partie du travail de routine qu'ils font lorsqu’ils travaillent sur des programmes de grande envergure. « Les développeurs à l’extérieur de Facebook peuvent utiliser cet outil pour élever le niveau d'abstraction dans leur code et construire des frameworks plus puissants », a expliqué Alejandro Marcu, un ingénieur logiciel chez Facebook. Il faut dire que les frameworks se sont montrés extrêmement précieux dans le développement de logiciel parce qu’ils permettent d’économiser en temps dans le développement d'une nouvelle application.

Les frameworks sont déclaratifs, ce qui signifie qu'ils permettent au développeur « d’écrire ce qu'ils veulent au lieu de la façon dont ils le veulent », a noté Marcu. Codegen fonctionne avec Hack, un langage de programmation qui ressemble à PHP que Facebook a conçu pour accélérer le développement de son site Web et a publié par la suite en open source afin que les développeurs puissent en profiter.

Avant de se servir de Codegen, les ingénieurs Facebook ont utilisé un patchwork de scripts et des modèles pour générer les morceaux de code qui effectuent des tâches simples mais souvent exécutées, comme aller chercher la date d’anniversaire d'un utilisateur.

Facebook avait des classes pour tous les types d’objet, comme :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
class UserNode extends Node {

  public function getName(): string {
    return $this->data['name'];
  }
  
  public function getBirthdate(): ?int{
    return $this->data['birthdate'] === 0 ? null : $this->data['birthdate'];
  }
}
Chaque classe disposait d’un chargeur qui était relativement simple d’utilisation et qui s’occupait d’accéder au stockage de données et également de remplir le tableau de données. La contrepartie est un mutateur

Code : Sélectionner tout
1
2
3
4
5
6
7
8
class UserMutator extends NodeMutator {
  public function getFields(): array {
    return array(
      'Name' => string_field('name'),
      'Birthdate' => timestamp_field('birthdate')->optional(),
    );
  }
}
Par la suite, le mutateur sera utilisé comme ceci.

Code : Sélectionner tout
1
2
3
4
UserMutator::create()
  ->setName('Jack Smith')
  ->setBirthday($day)
  ->save();
Il faut remarquer que le mutateur surcharge la méthode _call et, même si Facebook a apprécié l’approche grâce à laquelle l’utilisateur déclarait les champs dans le mutateur, la façon dont cela était mis en œuvre avec _call présentait certaines limites. Parmi elles le fait qu’elles ne soient pas typées, le fait que les EDI étaient incapables de compléter le code ou encore que la méthode setter n’était pas définie. Ce qui a conduit l’équipe d’infrastructure produit de Facebook à rechercher une façon d’améliorer l’un de leur système de lecture et d’écriture de données.

« La solution à laquelle nous sommes parvenus était un plus haut niveau d’abstraction, un schéma, qui garderait une description détaillée d’un type d’objet. Alors nous pouvions écrire un script qui pourrait générer le nœud, le mutateur, le chargeur, les tests, etc., directement depuis ce schéma ainsi que définir le stockage (par exemple MySQL db) », a avancé Marcu.

En clair la bibliothèque Codegen simplifie les opérations en permettant à un développeur de créer un schéma qui va contenir un échantillon de code qui pourrait être réutilisé plusieurs fois en plus de générer toutes les fonctionnalités connexes nécessaires comme un chargeur de données et une connexion à la base de données. L’utilisateur fournit des détails sur une mise en œuvre particulière et le logiciel va s’occuper du reste. Il pourra générer des classes, des méthodes, des variables, des fonctions, des fichiers et autres. Par exemple, ceci pourrait être un schéma utilisateur.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
class UserSchema extends NodeSchema {
  protected function getFields(): Map<string, INodeField> {
    return Map{
      'Name' => string_field('name')
        ->description('Full name of the user')
        ->example('John Smith'),
      'Birthdate' => timestamp_field('birthdate')->optional(),
      'Gender' => int_enum_field('gender', UserGender::class),      
    };
  }
}
Si cette structure ressemble à celle du mutateur, elle offre bien plus de possibilités. Par exemple il est possible d’écrire une description et un exemple d’un champ qui seront réécrit automatiquement dans la docblock de la méthode getter.

Concernant les fichiers signés, Marcu explique « nous voulions nous assurer que les ingénieurs n’apportent pas de modifications aux fichiers signés afin que nous puissions régénérer automatiquement un code une fois qu’il change un schéma. Nous aurions pu ajouter des commentaires précisant que le code ne doit pas être modifié mais nous étions inquiets à l’idée qu’ils puissent juste être survolés ». Aussi, Facebook a décidé de faire appel à une bibliothèque déjà fonctionnelle sur Facebook ; elle va faire un hachage des contenus des fichiers et préciser en en-tête que le contenu ne devrait pas être modifié manuellement. Par la suite il pourrait vérifier si les hash correspondent au contenu pour savoir si le fichier a été modifié et des outils vont arrêter de telles tentatives.

Cependant se posait le problème de flexibilité dans certaines sections du code généré, par exemple un champ qui pourrait nécessiter une modification post-génération automatique dans le getter. Facebook a opté pour laisser des sections dans le fichier qui puissent être modifiées manuellement. Le code de génération a été mis à jour afin qu’il puisse tenir compte de ces modifications manuelles.

Essayer CodeGen (dépôt GitHub)

Source : Facebook

Et vous ?

Qu'en pensez-vous ?

forum Libre & Open Source


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :
Contacter le responsable de la rubrique Accueil