Initial feature-dist
* extends BaseDumper, implements interface * put $keys into BaseDumper * WIP WIP WIP WIP * BaseDumper for utilities * interface to enforce 'dump()' * feature: * supports git * supports zip output * basic test to cover feature * add @todo for later * add vendor namespace to package name * add extension to getFilename() so we don't need to switch in there (HT, @naderman) * add extension (obviously 'zip' in ZipDumper) * create archive in destination dir (provided by __construct()) * condensed ZipDumper * moved code to BaseDumper (hopefully easier re-use) * use ProcessExecutor from BaseDumper * fix assignments in __construct() * allow injection of ProcessExecutor * fix parameters * fix regex * write in 'system temp dir' * update test case (oh look, a duplicate regex) * move working directory related to BaseDumper * add quotes * place holder for these methods * use PharData to create zip/tar when necessary * add placeholder calls * add call to package() using PharData * finish downloadHg(), downloadSvn() * put to use * make BaseDumper abstract (to force extension) * make BaseDumper implement Interface (makes for less code in the implementation) new functionality for dumping as .tar.gz tar instead of tar.gz, new abstract dumpertest class creates a local git repo instead of fetching a remote one more oo-ish version of it no constructor * refactor tests to be less linux-specific (used Composer\Util to wrap calls) * make filename only the version * various cs fixes (idention, tabs/spaces, doc blocks, etc.) * fixed a typo'd exception name * refactored downloading: * removed download*() methods * added dep on Composer\Factory to setup a DownloadManager instance * update CS with feedback from @stof * ArrayDumper doesn't extend BaseDumper anymore (hence no conflict on the interface) * move keys from BaseDumper back to ArrayDumper * interface now declares dump() to always return void Apparently I had to update the lock. CS fixes (tabs for spaces) Bugfix: sprintf() was missing. Fix docblock for @stof. ;) Pull in lock from master. Update lock one more time (hope it still merges). whitespace Revert ArrayDumper static keyspull/1567/head
parent
6f0a71a158
commit
2acb033057
|
@ -0,0 +1,166 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
use Composer\Util\ProcessExecutor;
|
||||||
|
use Composer\Downloader\GitDownloader;
|
||||||
|
use Composer\Downloader\HgDownloader;
|
||||||
|
use Composer\Downloader\SvnDownloader;
|
||||||
|
use Composer\IO\NullIO;
|
||||||
|
use Composer\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
*/
|
||||||
|
abstract class BaseDumper implements DumperInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Format: zip or tar.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $format = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Path to where to dump the export to.
|
||||||
|
* @var mixed|null
|
||||||
|
*/
|
||||||
|
protected $path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ProcessExecutor
|
||||||
|
*/
|
||||||
|
protected $process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Working directory.
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $temp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $path
|
||||||
|
* @param ProcessExecutor|null $process
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct($path = null, ProcessExecutor $process = null)
|
||||||
|
{
|
||||||
|
if (!empty($path)) {
|
||||||
|
if (!is_writable($path)) {
|
||||||
|
throw new \InvalidArgumentException("Not authorized to write to '{$path}'");
|
||||||
|
}
|
||||||
|
$this->path = $path;
|
||||||
|
}
|
||||||
|
$this->process = $process ?: new ProcessExecutor();
|
||||||
|
$this->temp = sys_get_temp_dir();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Composer\Downloader\DownloadManager
|
||||||
|
*/
|
||||||
|
public function getDownloadManager()
|
||||||
|
{
|
||||||
|
$factory = new Factory;
|
||||||
|
$dm = $factory->createDownloadManager(new NullIO());
|
||||||
|
return $dm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PackageInterface $package
|
||||||
|
* @param string $extension
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \InvalidArgumentException When unknown 'format' is encountered.
|
||||||
|
*/
|
||||||
|
public function getFilename(PackageInterface $package, $extension)
|
||||||
|
{
|
||||||
|
$name = $package->getPrettyVersion();
|
||||||
|
$fileName = sprintf('%s.%s', $name, $extension);
|
||||||
|
return $fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PackageInterface $package
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
protected function getAndEnsureWorkDirectory(PackageInterface $package)
|
||||||
|
{
|
||||||
|
$workDir = sprintf('%s/%s/%s', $this->temp, $this->format, $package->getName());
|
||||||
|
if (!file_exists($workDir)) {
|
||||||
|
mkdir($workDir, 0777, true);
|
||||||
|
}
|
||||||
|
if (!file_exists($workDir)) {
|
||||||
|
throw new \RuntimeException("Could not find '{$workDir}' directory.");
|
||||||
|
}
|
||||||
|
return $workDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package the given directory into an archive.
|
||||||
|
*
|
||||||
|
* The format is most likely \Phar::TAR or \Phar::ZIP.
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
* @param string $workDir
|
||||||
|
* @param int $format
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
protected function package($filename, $workDir, $format)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$phar = new \PharData($filename, null, null, $format);
|
||||||
|
$phar->buildFromDirectory($workDir);
|
||||||
|
} catch (\UnexpectedValueException $e) {
|
||||||
|
$message = "Original PHAR exception: " . (string) $e;
|
||||||
|
$message .= PHP_EOL . PHP_EOL;
|
||||||
|
$message .= sprintf("Could not create archive '%s' from '%s'.", $filename, $workDir);
|
||||||
|
throw new \RuntimeException($message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fileName
|
||||||
|
* @param string $sourceRef
|
||||||
|
* @param string $workDir
|
||||||
|
*/
|
||||||
|
protected function packageGit($fileName, $sourceRef, $workDir)
|
||||||
|
{
|
||||||
|
$command = sprintf(
|
||||||
|
'git archive --format %s --output %s %s',
|
||||||
|
$this->format,
|
||||||
|
escapeshellarg(sprintf('%s/%s', $this->path, $fileName)),
|
||||||
|
$sourceRef
|
||||||
|
);
|
||||||
|
$this->process->execute($command, $output, $workDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fileName
|
||||||
|
* @param string $sourceRef
|
||||||
|
* @param string $workDir
|
||||||
|
*/
|
||||||
|
protected function packageHg($fileName, $sourceRef, $workDir)
|
||||||
|
{
|
||||||
|
$format = ($this->format == 'tarball')?'tar':$this->format;
|
||||||
|
$command = sprintf(
|
||||||
|
'hg archive --rev %s --type %s %s',
|
||||||
|
$sourceRef,
|
||||||
|
$format,
|
||||||
|
escapeshellarg(sprintf('%s/%s', $this->path, $fileName))
|
||||||
|
);
|
||||||
|
$this->process->execute($command, $output, $workDir);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
namespace Composer\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
*/
|
||||||
|
interface DumperInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return value depends on implementation - e.g. generating a tar or zip the
|
||||||
|
* method currently returns void, the ArrayDumper returns an array.
|
||||||
|
*
|
||||||
|
* @param PackageInterface $package
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function dump(PackageInterface $package);
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\Dumper\BaseDumper;
|
||||||
|
use Composer\Package\Dumper\DumperInterface;
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
use Composer\Util\ProcessExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ulf Härnhammar <ulfharn@gmail.com>
|
||||||
|
*/
|
||||||
|
class TarDumper extends BaseDumper
|
||||||
|
{
|
||||||
|
protected $format = 'tar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PackageInterface $package
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function dump(PackageInterface $package)
|
||||||
|
{
|
||||||
|
$workDir = $this->getAndEnsureWorkDirectory($package);
|
||||||
|
|
||||||
|
$fileName = $this->getFilename($package, 'tar');
|
||||||
|
$sourceType = $package->getSourceType();
|
||||||
|
$sourceRef = $package->getSourceReference();
|
||||||
|
|
||||||
|
$dm = $this->getDownloadManager();
|
||||||
|
$dm->download($package, $workDir, true);
|
||||||
|
|
||||||
|
switch ($sourceType) {
|
||||||
|
case 'git':
|
||||||
|
$this->packageGit($fileName, $sourceRef, $workDir);
|
||||||
|
break;
|
||||||
|
case 'hg':
|
||||||
|
$this->packageHg($fileName, $sourceRef, $workDir);
|
||||||
|
break;
|
||||||
|
case 'svn':
|
||||||
|
$dir = $workDir . (substr($sourceRef, 0, 1) !== '/')?'/':'' . $sourceRef;
|
||||||
|
$this->package($fileName, $dir, \Phar::TAR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
"Unable to handle repositories of type '{$sourceType}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\Dumper\BaseDumper;
|
||||||
|
use Composer\Package\Dumper\DumperInterface;
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
use Composer\Util\ProcessExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
*/
|
||||||
|
class ZipDumper extends BaseDumper
|
||||||
|
{
|
||||||
|
protected $format = 'zip';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PackageInterface $package
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function dump(PackageInterface $package)
|
||||||
|
{
|
||||||
|
$workDir = $this->getAndEnsureWorkDirectory($package);
|
||||||
|
|
||||||
|
$fileName = $this->getFilename($package, 'zip');
|
||||||
|
$sourceType = $package->getSourceType();
|
||||||
|
$sourceRef = $package->getSourceReference();
|
||||||
|
|
||||||
|
$dm = $this->getDownloadManager();
|
||||||
|
$dm->download($package, $workDir, true);
|
||||||
|
|
||||||
|
switch ($sourceType) {
|
||||||
|
case 'git':
|
||||||
|
$this->packageGit($fileName, $sourceRef, $workDir);
|
||||||
|
break;
|
||||||
|
case 'hg':
|
||||||
|
$this->packageHg($fileName, $sourceRef, $workDir);
|
||||||
|
break;
|
||||||
|
case 'svn':
|
||||||
|
$dir = $workDir . (substr($sourceRef, 0, 1) !== '/')?'/':'' . $sourceRef;
|
||||||
|
$this->package($fileName, $dir, \Phar::ZIP);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new \InvalidArgumentException("Unable to handle repositories of type '{$sourceType}'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Test\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\MemoryPackage;
|
||||||
|
use Composer\Util\Filesystem;
|
||||||
|
use Composer\Util\ProcessExecutor;
|
||||||
|
|
||||||
|
abstract class DumperTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Composer\Util\Filesystem
|
||||||
|
*/
|
||||||
|
protected $fs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Composer\Util\ProcessExecutor
|
||||||
|
*/
|
||||||
|
protected $process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $testdir = '';
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->fs = new Filesystem;
|
||||||
|
$this->process = new ProcessExecutor;
|
||||||
|
$this->testdir = sys_get_temp_dir() . '/composer_dumpertest_git_repository' . mt_rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTestDir()
|
||||||
|
{
|
||||||
|
return $this->testdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create local git repository to run tests against!
|
||||||
|
*/
|
||||||
|
protected function setupGitRepo()
|
||||||
|
{
|
||||||
|
$td = $this->getTestDir();
|
||||||
|
|
||||||
|
$this->fs->removeDirectory($td);
|
||||||
|
$this->fs->ensureDirectoryExists($td);
|
||||||
|
|
||||||
|
$currentWorkDir = getcwd();
|
||||||
|
chdir($td);
|
||||||
|
|
||||||
|
$result = $this->process->execute("git init -q");
|
||||||
|
if ($result > 0) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
"Could not init: " . $this->process->getErrorOutput());
|
||||||
|
}
|
||||||
|
$result = file_put_contents('b', 'a');
|
||||||
|
if (false === $result) {
|
||||||
|
throw new \RuntimeException("Could not save file.");
|
||||||
|
}
|
||||||
|
$result = $this->process->execute("git add b && git commit -m 'commit b' -q");
|
||||||
|
if ($result > 0) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
"Could not init: " . $this->process->getErrorOutput());
|
||||||
|
}
|
||||||
|
chdir($currentWorkDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function removeGitRepo()
|
||||||
|
{
|
||||||
|
$td = $this->getTestDir();
|
||||||
|
$this->fs->removeDirectory($td);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setupPackage()
|
||||||
|
{
|
||||||
|
$td = $this->getTestDir();
|
||||||
|
$package = new MemoryPackage('dumpertest/dumpertest', 'master', 'master');
|
||||||
|
$package->setSourceUrl("file://$td");
|
||||||
|
$package->setSourceReference('master');
|
||||||
|
$package->setSourceType('git');
|
||||||
|
return $package;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPackageFileName(MemoryPackage $package)
|
||||||
|
{
|
||||||
|
return $package->getVersion();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Test\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\Dumper\TarDumper;
|
||||||
|
|
||||||
|
class TarDumperTest extends DumperTest
|
||||||
|
{
|
||||||
|
public function testThis()
|
||||||
|
{
|
||||||
|
$this->setupGitRepo();
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
$name = $this->getPackageFileName($package);
|
||||||
|
|
||||||
|
$temp = sys_get_temp_dir();
|
||||||
|
$tar = new TarDumper($temp);
|
||||||
|
$tar->dump($package);
|
||||||
|
|
||||||
|
$dist = sprintf('%s/%s.tar',
|
||||||
|
$temp, $name
|
||||||
|
);
|
||||||
|
$this->assertFileExists($dist);
|
||||||
|
unlink($dist);
|
||||||
|
$this->removeGitRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testException()
|
||||||
|
{
|
||||||
|
new TarDumper("/totally-random-" . time());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Test\Package\Dumper;
|
||||||
|
|
||||||
|
use Composer\Package\Dumper\ZipDumper;
|
||||||
|
|
||||||
|
class ZipDumperTest extends DumperTest
|
||||||
|
{
|
||||||
|
public function testThis()
|
||||||
|
{
|
||||||
|
$this->setupGitRepo();
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
$name = $this->getPackageFileName($package);
|
||||||
|
|
||||||
|
$temp = sys_get_temp_dir();
|
||||||
|
$zip = new ZipDumper($temp);
|
||||||
|
$zip->dump($package);
|
||||||
|
|
||||||
|
$dist = sprintf('%s/%s.zip',
|
||||||
|
$temp, $name
|
||||||
|
);
|
||||||
|
$this->assertFileExists($dist);
|
||||||
|
unlink($dist);
|
||||||
|
$this->removeGitRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testException()
|
||||||
|
{
|
||||||
|
new ZipDumper("/totally-random-" . time());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue