diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fd20b6..7d18f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,17 @@ This file is a manually maintained list of changes for each release. Feel free to add your changes here when sending pull requests. Also send corrections if you spot any mistakes. +## 0.2.0 (2013-xx-xx) + +* Feature: Packages can now also be cloned from any git URLs (#9), like this: + +`$ phar-composer build https://github.com/clue/phar-composer.git:dev-master` + ## 0.1.0 (2013-08-12) -* Feature: Packages can now automatically be downloaded and installed prior to generating phar (#7) +* Feature: Packages can now automatically be downloaded and installed prior to generating phar (#7), like this: + +`$ phar-composer build clue/phar-composer:dev-master` ## 0.0.2 (2013-05-25) diff --git a/src/Clue/PharComposer/Command/Build.php b/src/Clue/PharComposer/Command/Build.php index 79b9733..8412539 100644 --- a/src/Clue/PharComposer/Command/Build.php +++ b/src/Clue/PharComposer/Command/Build.php @@ -47,16 +47,69 @@ protected function execute(InputInterface $input, OutputInterface $output) $path = $input->getArgument('path'); - if ($this->isPackageName($path)) { + if ($this->isPackageUrl($path)) { + $url = $path; + $version = null; + + if (preg_match('/(.+)\:((?:dev\-|v\d)\S+)$/i', $url, $match)) { + $url = $match[1]; + $version = $match[2]; + if (substr($version, 0, 4) === 'dev-') { + $version = substr($version, 4); + } + } + + + $path = $this->getDirTemporary(); + + $finder = new ExecutableFinder(); + + $output->write('Cloning ' . $url . ' into temporary directory ' . $path . ''); + + $git = $finder->find('git', '/usr/bin/git'); + + $time = microtime(true); + $this->exec($git . ' clone ' . escapeshellarg($url) . ' ' . escapeshellarg($path), $output); + + if ($version !== null) { + $this->exec($git . ' checkout ' . escapeshellarg($version) . ' 2>&1', $output, $path); + } + + $time = max(microtime(true) - $time, 0); + $output->writeln(''); + $output->writeln(' OK - Cloning base repository completed after ' . round($time, 1) . 's'); + + $pharcomposer = new PharComposer($path . '/composer.json'); + $package = $pharcomposer->getPackageRoot()->getName(); + + if (is_file('composer.phar')) { + $command = $finder->find('php', '/usr/bin/php') . ' composer.phar'; + } else { + $command = $finder->find('composer', '/usr/bin/composer'); + } + + $output->write('Installing dependencies for ' . $package . ' into ' . $path . ' (using ' . $command . ')'); + + $command .= ' install --no-dev --no-progress --no-scripts'; + + $time = microtime(true); + try { + $this->exec($command, $output, $path); + } + catch (UnexpectedValueException $e) { + throw new UnexpectedValueException('Installing dependencies via composer failed', 0, $e); + } + + $time = max(microtime(true) - $time, 0); + $output->writeln(''); + $output->writeln(' OK - Downloading dependencies completed after ' . round($time, 1) . 's'); + } elseif ($this->isPackageName($path)) { if (is_dir($path)) { $output->writeln('There\'s also a directory with the given name'); } $package = $path; - $path = sys_get_temp_dir() . '/phar-composer' . mt_rand(0,9); - while (is_dir($path)) { - $path .= mt_rand(0, 9); - } + $path = $this->getDirTemporary(); $finder = new ExecutableFinder(); if (is_file('composer.phar')) { @@ -139,12 +192,27 @@ private function isPackageName($path) return !!preg_match('/^[^\s\/]+\/[^\s\/]+(\:[^\s]+)?$/i', $path); } - private function exec($cmd, OutputInterface $output) + private function isPackageUrl($path) + { + return (strpos($path, '://') !== false && @parse_url($path) !== false); + } + + private function getDirTemporary() + { + $path = sys_get_temp_dir() . '/phar-composer' . mt_rand(0,9); + while (is_dir($path)) { + $path .= mt_rand(0, 9); + } + + return $path; + } + + private function exec($cmd, OutputInterface $output, $chdir = null) { $ok = true; $nl = true; - $process = new Process($cmd); + $process = new Process($cmd, $chdir); $process->start(); $code = $process->wait(function($type, $data) use ($output, &$ok, &$nl) { if ($nl === true) {