Analyse de dépendances classes/fichiers
Dans mon précédent post sur "Zend Framework 1.8.3 demystified, Act I", je vous avais livré un schéma de dépendances entre packages générés grâce à un de mes outils... Je vous livre maintenant l'outils.
WDependency est un outil réalisé en PHP et utilisant le programme GraphViz/Dot pour générer des graphes de dépendances entre classes , fichiers, projets, packages...
Installation
pear channel-discover pear.phppro.fr pear install --alldeps phppro/wdependency
(Un package requis nommé 'WFramework' sera aussi installé, il s'agit d'un framework d'abstraction que je développe avec mes conventions pour illustrer des pratiques / conventions chez mes clients)
Vérifiez que l'installation c'est bien passée :
wdependency
(Vous devriez voir l'aide repris ci-dessous)
Il est ensuite nécessaire d'installer GraphViz/Dot (le binaire 'dot' doit être accessible en ligne de commande)
Vous pouvez vérifiez si il est installé sur votre poste :
wdependency :check-dot-support
Si la version de dot ne s'affiche pas, c'est que vous devez l'installer, rendez-vous sur http://www.graphviz.org rubrique downloads, téléchargez et installez l'outil dot.
Une fois installé, re-vérifiez que wdependency est bien cablé avec dot en relançant un :
wdependency :check-dot-support
Ensuite pour utiliser l'outil :
cd my-source-directory wdependency :help
Vous obtiendrez l'aide de l'outil ci-dessous :
***** [Syntax] ***************************************************************
$ wdependency [commands] [options] [<directory>[,<directory>,...]]
***** [Available commands] ***************************************************
use: :<command> , ':' is required
:help display this help
:instances computes the instances (use of new operator) dependencies
:cache parses directory content and caches result in all.php for further use
:clean-cache cleans existing cache file
:often-used top rank node that heavily depend on others
:classes computes the classes dependencies (children => mother)
:package0-inheritances computes the classes inheritances reduced to first package level
:package1 computes the classes dependencies reduced to second package level
:inheritances computes the inheritances dependencies
:includes computes the includes dependencies
:packages computes the packages dependencies
:dependent-nodes list all mostly dependent nodes (top ranked)
:check-dot-support display the version of dot binary if available (required for dot/picture export)
:popo list Plain Old PHP Objects (no extends / no implements)
:supers computes the hierarchy dependency (mother => children)
:testcases list all classes that extends PHPUnit_Framework_TestCase
:untestedpackages list all packages that does not contain phpunit test cases
:testedpackages list all packages that contains phpunit test cases
:hubs list all classes that are very used by others
:self-dependent list all classes that are self-dependent (depend on themself)
:dependent list all classes that are dependent to others (more than 4 links to the same)
:very-dependent list all classes that are very dependent to others (more than 10 links to the same)
:extra-dependent list all classes that are extra dependent to others (more than 20 links to the same)
:describe-X display content of specific interface, where X is:
* listener for displaying W_Dependency_Listener_Interface
* exporter for displaying W_Dependency_Exporter_Interface
* analyzer for displaying W_Dependency_Analyzer_Interface
* filter for displaying W_Dependency_Filter_Interface
* aggregator for displaying W_Dependency_Aggregator_Interface
* source for displaying W_Dependency_Source_Interface
* action for displaying W_Dependency_Action_Interface
***** [Available options] ****************************************************
use: -<option> , no value (no '=...')
-v verbose mode, debug information logged in ./wdependency.log
-h display this help
-c activate/use cache file for parsing optimization (generate/use ./wdependency.cache file)
-cc clean existing cache file
use: --<option>=<value> , no default value, '=<value>' is required
--action load custom action(s) (list separator: ,), specified by class name
--aggregator load custom aggregator(s) (list separator: ,), specified by class name
--analyzer load custom analyzer(s) (list separator: ,), specified by class name
--bottom keep only nodes that are in the specified bottom rank (top X) when computing weight from links
--by aggregate nodes using the specified algorithm:
* dir aggregate by directories (dirname on / of node)
* package aggregate by package (dirname on _ of node)
* package#X aggregate by package at position X
* dir#X aggregate by directory at position X
--class keep only nodes that are used by specified class
--dir keep only nodes that are used by file in specified directory
--exporter load custom exporter(s) (list separator: ,), specified by class name
--file keep only nodes that are used by specified file
--filter load custom filter(s) (list separator: ,), specified by class name
--format list of export format:
* png PNG picture file
* jpg JPG picture file
* gif GIF picture file
* dot GraphViz DOT text format
* graphml GraphML xml format
* json JavaScript Object Notation text format
* php PHP file (return array(...);)
* svg Scalable Vector Graphics picture format (xml)
--has keep only nodes that have links
--layout graphviz (dot) layout to use, by default 'dot', type dot -K? to see available list
--link keep only nodes that have link to specified node
--linked-to keep only links to specified dependency
--listener load custom listener(s) (list separator: ,), specified by class name
--load loads the specified file as a data source (from previous analyzes, PHP format supported only)
--max keep only nodes that have a maximum of links specified
--max-link-weight keep only links that have less than specified weight
--min keep only nodes that have at least the minimum links specified
--min-link-weight keep only links that have more than specified weight
--n keep only nodes that have number of nodes specified
--node keep only nodes that are used by specified node
--nolink keep only nodes that have not link to specified node
--none keep only nodes that have no links
--package keep only nodes that are used by class in specified package
--pattern keep only nodes that have name matching specified pattern
--prefix keep only nodes that have name beginning with specified prefix
--reverse reverse link order (user become used and used become user)
--source load custom source(s) (list separator: ,), specified by class name
--subdirs-as-projects use subdirectories as autonomous projects
--template php file template to render export (file exporter only), use $options and $data
--top keep only nodes that are in the specified top rank (top X) when computing weight from links
***** [Additional information] ***********************************************
* additional options could be available dependending on the renderer
template (i.e. phtml view file if used)
* for schema / graph export in dot, png, jpg, ... you must have the
graphviz binaries installed (dot binary)
***** [Software information] *************************************************
wdependency v0.0.7, built on 2009-10-25
Under BSD License, Olivier Hoareau <olivier a t phppro.fr> - PHPPRO
PEAR package
Le principe est simple :
- vous vous positionnez dans le répertoire racine à analyser
- vous indiquez l'action a effectuer et le format d'export voulu
- vous indiquez éventuellement les "filtres / tri" et les "aggrégations" voulues
- vous lancez wdependency avec tous ces paramètres
- wdependency va analyser chaque fichier PHP de répertoires du répertoire courant (récursif)
- il va construire un modèle de donnée en mémoire pour réprésenter les dépendances
- il va trier/filtrer les données
- il va exporter en jpg/png/... (i.e. le(s) format(s) que vous avez choisis)
Exemples
Vous pourrez ensuite générer le graphiques de dépendances entre vos répertoires de second niveau par exemple grâce à la commande :
wdependency :package1
un fichier png devrait apparaître dans le répertoire courant
Ou bien générer le graphe d'héritage de vos classes :
wdependency :inheritances
Le graphe d'héritage d'une classe en particulier :
wdependency :inheritances --node=MyPackage_MyClass
...
Mise en cache du parsing pour aller plus vite
Il est possible de parser une fois et de mettre en cache le modèle de données résultant pour ensuite faire plusieurs "requêtes" sans devoir tout reparser à chaque fois :
Commencez par vider le cache et regénérer le fichier de cache (./wdependency.cache):
wdependency -cc wdependency :cache
Puis exécutez n'importe laquelle des commandes comme d'habitude, vous verrez c'est plus rapide ;)
Bien sûr il s'agit d'une version alpha certainement buggée, merci par avance pour vos retours sur le gestionnaire d'issues : http://code.google.com/p/wdependency/issues/list
Bon usage !
Commentaires
Respects !
Voila un outil des plus intéressants concernant l'OO.
J'utilisais PHPDepends jusqu'à présent, mais ton outil est d'ores et déja dans ma liste ;-)