|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Créer les liens «Source» (liens vers Trac ou Redmine ou autre) sur chaque élément
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace autodoc\Plugin\Core\Compiler\Pass;
|
|
|
|
|
|
|
|
|
|
|
|
use autodoc\Plugin\Core\Compiler\Pass\VcsInformations\VcsInformationsAbstract;
|
|
|
|
use autodoc\Plugin\Core\Compiler\Pass\VcsViewer\DefaultViewer;
|
|
|
|
|
|
|
|
|
|
|
|
use phpDocumentor\Compiler\CompilerPassInterface;
|
|
|
|
use phpDocumentor\Descriptor\Collection;
|
|
|
|
use phpDocumentor\Descriptor\DescriptorAbstract;
|
|
|
|
use phpDocumentor\Descriptor\ProjectDescriptor;
|
|
|
|
use phpDocumentor\Descriptor\Tag\LinkDescriptor;
|
|
|
|
|
|
|
|
use Cilex\Application;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Collecter les erreurs
|
|
|
|
*/
|
|
|
|
class VcsLinkBuilder implements CompilerPassInterface
|
|
|
|
{
|
|
|
|
const COMPILER_PRIORITY = 8790;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* L'application
|
|
|
|
*
|
|
|
|
* Pour retrouver la source des fichiers sur le disque
|
|
|
|
*
|
|
|
|
* @var Application
|
|
|
|
**/
|
|
|
|
private $app;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructeur
|
|
|
|
*
|
|
|
|
* @param Application $app
|
|
|
|
**/
|
|
|
|
public function __construct(Application $app) {
|
|
|
|
$this->app = $app;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function getDescription()
|
|
|
|
{
|
|
|
|
return '[Autodoc] Create "source" link on each element';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function execute(ProjectDescriptor $project)
|
|
|
|
{
|
|
|
|
# $is_spip = SpipShare::is_spip($project);
|
|
|
|
|
|
|
|
// retrouver la racine des sources locales…
|
|
|
|
$root = $this->getRoot($project);
|
|
|
|
|
|
|
|
// parcourir les fichiers
|
|
|
|
foreach ($project->getFiles() as $file) {
|
|
|
|
|
|
|
|
$line = $file->getLine();
|
|
|
|
$path = $file->getPath();
|
|
|
|
|
|
|
|
$dir = dirname($path);
|
|
|
|
if ($dir == '.') {
|
|
|
|
$dir = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
$vcs_infos = VcsInformations\Finder::find($root, $dir);
|
|
|
|
$vcs_viewer = $this->getVcsViewer($vcs_infos);
|
|
|
|
$vcs_viewer->setFilename($file->getName());
|
|
|
|
|
|
|
|
// ajouter les tags source
|
|
|
|
$this->addSourceTag($file, $vcs_viewer);
|
|
|
|
|
|
|
|
// fonctions & constantes
|
|
|
|
foreach ($file->getFunctions() as $function) {
|
|
|
|
$this->addSourceTag($function, $vcs_viewer);
|
|
|
|
}
|
|
|
|
foreach ($file->getConstants() as $constant) {
|
|
|
|
$this->addSourceTag($constant, $vcs_viewer);
|
|
|
|
}
|
|
|
|
|
|
|
|
// classes, interfaces, traits
|
|
|
|
foreach (array('getClasses', 'getInterfaces', 'getTraits') as $get) {
|
|
|
|
foreach ($file->$get() as $class) {
|
|
|
|
$this->addSourceTag($class, $vcs_viewer);
|
|
|
|
foreach ($class->getMethods() as $method) {
|
|
|
|
$this->addSourceTag($method, $vcs_viewer);
|
|
|
|
}
|
|
|
|
foreach ($class->getConstants() as $constant) {
|
|
|
|
$this->addSourceTag($constant, $vcs_viewer);
|
|
|
|
}
|
|
|
|
foreach ($class->getProperties() as $property) {
|
|
|
|
$this->addSourceTag($property, $vcs_viewer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Obtenir la racine des sources locales…
|
|
|
|
*
|
|
|
|
* Bien planquée dans le parseur.
|
|
|
|
*
|
|
|
|
* @note
|
|
|
|
* Malheureusement, le parseur n'a pas de methode `getPath()`
|
|
|
|
* On l'obtient de la propriété privée `path` par une réflexion
|
|
|
|
* sur l'instance du parseur.
|
|
|
|
*
|
|
|
|
* @param ProjectDescriptor $project
|
|
|
|
* @return bool
|
|
|
|
**/
|
|
|
|
private function getRoot(ProjectDescriptor $project) {
|
|
|
|
$parser = $this->app['parser'];
|
|
|
|
|
|
|
|
$reflectedParser = new \ReflectionClass( $parser );
|
|
|
|
$property = $reflectedParser->getProperty('path');
|
|
|
|
$property->setAccessible(true);
|
|
|
|
|
|
|
|
return $property->getValue( $parser );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Ajouter un tag Source sur un élément
|
|
|
|
*
|
|
|
|
* @note
|
|
|
|
* Tristement les descripteurs d'éléments n'ont pas connaissance
|
|
|
|
* du numéro de ligne du début du docblock, seulement du numéro
|
|
|
|
* de ligne de l'élément (fonction, méthode, ...)
|
|
|
|
*
|
|
|
|
* C'est ennuyant pour créer les liens vers trac ou redmine :
|
|
|
|
* ils pointent donc après le docblock éventuel.
|
|
|
|
*
|
|
|
|
* @param DescriptorAbstract $element
|
|
|
|
* @param DefaultViewer $vcsViewer
|
|
|
|
**/
|
|
|
|
private function addSourceTag(DescriptorAbstract $element, DefaultViewer $vcsViewer) {
|
|
|
|
// FIXME: (re)Trouver le début du docblock.
|
|
|
|
$vcsViewer->setLine( $element->getLine() );
|
|
|
|
$url = $vcsViewer->getUrl();
|
|
|
|
|
|
|
|
$sourceTag = new LinkDescriptor('source');
|
|
|
|
$sourceTag->setDescription("[Voir en ligne]($url)");
|
|
|
|
$sourceTag->setLink( $url );
|
|
|
|
|
|
|
|
// ajouter le tag aux autres 'source' s'il y en a (aucazou)
|
|
|
|
$sources = $element->getTags()->get('source', new Collection());
|
|
|
|
$sources->add($sourceTag);
|
|
|
|
$element->getTags()->set('source', $sources);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Obtenir un calculateur d'URL des sources des fichiers en ligne
|
|
|
|
*
|
|
|
|
* @param VcsInformationsAbstract $vcs_infos Informations sur le VCS
|
|
|
|
* @return DefaultViewer
|
|
|
|
**/
|
|
|
|
public function getVcsViewer(VcsInformationsAbstract $vcs_infos) {
|
|
|
|
$root = $vcs_infos->getUrlRoot();
|
|
|
|
list($viewer, $url) = $this->source_pour_humains($root);
|
|
|
|
if (is_null($viewer)) $viewer = 'DefaultViewer';
|
|
|
|
|
|
|
|
$VcsViewer = 'autodoc\Plugin\Core\Compiler\Pass\VcsViewer\\' . ucfirst($viewer);
|
|
|
|
if (!class_exists($VcsViewer)) {
|
|
|
|
throw new \Exception('Classe ' . $VcsViewer . ' introuvable.');
|
|
|
|
}
|
|
|
|
|
|
|
|
return new $VcsViewer( $vcs_infos, $url );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retourne l'URL pour un humain d'une source de repository,
|
|
|
|
* si on la connait.
|
|
|
|
*
|
|
|
|
* @todo
|
|
|
|
* Rendre paramétrable en config cette liste d'URLs
|
|
|
|
*
|
|
|
|
* @param string $url_repo URL du repository (svn)
|
|
|
|
* @return array Liste : type de viewer (trac|redmine|autre, sinon null), URL (du viewer, sinon du repository).
|
|
|
|
**/
|
|
|
|
function source_pour_humains($url_repo) {
|
|
|
|
static $connus = array(
|
|
|
|
'svn://zone.spip.org/spip-zone' => array('trac', 'https://zone.spip.org/trac/spip-zone'),
|
|
|
|
'svn://trac.rezo.net/spip' => array('redmine', 'https://core.spip.net/projects/spip'),
|
|
|
|
'https://git.spip.net' => array('gitea', 'https://git.spip.net'),
|
|
|
|
'git@git.spip.net' => array('gitea', 'https://git.spip.net'),
|
|
|
|
'https://github.com' => array('github', 'https://github.com'),
|
|
|
|
'git@github.com' => array('github', 'https://github.com'),
|
|
|
|
'https://gitlab.com' => array('gitlab', 'https://gitlab.com'),
|
|
|
|
'git@gitlab.com' => array('gitlab', 'https://gitlab.com'),
|
|
|
|
);
|
|
|
|
$url_repo = (string) $url_repo;
|
|
|
|
if (isset($connus[$url_repo])) {
|
|
|
|
return $connus[$url_repo];
|
|
|
|
}
|
|
|
|
return array(null, $url_repo);
|
|
|
|
}
|
|
|
|
}
|