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) {