Refactored the archiver package
parent
3d0ce85db2
commit
20e717f975
|
@ -0,0 +1,113 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
use Composer\Downloader\DownloadManager;
|
||||||
|
use Composer\Factory;
|
||||||
|
use Composer\IO\NullIO;
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
use Composer\Util\Filesystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
*/
|
||||||
|
class ArchiveManager
|
||||||
|
{
|
||||||
|
protected $buildDir;
|
||||||
|
|
||||||
|
protected $downloadManager;
|
||||||
|
|
||||||
|
protected $archivers = array();
|
||||||
|
|
||||||
|
protected $vcsArchivers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $buildDir The directory used to build the archive
|
||||||
|
* @param DownloadManager $downloadManager A manager used to download package sources
|
||||||
|
*/
|
||||||
|
public function __construct($buildDir, DownloadManager $downloadManager = null)
|
||||||
|
{
|
||||||
|
$this->buildDir = $buildDir;
|
||||||
|
|
||||||
|
if (null !== $downloadManager) {
|
||||||
|
$this->downloadManager = $downloadManager;
|
||||||
|
} else {
|
||||||
|
$factory = new Factory();
|
||||||
|
$this->downloadManager = $factory->createDownloadManager(new NullIO());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ArchiverInterface $archiver
|
||||||
|
*/
|
||||||
|
public function addArchiver(ArchiverInterface $archiver)
|
||||||
|
{
|
||||||
|
if ($archiver instanceof VcsArchiver) {
|
||||||
|
$this->vcsArchivers[$archiver->getSourceType()] = $archiver;
|
||||||
|
} else {
|
||||||
|
$this->archivers[] = $archiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an archive of the specified package.
|
||||||
|
*
|
||||||
|
* @param PackageInterface $package The package to archive
|
||||||
|
* @param string $format The format of the archive (zip, tar, ...)
|
||||||
|
*
|
||||||
|
* @return string The path of the created archive
|
||||||
|
*/
|
||||||
|
public function archive(PackageInterface $package, $format)
|
||||||
|
{
|
||||||
|
if (empty($format)) {
|
||||||
|
throw new \InvalidArgumentException('Format must be specified');
|
||||||
|
}
|
||||||
|
|
||||||
|
$filesystem = new Filesystem();
|
||||||
|
$packageName = str_replace('/', DIRECTORY_SEPARATOR, $package->getUniqueName());
|
||||||
|
|
||||||
|
// Directory used to download the sources
|
||||||
|
$sources = sys_get_temp_dir().DIRECTORY_SEPARATOR.$packageName;
|
||||||
|
$filesystem->ensureDirectoryExists($sources);
|
||||||
|
|
||||||
|
// Archive filename
|
||||||
|
$target = $this->buildDir.DIRECTORY_SEPARATOR.$packageName.'.'.$format;
|
||||||
|
$filesystem->ensureDirectoryExists(dirname($this->buildDir.$target));
|
||||||
|
|
||||||
|
// Download sources
|
||||||
|
$this->downloadManager->download($package, $sources, true);
|
||||||
|
|
||||||
|
// Try VCS archivers first
|
||||||
|
$sourceType = $package->getSourceType();
|
||||||
|
if (isset($this->archivers[$sourceType]) && $this->archivers[$sourceType]->supports($format)) {
|
||||||
|
$archiver = $this->archivers[$sourceType];
|
||||||
|
$archiver->setSourceRef($sourceRef);
|
||||||
|
$archiver->setFormat($format);
|
||||||
|
$archiver->archive($sources, $target);
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback on default archivers
|
||||||
|
foreach ($this->archivers as $archiver) {
|
||||||
|
if ($archiver->supports($format)) {
|
||||||
|
$archiver->archive($sources, $target);
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RuntimeException(sprintf('No archiver found to support %s format', $format));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -8,22 +9,31 @@
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Composer\Package\Archiver;
|
namespace Composer\Package\Archiver;
|
||||||
|
|
||||||
use Composer\Package\PackageInterface;
|
use Composer\Package\PackageInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Till Klampaeckel <till@php.net>
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
*/
|
*/
|
||||||
interface ArchiverInterface
|
interface ArchiverInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return value depends on implementation - e.g. generating a tar or zip the
|
* Create an archive from the sources.
|
||||||
* method currently returns void, the ArrayArchiver returns an array.
|
|
||||||
*
|
*
|
||||||
* @param PackageInterface $package
|
* @param string $source The sources directory
|
||||||
*
|
* @param string $target The target file
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function dump(PackageInterface $package);
|
public function archive($sources, $target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format supported by the archiver.
|
||||||
|
*
|
||||||
|
* @param string $format The format to support
|
||||||
|
*
|
||||||
|
* @return boolean true if the format is supported by the archiver
|
||||||
|
*/
|
||||||
|
public function supports($format);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -11,156 +12,34 @@
|
||||||
|
|
||||||
namespace Composer\Package\Archiver;
|
namespace Composer\Package\Archiver;
|
||||||
|
|
||||||
|
use Composer\Package\BasePackage;
|
||||||
use Composer\Package\PackageInterface;
|
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>
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
*/
|
*/
|
||||||
abstract class BaseArchiver implements ArchiverInterface
|
abstract class BaseArchiver implements ArchiverInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Format: zip or tar.
|
* Create a PHAR archive.
|
||||||
* @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
|
* @param string $sources Path of the directory to archive
|
||||||
|
* @param string $target Path of the file archive to create
|
||||||
|
* @param int $format Format of the archive
|
||||||
*/
|
*/
|
||||||
public function __construct($path = null, ProcessExecutor $process = null)
|
protected function createPharArchive($sources, $target, $format)
|
||||||
{
|
|
||||||
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 {
|
try {
|
||||||
$phar = new \PharData($filename, null, null, $format);
|
$phar = new \PharData($target, null, null, $format);
|
||||||
$phar->buildFromDirectory($workDir);
|
$phar->buildFromDirectory($sources);
|
||||||
} catch (\UnexpectedValueException $e) {
|
} catch (\UnexpectedValueException $e) {
|
||||||
$message = "Original PHAR exception: " . (string) $e;
|
throw new \RuntimeException(
|
||||||
$message .= PHP_EOL . PHP_EOL;
|
sprintf("Could not create archive '%s' from '%s': %s",
|
||||||
$message .= sprintf("Could not create archive '%s' from '%s'.", $filename, $workDir);
|
$target,
|
||||||
throw new \RuntimeException($message);
|
$sources,
|
||||||
|
$e->getMessage()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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,58 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
|
class GitArchiver extends VcsArchiver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function archive($source, $target)
|
||||||
|
{
|
||||||
|
$format = $this->format ?: 'zip';
|
||||||
|
$sourceRef = $this->sourceRef ?: 'HEAD';
|
||||||
|
|
||||||
|
$command = sprintf(
|
||||||
|
'git archive --format %s --output %s %s',
|
||||||
|
$format,
|
||||||
|
escapeshellarg($target),
|
||||||
|
$sourceRef
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->process->execute($command, $output, $source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSourceType()
|
||||||
|
{
|
||||||
|
return 'git';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function supports($format)
|
||||||
|
{
|
||||||
|
return in_array($format, array(
|
||||||
|
'zip',
|
||||||
|
'tar',
|
||||||
|
'tgz',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
|
class MercurialArchiver extends VcsArchiver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function archive($source, $target)
|
||||||
|
{
|
||||||
|
$format = $this->format ?: 'zip';
|
||||||
|
$sourceRef = $this->sourceRef ?: 'default';
|
||||||
|
|
||||||
|
$command = sprintf(
|
||||||
|
'hg archive --rev %s --type %s %s',
|
||||||
|
$sourceRef,
|
||||||
|
$format,
|
||||||
|
escapeshellarg($target)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->process->execute($command, $output, $source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getSourceType()
|
||||||
|
{
|
||||||
|
return 'hg';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function supports($format)
|
||||||
|
{
|
||||||
|
return in_array($format, array(
|
||||||
|
'tar',
|
||||||
|
'tbz2',
|
||||||
|
'tgz',
|
||||||
|
'uzip',
|
||||||
|
'zip',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -11,47 +12,28 @@
|
||||||
|
|
||||||
namespace Composer\Package\Archiver;
|
namespace Composer\Package\Archiver;
|
||||||
|
|
||||||
use Composer\Package\Archiver\BaseArchiver;
|
use Composer\Package\BasePackage;
|
||||||
use Composer\Package\Archiver\ArchiverInterface;
|
|
||||||
use Composer\Package\PackageInterface;
|
use Composer\Package\PackageInterface;
|
||||||
use Composer\Util\ProcessExecutor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ulf Härnhammar <ulfharn@gmail.com>
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
*/
|
*/
|
||||||
class TarArchiver extends BaseArchiver
|
class TarArchiver extends BaseArchiver
|
||||||
{
|
{
|
||||||
protected $format = 'tar';
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function archive($sources, $target)
|
||||||
|
{
|
||||||
|
$this->createPharArchive($sources, $target, \Phar::TAR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PackageInterface $package
|
* {@inheritdoc}
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
*/
|
||||||
public function dump(PackageInterface $package)
|
public function supports($format)
|
||||||
{
|
{
|
||||||
$workDir = $this->getAndEnsureWorkDirectory($package);
|
return 'tar' === $format;
|
||||||
|
|
||||||
$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,60 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
use Composer\Util\ProcessExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VCS archivers are optimized for a specific source type.
|
||||||
|
*
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
|
abstract class VcsArchiver implements ArchiverInterface
|
||||||
|
{
|
||||||
|
protected $process;
|
||||||
|
protected $sourceRef;
|
||||||
|
protected $format;
|
||||||
|
|
||||||
|
public function __construct($process = null)
|
||||||
|
{
|
||||||
|
$this->process = $process ?: new ProcessExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSourceRef()
|
||||||
|
{
|
||||||
|
return $this->sourceRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSourceRef($sourceRef)
|
||||||
|
{
|
||||||
|
$this->sourceRef = $sourceRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFormat()
|
||||||
|
{
|
||||||
|
return $this->format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFormat($format)
|
||||||
|
{
|
||||||
|
$this->format = $format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the source type supported by the archiver.
|
||||||
|
*
|
||||||
|
* @return string The source type of the archiver
|
||||||
|
*/
|
||||||
|
abstract public function getSourceType();
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -11,46 +12,28 @@
|
||||||
|
|
||||||
namespace Composer\Package\Archiver;
|
namespace Composer\Package\Archiver;
|
||||||
|
|
||||||
use Composer\Package\Archiver\BaseArchiver;
|
use Composer\Package\BasePackage;
|
||||||
use Composer\Package\Archiver\ArchiverInterface;
|
|
||||||
use Composer\Package\PackageInterface;
|
use Composer\Package\PackageInterface;
|
||||||
use Composer\Util\ProcessExecutor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Till Klampaeckel <till@php.net>
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
*/
|
*/
|
||||||
class ZipArchiver extends BaseArchiver
|
class ZipArchiver extends BaseArchiver
|
||||||
{
|
{
|
||||||
protected $format = 'zip';
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function archive($sources, $target)
|
||||||
|
{
|
||||||
|
$this->createPharArchive($sources, $target, \Phar::ZIP);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param PackageInterface $package
|
* {@inheritdoc}
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
*/
|
||||||
public function dump(PackageInterface $package)
|
public function supports($format)
|
||||||
{
|
{
|
||||||
$workDir = $this->getAndEnsureWorkDirectory($package);
|
return 'zip' === $format;
|
||||||
|
|
||||||
$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,92 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
use Composer\Package\Archiver;
|
||||||
|
use Composer\Package\Archiver\ArchiveManager;
|
||||||
|
use Composer\Package\PackageInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
|
class ArchiveManagerTest extends ArchiverTest
|
||||||
|
{
|
||||||
|
protected $manager;
|
||||||
|
|
||||||
|
protected $workDir;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->workDir = sys_get_temp_dir();
|
||||||
|
|
||||||
|
$this->manager = new ArchiveManager($this->workDir);
|
||||||
|
$this->manager->addArchiver(new Archiver\GitArchiver);
|
||||||
|
$this->manager->addArchiver(new Archiver\MercurialArchiver);
|
||||||
|
$this->manager->addArchiver(new Archiver\TarArchiver);
|
||||||
|
$this->manager->addArchiver(new Archiver\ZipArchiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUnknownFormat()
|
||||||
|
{
|
||||||
|
$this->setExpectedException('RuntimeException');
|
||||||
|
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
|
||||||
|
$this->manager->archive($package, '__unknown_format__');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArchiveTarWithVcs()
|
||||||
|
{
|
||||||
|
$this->setupGitRepo();
|
||||||
|
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
|
||||||
|
// The package is source from git,
|
||||||
|
// so it should `git archive --format tar`
|
||||||
|
$this->manager->archive($package, 'tar');
|
||||||
|
|
||||||
|
$target = $this->getTargetName($package, 'tar');
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
|
unlink($target);
|
||||||
|
$this->removeGitRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArchiveTarWithoutVcs()
|
||||||
|
{
|
||||||
|
$this->setupGitRepo();
|
||||||
|
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
|
||||||
|
// This should use the TarArchiver
|
||||||
|
$this->manager->archive($package, 'tar');
|
||||||
|
|
||||||
|
$package->setSourceType('__unknown_type__'); // disable VCS recognition
|
||||||
|
$target = $this->getTargetName($package, 'tar');
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
|
unlink($target);
|
||||||
|
$this->removeGitRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTargetName(PackageInterface $package, $format)
|
||||||
|
{
|
||||||
|
$packageName = str_replace('/', DIRECTORY_SEPARATOR, $package->getUniqueName());
|
||||||
|
$target = $this->workDir.DIRECTORY_SEPARATOR.$packageName.'.'.$format;
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -11,16 +12,20 @@
|
||||||
|
|
||||||
namespace Composer\Test\Package\Archiver;
|
namespace Composer\Test\Package\Archiver;
|
||||||
|
|
||||||
use Composer\Package\MemoryPackage;
|
|
||||||
use Composer\Util\Filesystem;
|
use Composer\Util\Filesystem;
|
||||||
use Composer\Util\ProcessExecutor;
|
use Composer\Util\ProcessExecutor;
|
||||||
|
use Composer\Package\MemoryPackage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
abstract class ArchiverTest extends \PHPUnit_Framework_TestCase
|
abstract class ArchiverTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var \Composer\Util\Filesystem
|
* @var \Composer\Util\Filesystem
|
||||||
*/
|
*/
|
||||||
protected $fs;
|
protected $filesystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Composer\Util\ProcessExecutor
|
* @var \Composer\Util\ProcessExecutor
|
||||||
|
@ -30,18 +35,13 @@ abstract class ArchiverTest extends \PHPUnit_Framework_TestCase
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $testdir = '';
|
protected $testDir;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
$this->fs = new Filesystem;
|
$this->filesystem = new Filesystem();
|
||||||
$this->process = new ProcessExecutor;
|
$this->process = new ProcessExecutor();
|
||||||
$this->testdir = sys_get_temp_dir() . '/composer_archivertest_git_repository' . mt_rand();
|
$this->testDir = sys_get_temp_dir().'/composer_archivertest_git_repository'.mt_rand();
|
||||||
}
|
|
||||||
|
|
||||||
protected function getTestDir()
|
|
||||||
{
|
|
||||||
return $this->testdir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,49 +49,42 @@ abstract class ArchiverTest extends \PHPUnit_Framework_TestCase
|
||||||
*/
|
*/
|
||||||
protected function setupGitRepo()
|
protected function setupGitRepo()
|
||||||
{
|
{
|
||||||
$td = $this->getTestDir();
|
$this->filesystem->removeDirectory($this->testDir);
|
||||||
|
$this->filesystem->ensureDirectoryExists($this->testDir);
|
||||||
$this->fs->removeDirectory($td);
|
|
||||||
$this->fs->ensureDirectoryExists($td);
|
|
||||||
|
|
||||||
$currentWorkDir = getcwd();
|
$currentWorkDir = getcwd();
|
||||||
chdir($td);
|
chdir($this->testDir);
|
||||||
|
|
||||||
$result = $this->process->execute("git init -q");
|
$result = $this->process->execute('git init -q');
|
||||||
if ($result > 0) {
|
if ($result > 0) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException('Could not init: '.$this->process->getErrorOutput());
|
||||||
"Could not init: " . $this->process->getErrorOutput());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = file_put_contents('b', 'a');
|
$result = file_put_contents('b', 'a');
|
||||||
if (false === $result) {
|
if (false === $result) {
|
||||||
throw new \RuntimeException("Could not save file.");
|
throw new \RuntimeException('Could not save file.');
|
||||||
}
|
}
|
||||||
$result = $this->process->execute("git add b && git commit -m 'commit b' -q");
|
|
||||||
|
$result = $this->process->execute('git add b && git commit -m "commit b" -q');
|
||||||
if ($result > 0) {
|
if ($result > 0) {
|
||||||
throw new \RuntimeException(
|
throw new \RuntimeException('Could not commit: '.$this->process->getErrorOutput());
|
||||||
"Could not init: " . $this->process->getErrorOutput());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chdir($currentWorkDir);
|
chdir($currentWorkDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function removeGitRepo()
|
protected function removeGitRepo()
|
||||||
{
|
{
|
||||||
$td = $this->getTestDir();
|
$this->filesystem->removeDirectory($this->testDir);
|
||||||
$this->fs->removeDirectory($td);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setupPackage()
|
protected function setupPackage()
|
||||||
{
|
{
|
||||||
$td = $this->getTestDir();
|
|
||||||
$package = new MemoryPackage('archivertest/archivertest', 'master', 'master');
|
$package = new MemoryPackage('archivertest/archivertest', 'master', 'master');
|
||||||
$package->setSourceUrl("file://$td");
|
$package->setSourceUrl(realpath($this->testDir));
|
||||||
$package->setSourceReference('master');
|
$package->setSourceReference('master');
|
||||||
$package->setSourceType('git');
|
$package->setSourceType('git');
|
||||||
|
|
||||||
return $package;
|
return $package;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPackageFileName(MemoryPackage $package)
|
|
||||||
{
|
|
||||||
return $package->getVersion();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
use Composer\Package\Archiver\GitArchiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
|
class GitArchiverTest extends ArchiverTest
|
||||||
|
{
|
||||||
|
public function testZipArchive()
|
||||||
|
{
|
||||||
|
$this->setupGitRepo();
|
||||||
|
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
$target = sys_get_temp_dir().'/composer_archiver_test.zip';
|
||||||
|
|
||||||
|
// Test archive
|
||||||
|
$archiver = new GitArchiver();
|
||||||
|
$archiver->setFormat('zip');
|
||||||
|
$archiver->setSourceRef('master');
|
||||||
|
$archiver->archive($package->getSourceUrl(), $target);
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
|
unlink($target);
|
||||||
|
$this->removeGitRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTarArchive()
|
||||||
|
{
|
||||||
|
$this->setupGitRepo();
|
||||||
|
|
||||||
|
$package = $this->setupPackage();
|
||||||
|
$target = sys_get_temp_dir().'/composer_archiver_test.tar';
|
||||||
|
|
||||||
|
// Test archive
|
||||||
|
$archiver = new GitArchiver();
|
||||||
|
$archiver->setFormat('tar');
|
||||||
|
$archiver->setSourceRef('master');
|
||||||
|
$archiver->archive($package->getSourceUrl(), $target);
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
|
unlink($target);
|
||||||
|
$this->removeGitRepo();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
<?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\Archiver;
|
||||||
|
|
||||||
|
use Composer\Package\Archiver\MercurialArchiver;
|
||||||
|
use Composer\Package\MemoryPackage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
*/
|
||||||
|
class MercurialArchiverTest extends ArchiverTest
|
||||||
|
{
|
||||||
|
public function testZipArchive()
|
||||||
|
{
|
||||||
|
$this->setupMercurialRepo();
|
||||||
|
|
||||||
|
$package = $this->setupMercurialPackage();
|
||||||
|
$target = sys_get_temp_dir().'/composer_archiver_test.zip';
|
||||||
|
|
||||||
|
// Test archive
|
||||||
|
$archiver = new MercurialArchiver();
|
||||||
|
$archiver->setFormat('zip');
|
||||||
|
$archiver->setSourceRef('default');
|
||||||
|
$archiver->archive($package->getSourceUrl(), $target);
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
|
unlink($target);
|
||||||
|
$this->removeMercurialRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTarArchive()
|
||||||
|
{
|
||||||
|
$this->setupMercurialRepo();
|
||||||
|
|
||||||
|
$package = $this->setupMercurialPackage();
|
||||||
|
$target = sys_get_temp_dir().'/composer_archiver_test.tar';
|
||||||
|
|
||||||
|
// Test archive
|
||||||
|
$archiver = new MercurialArchiver();
|
||||||
|
$archiver->setFormat('tar');
|
||||||
|
$archiver->setSourceRef('default');
|
||||||
|
$archiver->archive($package->getSourceUrl(), $target);
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
|
unlink($target);
|
||||||
|
$this->removeMercurialRepo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create local git repository to run tests against!
|
||||||
|
*/
|
||||||
|
protected function setupMercurialRepo()
|
||||||
|
{
|
||||||
|
$this->filesystem->removeDirectory($this->testDir);
|
||||||
|
$this->filesystem->ensureDirectoryExists($this->testDir);
|
||||||
|
|
||||||
|
$currentWorkDir = getcwd();
|
||||||
|
chdir($this->testDir);
|
||||||
|
|
||||||
|
$result = $this->process->execute('hg 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('hg add b && hg commit -m "commit b" --config ui.username=test -q');
|
||||||
|
if ($result > 0) {
|
||||||
|
throw new \RuntimeException('Could not commit: '.$this->process->getErrorOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
chdir($currentWorkDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function removeMercurialRepo()
|
||||||
|
{
|
||||||
|
$this->filesystem->removeDirectory($this->testDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setupMercurialPackage()
|
||||||
|
{
|
||||||
|
$package = new MemoryPackage('archivertest/archivertest', 'master', 'master');
|
||||||
|
$package->setSourceUrl(realpath($this->testDir));
|
||||||
|
$package->setSourceReference('default');
|
||||||
|
$package->setSourceType('hg');
|
||||||
|
|
||||||
|
return $package;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -13,31 +14,25 @@ namespace Composer\Test\Package\Archiver;
|
||||||
|
|
||||||
use Composer\Package\Archiver\TarArchiver;
|
use Composer\Package\Archiver\TarArchiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
class TarArchiverTest extends ArchiverTest
|
class TarArchiverTest extends ArchiverTest
|
||||||
{
|
{
|
||||||
public function testThis()
|
public function testArchive()
|
||||||
{
|
{
|
||||||
$this->setupGitRepo();
|
$this->setupGitRepo();
|
||||||
|
|
||||||
$package = $this->setupPackage();
|
$package = $this->setupPackage();
|
||||||
$name = $this->getPackageFileName($package);
|
$target = sys_get_temp_dir().'/composer_archiver_test.tar';
|
||||||
|
|
||||||
$temp = sys_get_temp_dir();
|
// Test archive
|
||||||
$tar = new TarArchiver($temp);
|
$archiver = new TarArchiver();
|
||||||
$tar->dump($package);
|
$archiver->archive($package->getSourceUrl(), $target);
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
$dist = sprintf('%s/%s.tar',
|
unlink($target);
|
||||||
$temp, $name
|
|
||||||
);
|
|
||||||
$this->assertFileExists($dist);
|
|
||||||
unlink($dist);
|
|
||||||
$this->removeGitRepo();
|
$this->removeGitRepo();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException \InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function testException()
|
|
||||||
{
|
|
||||||
new TarArchiver("/totally-random-" . time());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of Composer.
|
* This file is part of Composer.
|
||||||
*
|
*
|
||||||
|
@ -13,31 +14,25 @@ namespace Composer\Test\Package\Archiver;
|
||||||
|
|
||||||
use Composer\Package\Archiver\ZipArchiver;
|
use Composer\Package\Archiver\ZipArchiver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Till Klampaeckel <till@php.net>
|
||||||
|
* @author Matthieu Moquet <matthieu@moquet.net>
|
||||||
|
*/
|
||||||
class ZipArchiverTest extends ArchiverTest
|
class ZipArchiverTest extends ArchiverTest
|
||||||
{
|
{
|
||||||
public function testThis()
|
public function testArchive()
|
||||||
{
|
{
|
||||||
$this->setupGitRepo();
|
$this->setupGitRepo();
|
||||||
|
|
||||||
$package = $this->setupPackage();
|
$package = $this->setupPackage();
|
||||||
$name = $this->getPackageFileName($package);
|
$target = sys_get_temp_dir().'/composer_archiver_test.zip';
|
||||||
|
|
||||||
$temp = sys_get_temp_dir();
|
// Test archive
|
||||||
$zip = new ZipArchiver($temp);
|
$archiver = new ZipArchiver();
|
||||||
$zip->dump($package);
|
$archiver->archive($package->getSourceUrl(), $target);
|
||||||
|
$this->assertFileExists($target);
|
||||||
|
|
||||||
$dist = sprintf('%s/%s.zip',
|
unlink($target);
|
||||||
$temp, $name
|
|
||||||
);
|
|
||||||
$this->assertFileExists($dist);
|
|
||||||
unlink($dist);
|
|
||||||
$this->removeGitRepo();
|
$this->removeGitRepo();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @expectedException \InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public function testException()
|
|
||||||
{
|
|
||||||
new ZipArchiver("/totally-random-" . time());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue