Browse Source

Create the path repository and downloader

Samuel ROZE 9 năm trước cách đây
mục cha
commit
ead68d3d49

+ 1 - 0
composer.json

@@ -29,6 +29,7 @@
         "symfony/console": "~2.5",
         "symfony/finder": "~2.2",
         "symfony/process": "~2.1",
+        "symfony/filesystem": "~2.5",
         "seld/phar-utils": "~1.0",
         "seld/cli-prompt": "~1.0"
     },

+ 51 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "6fbac2ddcd4e9064c84090f6d5514412",
+    "hash": "3024e89a7e808b8dece156112459a7ea",
     "packages": [
         {
             "name": "composer/spdx-licenses",
@@ -328,6 +328,56 @@
             "homepage": "https://symfony.com",
             "time": "2015-07-26 09:08:40"
         },
+        {
+            "name": "symfony/filesystem",
+            "version": "v2.6.11",
+            "target-dir": "Symfony/Component/Filesystem",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Filesystem.git",
+                "reference": "823c035b1a5c13a4924e324d016eb07e70f94735"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Filesystem/zipball/823c035b1a5c13a4924e324d016eb07e70f94735",
+                "reference": "823c035b1a5c13a4924e324d016eb07e70f94735",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "~2.7"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Filesystem\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Filesystem Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-07-08 05:59:48"
+        },
         {
             "name": "symfony/finder",
             "version": "v2.6.11",

+ 50 - 0
src/Composer/Downloader/PathDownloader.php

@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Downloader;
+
+use Composer\Package\PackageInterface;
+use Symfony\Component\Filesystem\Exception\IOException;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * Download a package from a local path.
+ *
+ * @author Samuel Roze <samuel.roze@gmail.com>
+ * @author Johann Reinke <johann.reinke@gmail.com>
+ */
+class PathDownloader extends FileDownloader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function download(PackageInterface $package, $path)
+    {
+        $fileSystem = new Filesystem();
+        if ($fileSystem->exists($path)) {
+            $fileSystem->remove($path);
+        }
+
+        try {
+            $fileSystem->symlink($package->getDistUrl(), $path);
+        } catch (IOException $e) {
+            $fileSystem->mirror($package->getDistUrl(), $path);
+        }
+
+        $this->io->writeError(sprintf(
+            '    Downloaded <info>%s</info> (<comment>%s</comment>) from %s',
+            $package->getName(),
+            $package->getFullPrettyVersion(),
+            $package->getDistUrl()
+        ));
+    }
+}

+ 2 - 0
src/Composer/Factory.php

@@ -331,6 +331,7 @@ class Factory
         $rm->setRepositoryClass('perforce', 'Composer\Repository\VcsRepository');
         $rm->setRepositoryClass('hg', 'Composer\Repository\VcsRepository');
         $rm->setRepositoryClass('artifact', 'Composer\Repository\ArtifactRepository');
+        $rm->setRepositoryClass('path', 'Composer\Repository\PathRepository');
 
         return $rm;
     }
@@ -403,6 +404,7 @@ class Factory
         $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $eventDispatcher, $cache));
         $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $eventDispatcher, $cache));
         $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $eventDispatcher, $cache));
+        $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $eventDispatcher, $cache));
 
         return $dm;
     }

+ 105 - 0
src/Composer/Repository/PathRepository.php

@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Repository;
+
+use Composer\Json\JsonFile;
+use Composer\Package\Loader\ArrayLoader;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * This repository allows installing local packages that are not necessarily under their own VCS.
+ *
+ * The local packages will be symlinked when possible, else they will be copied.
+ *
+ * @code
+ * "require": {
+ *     "<vendor>/<local-package>": "*"
+ * },
+ * "repositories": [
+ *     {
+ *         "type": "path",
+ *         "url": "../../relative/path/to/package/"
+ *     },
+ *     {
+ *         "type": "path",
+ *         "url": "/absolute/path/to/package/"
+ *     }
+ * ]
+ * @endcode
+ *
+ * @author Samuel Roze <samuel.roze@gmail.com>
+ * @author Johann Reinke <johann.reinke@gmail.com>
+ */
+class PathRepository extends ArrayRepository
+{
+    /**
+     * @var Filesystem
+     */
+    private $fileSystem;
+
+    /**
+     * @var ArrayLoader
+     */
+    private $loader;
+
+    /**
+     * @var string
+     */
+    private $path;
+
+    /**
+     * Initializes path repository.
+     *
+     * @param array $config package definition
+     */
+    public function __construct(array $config)
+    {
+        if (!isset($config['url'])) {
+            throw new \RuntimeException('You must specify the `url` configuration for the path repository');
+        }
+
+        $this->fileSystem = new Filesystem();
+        $this->loader = new ArrayLoader();
+        $this->path = realpath(rtrim($config['url'], '/')) . '/';
+    }
+
+    /**
+     * Initializes path repository.
+     *
+     * This method will basically read the folder and add the found package.
+     *
+     */
+    protected function initialize()
+    {
+        parent::initialize();
+
+        $composerFilePath = $this->path.'composer.json';
+        if (!$this->fileSystem->exists($composerFilePath)) {
+            throw new \RuntimeException(sprintf('No `composer.json` file found in path repository "%s"', $this->path));
+        }
+
+        $json = file_get_contents($composerFilePath);
+        $package = JsonFile::parseJson($json, $composerFilePath);
+        $package['dist'] = array(
+            'type' => 'folder',
+            'url' => $this->path,
+        );
+
+        if (!isset($package['version'])) {
+            $package['version'] = 'dev-master';
+        }
+
+        $package = $this->loader->load($package);
+        $this->addPackage($package);
+    }
+}

+ 8 - 1
src/Composer/Util/Filesystem.php

@@ -508,7 +508,14 @@ class Filesystem
         return unlink($path);
     }
 
-    private function isSymlinkedDirectory($directory)
+    /**
+     * return true if that directory is a symlink.
+     *
+     * @param string $directory
+     *
+     * @return bool
+     */
+    public function isSymlinkedDirectory($directory)
     {
         if (!is_dir($directory)) {
             return false;