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); } }