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