<?php namespace LakeDrops\DorgFlow; use Composer\Package\PackageInterface; use Composer\Composer; use Composer\IO\IOInterface; use Composer\Script\Event as ScriptEvent; use GitElephant\Repository; use LakeDrops\Component\Dotenv\Dotenv; use Symfony\Component\Filesystem\Filesystem; class Handler { /** * @var \Composer\Composer */ protected $composer; /** * @var \Composer\IO\IOInterface */ protected $io; /** * Handler constructor. * * @param Composer $composer * @param IOInterface $io */ public function __construct(Composer $composer, IOInterface $io) { $this->composer = $composer; $this->io = $io; } /** * Retrieve a package from the current composer process. * * @param string $name * Name of the package to get from the current composer installation. * * @return PackageInterface */ protected function getPackage($name) { return $this->composer->getRepositoryManager()->getLocalRepository()->findPackage($name, '*'); } /** * Post install/update event to prepare projects for development. * * @param ScriptEvent $event */ public function prepareDevProjects($event) { // We only do the fancy stuff for developers if (!$event->isDevMode()) { return; } $options = $this->getOptions(); if (empty($options['projects'])) { return; } $this->io->write('Dorgflow: Preparing drupol.org packages for development', TRUE); $installationManager = $this->composer->getInstallationManager(); foreach ($options['projects'] as $project => $version) { $package = $this->getPackage($project); if (empty($package)) { continue; } $path = $installationManager->getInstallPath($package); $this->io->write("- $project => $path", TRUE); $this->prepareWorkingDirectory($path, $project, $version, $options['username']); } } /** * Retrieve excludes from optional "extra" configuration. * * @return array */ protected function getOptions() { $env = new Dotenv('dorgflow', $this->io); $extra = $this->composer->getPackage()->getExtra() + ['dorgflow' => []]; $options = $extra['dorgflow'] + [ 'projects' => [], 'username' => $env->receive('drupal_org_username', 'Drupal.org username', getenv('USER')), ]; return $options; } /** * @inheritDoc */ protected function prepareWorkingDirectory($path, $project, $version, $username) { list(, $projectname) = explode('/', $project); $uri = $username . '@git.drupal.org:project/' . $projectname . '.git'; // Git Clone the repository into the working directory $repository = Repository::open($path); $repository->init(); try { $origin = $repository->getRemote('origin', FALSE); if ($origin && $origin->getFetchURL() == $uri) { // Already setup correctly. return; } } catch (\Exception $ex) { // ignore the exception and conitue setup. } $fs = new Filesystem(); $fs->remove($path); $fs->mkdir($path); $repository->init(); $repository->addRemote('origin', $uri); $repository->fetch(); $repository->checkout($version); $repository->getCaller()->execute('branch --set-upstream-to origin/' . $version . ' ' . $version); $this->io->write(" - completed", TRUE); } }