1
0
Fork 0

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 keys
pull/1567/head
Till Klampaeckel 2012-08-24 10:57:38 +02:00 committed by Nils Adermann
parent 6f0a71a158
commit 2acb033057
7 changed files with 491 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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}'.");
}
}
}

View File

@ -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}'.");
}
}
}

View File

@ -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();
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}