瀏覽代碼

Merge remote-tracking branch 'xaav/refractor_classes'

Jordi Boggiano 13 年之前
父節點
當前提交
f2effe96df

+ 2 - 1
app/config/config.yml

@@ -59,4 +59,5 @@ fos_user:
     db_driver:     orm
     firewall_name: main
     user_class:  Packagist\WebBundle\Entity\User
-    #from_email:     { webmaster@example.com: Admin }
+    #from_email:     { webmaster@example.com: Admin }
+    

+ 18 - 35
src/Packagist/WebBundle/Command/UpdatePackagesCommand.php

@@ -39,6 +39,7 @@ class UpdatePackagesCommand extends ContainerAwareCommand
             ))
             ->setDescription('Updates packages')
             ->setHelp(<<<EOF
+
 EOF
             )
         ;
@@ -51,6 +52,7 @@ EOF
     {
         $em = $this->getContainer()->get('doctrine')->getEntityManager();
         $logger = $this->getContainer()->get('logger');
+        $provider = $this->getContainer()->get('repository_provider');
 
         $qb = $em->createQueryBuilder();
         $qb->select('p, v')
@@ -60,29 +62,21 @@ EOF
             ->setParameters(array(date('Y-m-d H:i:s', time() - 3600)));
 
         foreach ($qb->getQuery()->getResult() as $package) {
-            $repo = $package->getRepository();
 
             // Process GitHub via API
-            if (preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $repo, $match)) {
-                $owner = $match[1];
-                $repository = $match[2];
-                $output->writeln('Importing '.$owner.'/'.$repository);
-
-                $repoData = json_decode(file_get_contents('http://github.com/api/v2/json/repos/show/'.$owner.'/'.$repository), true);
-                if (!$repoData) {
-                    $output->writeln('Err: Could not fetch data from: '.$repo.', skipping.');
-                    continue;
-                }
+            if ($repo = $provider->getRepository($package->getRepository())) {
 
-                $tagsData = json_decode(file_get_contents('http://github.com/api/v2/json/repos/show/'.$owner.'/'.$repository.'/tags'), true);
+                $output->writeln('Importing '.$repo->getUrl());
 
-                foreach ($tagsData['tags'] as $tag => $hash) {
-                    $data = json_decode(file_get_contents('https://raw.github.com/'.$owner.'/'.$repository.'/'.$hash.'/composer.json'), true);
+                try {
+                    $files = $repo->getAllComposerFiles();
+                }
+                catch (Exception $ex) {
+                    $output->writeln('Err: Could not fetch data from: '.$repo->getUrl().', skipping.');
+                    continue;
+                }
 
-                    // silently skip tags without composer.json, this is expected.
-                    if (!$data) {
-                        continue;
-                    }
+                foreach ($files as $uniqid => $data) {
 
                     // TODO parse $data['version'] w/ composer version parser, if no match, ignore the tag
 
@@ -94,7 +88,7 @@ EOF
                     }
 
                     if ($data['name'] !== $package->getName()) {
-                        $output->writeln('Err: Package name seems to have changed for '.$repo.'@'.$tag.' '.$hash.', skipping');
+                        $output->writeln('Err: Package name seems to have changed for '.$repo->getUrl().'@'.$uniqid.', skipping');
                         continue;
                     }
 
@@ -107,24 +101,13 @@ EOF
                         }
                     }
 
-                    // fetch date from the commit if not specified
-                    if (!isset($data['time'])) {
-                        $commit = json_decode(file_get_contents('http://github.com/api/v2/json/commits/show/'.$owner.'/'.$repository.'/'.$hash), true);
-                        $data['time'] = $commit['commit']['committed_date'];
-                    }
-
                     $version->setPackage($package);
                     $version->setUpdatedAt(new \DateTime);
                     $version->setReleasedAt(new \DateTime($data['time']));
-                    $version->setSource(array('type' => 'git', 'url' => 'http://github.com/'.$owner.'/'.$repository.'.git'));
-
-                    if ($repoData['repository']['has_downloads']) {
-                        $downloadUrl = 'https://github.com/'.$owner.'/'.$repository.'/zipball/'.$tag;
-                        $checksum = hash_file('sha1', $downloadUrl);
-                        $version->setDist(array('type' => 'zip', 'url' => $downloadUrl, 'shasum' => $checksum ?: ''));
-                    } else {
-                        // TODO clone the repo and build/host a zip ourselves. Not sure if this can happen, but it'll be needed for non-GitHub repos anyway
-                    }
+                    $version->setSource(array('type' => $repo->getType(), 'url' => $repo->getUrl()));
+
+                    $checksum = hash_file('sha1', $data['download']);
+                    $version->setDist(array('type' => 'zip', 'url' => $data['download'], 'shasum' => $checksum ?: ''));
 
                     if (isset($data['keywords'])) {
                         foreach ($data['keywords'] as $keyword) {
@@ -178,7 +161,7 @@ EOF
                 // TODO parse composer.json on every branch matching a "$num.x.x" version scheme, + the master one, for all "x.y.z-dev" versions, usable through "latest-dev"
             } else {
                 // TODO support other repos
-                $output->writeln('Err: unsupported repository: '.$repo);
+                $output->writeln('Err: unsupported repository: '.$package->getRepository());
                 continue;
             }
             $package->setUpdatedAt(new \DateTime);

+ 18 - 0
src/Packagist/WebBundle/DependencyInjection/PackagistWebExtension.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Packagist\WebBundle\DependencyInjection;
+
+use Symfony\Component\Config\FileLocator;
+
+use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+
+class PackagistWebExtension extends Extension
+{
+    public function load(array $configs, ContainerBuilder $container)
+    {
+        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+        $loader->load('services.yml');
+    }
+}

+ 20 - 0
src/Packagist/WebBundle/Repository/Provider/GitProvider.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Packagist\WebBundle\Repository\Provider;
+
+use Packagist\WebBundle\Repository\Repository\GitRepository;
+
+class GitProvider implements ProviderInterface
+{
+    public function getRepository($url)
+    {
+        if($this->supports($url)){
+            return new GitRepository($url);
+        }
+    }
+
+    public function supports($url)
+    {
+        return preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $url, $match);
+    }
+}

+ 20 - 0
src/Packagist/WebBundle/Repository/Provider/ProviderInterface.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Packagist\WebBundle\Repository\Provider;
+
+interface ProviderInterface
+{
+    /**
+     * Returns whether the provider supports the URL
+     * @param string $url
+     */
+    public function supports($url);
+
+    /**
+     * Get the repository for the URL.
+     * This method is expected to return null if the URL is not supported.
+     *
+     * @param string $url
+     */
+    public function getRepository($url);
+}

+ 67 - 0
src/Packagist/WebBundle/Repository/Repository/GitRepository.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace Packagist\WebBundle\Repository\Repository;
+
+class GitRepository implements RepositoryInterface
+{
+    protected $owner;
+    protected $repository;
+
+    public function __construct($url)
+    {
+        preg_match('#^(?:https?|git)://github\.com/([^/]+)/(.+?)(?:\.git)?$#', $url, $match);
+        $this->owner = $match[1];
+        $this->repository = $match[2];
+    }
+
+    protected function getRepoData()
+    {
+        return json_decode(file_get_contents('http://github.com/api/v2/json/repos/show/'.$this->owner.'/'.$this->repository), true);
+    }
+
+    public function getType()
+    {
+        return 'git';
+    }
+
+    public function getUrl()
+    {
+        return 'http://github.com/'.$this->owner.'/'.$this->repository.'.git';
+    }
+
+    protected function getDist($tag)
+    {
+        $repoData = $this->getRepoData();
+        if ($repoData['repository']['has_downloads']) {
+            return 'https://github.com/'.$this->owner.'/'.$this->repository.'/zipball/'.$tag;
+        } else {
+            // TODO clone the repo and build/host a zip ourselves. Not sure if this can happen, but it'll be needed for non-GitHub repos anyway
+        }
+    }
+
+    public function getAllComposerFiles()
+    {
+        if(!$repoData = $this->getRepoData()) {
+            throw new \Exception();
+        }
+
+        $files = array();
+
+        $tagsData = json_decode(file_get_contents('http://github.com/api/v2/json/repos/show/'.$this->owner.'/'.$this->repository.'/tags'), true);
+        foreach ($tagsData['tags'] as $tag => $hash) {
+            if($file = json_decode(file_get_contents('https://raw.github.com/'.$this->owner.'/'.$this->repository.'/'.$hash.'/composer.json'), true)) {
+
+                if(!isset($file['time'])) {
+                    $commit = json_decode(file_get_contents('http://github.com/api/v2/json/commits/show/'.$this->owner.'/'.$this->repository.'/'.$tag), true);
+                    $file['time'] = $commit['commit']['committed_date'];
+                }
+
+                $file['download'] = $this->getDist($tag);
+
+                $files[$tag] = $file;
+            }
+        }
+
+        return $files;
+    }
+}

+ 21 - 0
src/Packagist/WebBundle/Repository/Repository/RepositoryInterface.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Packagist\WebBundle\Repository\Repository;
+
+interface RepositoryInterface
+{
+    /**
+     * Return an array of all composer files (by tag).
+     */
+    public function getAllComposerFiles();
+
+    /**
+     * Return the URL of the Repository
+     */
+    public function getUrl();
+
+    /**
+     * Return the type of the repository
+     */
+    public function getType();
+}

+ 24 - 0
src/Packagist/WebBundle/Repository/RepositoryProvider.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Packagist\WebBundle\Repository;
+
+use Packagist\WebBundle\Repository\Provider\ProviderInterface;
+
+class RepositoryProvider implements RepositoryProviderInterface
+{
+    protected $providers = array();
+
+    public function addProvider(ProviderInterface $provider)
+    {
+        $this->providers[] = $provider;
+    }
+
+    public function getRepository($url)
+    {
+        foreach ($this->providers as $provider){
+            if($provider->supports($url)){
+                return $provider->getRepository($url);
+            }
+        }
+    }
+}

+ 12 - 0
src/Packagist/WebBundle/Repository/RepositoryProviderInterface.php

@@ -0,0 +1,12 @@
+<?php
+
+namespace Packagist\WebBundle\Repository;
+
+use Packagist\WebBundle\Repository\Provider\ProviderInterface;
+
+interface RepositoryProviderInterface
+{
+    public function addProvider(ProviderInterface $provider);
+
+    public function getRepository($url);
+}

+ 8 - 0
src/Packagist/WebBundle/Resources/config/services.yml

@@ -0,0 +1,8 @@
+services:
+    git_repository_provider:
+        class: Packagist\WebBundle\Repository\Provider\GitProvider
+        
+    repository_provider:
+        class: Packagist\WebBundle\Repository\RepositoryProvider
+        calls:
+            - [ addProvider, [ @git_repository_provider ] ]