PathRepository.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Repository;
  12. use Composer\Config;
  13. use Composer\IO\IOInterface;
  14. use Composer\Json\JsonFile;
  15. use Composer\Package\Loader\ArrayLoader;
  16. use Composer\Package\Loader\LoaderInterface;
  17. use Composer\Package\Version\VersionGuesser;
  18. use Composer\Package\Version\VersionParser;
  19. use Composer\Util\ProcessExecutor;
  20. /**
  21. * This repository allows installing local packages that are not necessarily under their own VCS.
  22. *
  23. * The local packages will be symlinked when possible, else they will be copied.
  24. *
  25. * @code
  26. * "require": {
  27. * "<vendor>/<local-package>": "*"
  28. * },
  29. * "repositories": [
  30. * {
  31. * "type": "path",
  32. * "url": "../../relative/path/to/package/"
  33. * },
  34. * {
  35. * "type": "path",
  36. * "url": "/absolute/path/to/package/"
  37. * }
  38. * ]
  39. * @endcode
  40. *
  41. * @author Samuel Roze <samuel.roze@gmail.com>
  42. * @author Johann Reinke <johann.reinke@gmail.com>
  43. */
  44. class PathRepository extends ArrayRepository
  45. {
  46. /**
  47. * @var ArrayLoader
  48. */
  49. private $loader;
  50. /**
  51. * @var VersionGuesser
  52. */
  53. private $versionGuesser;
  54. /**
  55. * @var string
  56. */
  57. private $url;
  58. /**
  59. * @var ProcessExecutor
  60. */
  61. private $process;
  62. /**
  63. * Initializes path repository.
  64. *
  65. * @param array $repoConfig
  66. * @param IOInterface $io
  67. * @param Config $config
  68. */
  69. public function __construct(array $repoConfig, IOInterface $io, Config $config)
  70. {
  71. if (!isset($repoConfig['url'])) {
  72. throw new \RuntimeException('You must specify the `url` configuration for the path repository');
  73. }
  74. $this->loader = new ArrayLoader();
  75. $this->url = $repoConfig['url'];
  76. $this->process = new ProcessExecutor($io);
  77. $this->versionGuesser = new VersionGuesser($config, $this->process, new VersionParser());
  78. parent::__construct();
  79. }
  80. /**
  81. * Initializes path repository.
  82. *
  83. * This method will basically read the folder and add the found package.
  84. */
  85. protected function initialize()
  86. {
  87. parent::initialize();
  88. $path = $this->getPath();
  89. $composerFilePath = $path.'composer.json';
  90. if (!file_exists($composerFilePath)) {
  91. throw new \RuntimeException(sprintf('No `composer.json` file found in path repository "%s"', $path));
  92. }
  93. $json = file_get_contents($composerFilePath);
  94. $package = JsonFile::parseJson($json, $composerFilePath);
  95. $package['dist'] = array(
  96. 'type' => 'path',
  97. 'url' => $this->url,
  98. 'reference' => '',
  99. );
  100. if (!isset($package['version'])) {
  101. $package['version'] = $this->versionGuesser->guessVersion($package, $path) ?: 'dev-master';
  102. }
  103. if (is_dir($path.'/.git') && 0 === $this->process->execute('git log -n1 --pretty=%H', $output, $path)) {
  104. $package['dist']['reference'] = trim($output);
  105. }
  106. $package = $this->loader->load($package);
  107. $this->addPackage($package);
  108. }
  109. /**
  110. * @return string
  111. */
  112. private function getPath()
  113. {
  114. return realpath(rtrim($this->url, '/')) . '/';
  115. }
  116. }