您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AssetVcsRepository.php 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. <?php
  2. /*
  3. * This file is part of the Fxp Composer Asset Plugin package.
  4. *
  5. * (c) François Pluchino <francois.pluchino@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Fxp\Composer\AssetPlugin\Repository;
  11. use Composer\Package\AliasPackage;
  12. use Composer\Package\BasePackage;
  13. use Composer\Package\CompletePackageInterface;
  14. use Composer\Package\Loader\ArrayLoader;
  15. use Composer\Package\PackageInterface;
  16. use Composer\Repository\InvalidRepositoryException;
  17. use Composer\Repository\Vcs\VcsDriverInterface;
  18. use Fxp\Composer\AssetPlugin\Package\LazyCompletePackage;
  19. use Fxp\Composer\AssetPlugin\Package\Version\VersionParser;
  20. use Fxp\Composer\AssetPlugin\Util\Validator;
  21. /**
  22. * Asset VCS repository.
  23. *
  24. * @author François Pluchino <francois.pluchino@gmail.com>
  25. */
  26. class AssetVcsRepository extends AbstractAssetVcsRepository
  27. {
  28. /**
  29. * {@inheritdoc}
  30. */
  31. protected function initialize()
  32. {
  33. $this->packages = array();
  34. $this->packageName = isset($this->repoConfig['name']) ? Util::cleanPackageName($this->repoConfig['name']) : null;
  35. $driver = $this->initDriver();
  36. $this->initLoader();
  37. $this->initRootIdentifier($driver);
  38. $this->initRegistryVersions();
  39. $this->initTags($driver);
  40. $this->initBranches($driver);
  41. $driver->cleanup();
  42. if (!$this->getPackages()) {
  43. throw new InvalidRepositoryException('No valid '.$this->assetType->getFilename().' was found in any branch or tag of '.$this->url.', could not load a package from it.');
  44. }
  45. }
  46. /**
  47. * Initializes all tags.
  48. *
  49. * @param VcsDriverInterface $driver
  50. */
  51. protected function initTags(VcsDriverInterface $driver)
  52. {
  53. foreach ($driver->getTags() as $tag => $identifier) {
  54. $packageName = $this->createPackageName();
  55. // strip the release- prefix from tags if present
  56. $tag = str_replace(array('release-', 'version/'), '', $tag);
  57. $this->initTag($driver, $packageName, $tag, $identifier);
  58. }
  59. if (!$this->verbose) {
  60. $this->io->overwrite('', false);
  61. }
  62. }
  63. /**
  64. * Initializes the tag: check if tag must be skipped and validate the tag.
  65. *
  66. * @param VcsDriverInterface $driver
  67. * @param string $packageName
  68. * @param string $tag
  69. * @param string $identifier
  70. */
  71. protected function initTag(VcsDriverInterface $driver, $packageName, $tag, $identifier)
  72. {
  73. if (null !== $this->filter && $this->filter->skip($this->assetType, $packageName, $tag)) {
  74. return;
  75. }
  76. if (!$parsedTag = Validator::validateTag($tag, $this->assetType, $this->versionParser)) {
  77. if ($this->verbose) {
  78. $this->io->write('<warning>Skipped tag '.$tag.', invalid tag name</warning>');
  79. }
  80. return;
  81. }
  82. $this->initTagAddPackage($driver, $packageName, $tag, $identifier, $parsedTag);
  83. }
  84. /**
  85. * Initializes the tag: convert data and create package.
  86. *
  87. * @param VcsDriverInterface $driver
  88. * @param string $packageName
  89. * @param string $tag
  90. * @param string $identifier
  91. * @param string $parsedTag
  92. */
  93. protected function initTagAddPackage(VcsDriverInterface $driver, $packageName, $tag, $identifier, $parsedTag)
  94. {
  95. $packageClass = 'Fxp\Composer\AssetPlugin\Package\LazyCompletePackage';
  96. $data = $this->createMockOfPackageConfig($packageName, $tag);
  97. $data['version'] = $this->assetType->getVersionConverter()->convertVersion($tag);
  98. $data['version_normalized'] = $parsedTag;
  99. // make sure tag packages have no -dev flag
  100. $data['version'] = preg_replace('{[.-]?dev$}i', '', (string) $data['version']);
  101. $data['version_normalized'] = preg_replace('{(^dev-|[.-]?dev$)}i', '', (string) $data['version_normalized']);
  102. $packageData = $this->preProcessAsset($data);
  103. $package = $this->loader->load($packageData, $packageClass);
  104. $lazyLoader = $this->createLazyLoader('tag', $identifier, $packageData, $driver);
  105. /* @var LazyCompletePackage $package */
  106. $package->setLoader($lazyLoader);
  107. if (!$this->hasPackage($package)) {
  108. $this->addPackage($package);
  109. }
  110. }
  111. /**
  112. * Initializes all branches.
  113. *
  114. * @param VcsDriverInterface $driver
  115. */
  116. protected function initBranches(VcsDriverInterface $driver)
  117. {
  118. foreach ($driver->getBranches() as $branch => $identifier) {
  119. if (is_array($this->rootData) && $branch === $driver->getRootIdentifier()) {
  120. $this->preInitBranchPackage($driver, $this->rootData, $branch, $identifier);
  121. continue;
  122. }
  123. $this->preInitBranchLazyPackage($driver, $branch, $identifier);
  124. }
  125. if (!$this->verbose) {
  126. $this->io->overwrite('', false);
  127. }
  128. }
  129. /**
  130. * Pre inits the branch of complete package.
  131. *
  132. * @param VcsDriverInterface $driver The vcs driver
  133. * @param array $data The asset package data
  134. * @param string $branch The branch name
  135. * @param string $identifier The branch identifier
  136. */
  137. protected function preInitBranchPackage(VcsDriverInterface $driver, array $data, $branch, $identifier)
  138. {
  139. $packageName = $this->createPackageName();
  140. $data = array_merge($this->createMockOfPackageConfig($packageName, $branch), $data);
  141. $data = $this->preProcessAsset($data);
  142. $data['version'] = $branch;
  143. $data = $this->configureBranchPackage($branch, $data);
  144. if (!isset($data['dist'])) {
  145. $data['dist'] = $driver->getDist($identifier);
  146. }
  147. if (!isset($data['source'])) {
  148. $data['source'] = $driver->getSource($identifier);
  149. }
  150. $loader = new ArrayLoader();
  151. $package = $loader->load($data);
  152. $package = $this->includeBranchAlias($driver, $package, $branch);
  153. $this->addPackage($package);
  154. }
  155. /**
  156. * Pre inits the branch of lazy package.
  157. *
  158. * @param VcsDriverInterface $driver The vcs driver
  159. * @param string $branch The branch name
  160. * @param string $identifier The branch identifier
  161. */
  162. protected function preInitBranchLazyPackage(VcsDriverInterface $driver, $branch, $identifier)
  163. {
  164. $packageName = $this->createPackageName();
  165. $data = $this->createMockOfPackageConfig($packageName, $branch);
  166. $data = $this->configureBranchPackage($branch, $data);
  167. $this->initBranchLazyPackage($driver, $data, $branch, $identifier);
  168. }
  169. /**
  170. * Configures the package of branch.
  171. *
  172. * @param string $branch The branch name
  173. * @param array $data The data
  174. *
  175. * @return array
  176. */
  177. protected function configureBranchPackage($branch, array $data)
  178. {
  179. $parsedBranch = $this->versionParser->normalizeBranch($branch);
  180. $data['version_normalized'] = $parsedBranch;
  181. // make sure branch packages have a dev flag
  182. if ('dev-' === substr((string) $parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) {
  183. $data['version'] = 'dev-'.$data['version'];
  184. } else {
  185. $data['version'] = preg_replace('{(\.9{7})+}', '.x', (string) $parsedBranch);
  186. }
  187. return $data;
  188. }
  189. /**
  190. * Inits the branch of lazy package.
  191. *
  192. * @param VcsDriverInterface $driver The vcs driver
  193. * @param array $data The package data
  194. * @param string $branch The branch name
  195. * @param string $identifier The branch identifier
  196. */
  197. protected function initBranchLazyPackage(VcsDriverInterface $driver, array $data, $branch, $identifier)
  198. {
  199. $packageClass = 'Fxp\Composer\AssetPlugin\Package\LazyCompletePackage';
  200. $packageData = $this->preProcessAsset($data);
  201. /* @var LazyCompletePackage $package */
  202. $package = $this->loader->load($packageData, $packageClass);
  203. $lazyLoader = $this->createLazyLoader('branch', $identifier, $packageData, $driver);
  204. $package->setLoader($lazyLoader);
  205. $package = $this->includeBranchAlias($driver, $package, $branch);
  206. $this->addPackage($package);
  207. }
  208. /**
  209. * Include the package in the alias package if the branch is a root branch
  210. * identifier and having a package version.
  211. *
  212. * @param VcsDriverInterface $driver The vcs driver
  213. * @param PackageInterface $package The package instance
  214. * @param string $branch The branch name
  215. *
  216. * @return PackageInterface|AliasPackage
  217. */
  218. protected function includeBranchAlias(VcsDriverInterface $driver, PackageInterface $package, $branch)
  219. {
  220. if (null !== $this->rootPackageVersion && $branch === $driver->getRootIdentifier()) {
  221. $aliasNormalized = $this->normalizeBranchAlias($package);
  222. $package = $package instanceof AliasPackage ? $package->getAliasOf() : $package;
  223. $package = $this->overrideBranchAliasConfig($package, $aliasNormalized, $branch);
  224. $package = $this->addPackageAliases($package, $aliasNormalized);
  225. }
  226. return $package;
  227. }
  228. /**
  229. * Normalize the alias of branch.
  230. *
  231. * @param PackageInterface $package The package instance
  232. *
  233. * @return string The alias branch name
  234. */
  235. protected function normalizeBranchAlias(PackageInterface $package)
  236. {
  237. $stability = VersionParser::parseStability($this->versionParser->normalize($this->rootPackageVersion));
  238. $aliasNormalized = 'dev-'.$this->rootPackageVersion;
  239. if (BasePackage::STABILITY_STABLE === BasePackage::$stabilities[$stability]
  240. && null === $this->findPackage($package->getName(), $this->rootPackageVersion)) {
  241. $aliasNormalized = $this->versionParser->normalize($this->rootPackageVersion);
  242. }
  243. return $aliasNormalized;
  244. }
  245. /**
  246. * Init the package versions added directly in the Asset Registry.
  247. */
  248. protected function initRegistryVersions()
  249. {
  250. if (isset($this->repoConfig['registry-versions'])) {
  251. /* @var CompletePackageInterface $package */
  252. foreach ($this->repoConfig['registry-versions'] as $package) {
  253. $this->addPackage($package);
  254. }
  255. }
  256. }
  257. }