Je me suis fais enchaîner par un blogueur à coquille au marronnier de l'été, la disserte sur les conventions de codage. Je lui en aurait presque voulu de m'acculer à certain aveu intime et douloureux si ça ne m'avait pas permis de découvrir qu'une nouvelle version de PHP CodeSniffer était sortie il y a peu.
J'ai déjà évoqué (ici et là) cette bibliothèque de fonctions développée par Greg Sherwood et intégrée au projet PEAR. La nouvelle version 1.1 comporte des évolutions très intéressantes:
- elle permet désormais l'analyse non seulement des fichiers PHP, mais aussi javascript ! Pour cela, les classes qui explosent le code source en lexèmes (en PHP on parle de tokens) ont été externalisées. On pourra ainsi à l'avenir brancher d'autres analyseurs de code (le but de Greg est de permettre également à terme l'analyse des fichiers CSS, HTML et XML). Une fois le code segmenté en tokens, ceux-ci sont passés au moteur chargé de contrôler le respect de la convention. On peut préciser au niveau de chaque règle de la convention à quels langages elle s'applique. Une même règle (par exemple pour l'indendation) pourra donc être valable pour tous les langages utilisés dans un projet, ou juste pour certains.
- phpcs est désormais fournie avec un "pre-commit hook svn", c'est à dire que si vous utilisez Subversion, vous pouvez contrôler le respect des conventions de codage au moment du commit, et l'interdire en cas de non-respect
- en plus des conventions de PEAR et de celles des projets de Squiz, l'employeur de Greg, la bibliothèque supporte à présent nativement celles du framework Zend, sans avoir besoin d'installer un programme externe.
- phpcs peut s'interfacer avec JavaScript Lint pour valider les fichiers javascript (à condition que celui-ci soit installé sur la machine, bien sûr)
- enfin, le manuel s'est enrichi d'une documentation sur la création de nouvelles convention
Et ce n'est pas fini, car dans un billet récent, Greg indique travailler sur de nouvelles fonctionnalités dont la détection de code dupliqué dans le projet (en reprenant une fonctionnalité de PHPUnit). Cela signifie que PHP CodeSniffer pourra à l'avenir utiliser des règles ne portant pas que sur la syntaxe des fichiers, mais sur l'ensemble du projet.
Créer sa convention
Si les standard fournis par défaut ne vous conviennent pas, vous pouvez créer les vôtres. Il "suffit" pour cela de créer une classe principale et des règles, chaque règle effectuant un certain nombre de tests sur une partie du code. La classe principale permet d'indiquer que la convention se compose, en plus de ses propres règles, de "sniffs" provenant d'autres conventions. On peut ainsi créer facilement un nouveau standard en reprenant des règles existantes. De même, on peut créer de nouvelles règles héritant de règles existantes. Par exemple, une règle "générique" fournie avec la librairie permet de vérifier le nombre d'espaces utilisés pour indenter. Elle fixe ce nombre à 4. Si votre projet utilise 2 espaces, créez une règle qui étend la classe Generic-Sniffs_WhiteSpace_ScopeIndentSniff en modifiant juste la valeur de l'indentation par défaut.
Pour utiliser votre convention par défaut, il suffit de taper:
$ phpcs --config-set default_standard /path/to/your/standard
Bon alors Niko, à quand l'intégration des conventions de Symfony ?
Enfin, vous pouvez utiliser CodeSniffer avec Phing, via une tâche optionnelle (qui ne figure pas encore dans la documentation de la version courante)
PS: ah, et la réponse à la question initiale, quelle sont mes préconisations
en matière de codage ? mais c'est vachement intime comme question !
(autre façon de dire que quand on m'en donne, je les respecte, et sur mes
projets persos, je cherche encore, mélange allégrement tout ce que j'ai appris,
et change d'avis toutes les 2 minutes. Bref, mon code est un souk innommable
Mais peut-être que ce coup-ci CodeSniffer va enfin m'aider à m'astreindre à
un peu plus de rigueur. On peut toujours rêver, mais je vais essayer d'intégrer
progressivement quelques règles au projet). Et comme il faut briser les
chaînes, je ne refourgue celle-ci à personne.