mirror of
https://github.com/composer/composer
synced 2025-05-09 00:22:53 +00:00

any tests that use the filesystem should have their own unique directory, as we run our test suite in parallel and cleanup of tests (removing directories) should not interfere with currently running tests
298 lines
8.4 KiB
PHP
298 lines
8.4 KiB
PHP
<?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\ArchivableFilesFinder;
|
|
use Composer\TestCase;
|
|
use Composer\Util\Filesystem;
|
|
use Symfony\Component\Process\Process;
|
|
use Symfony\Component\Process\ExecutableFinder;
|
|
|
|
class ArchivableFilesFinderTest extends TestCase
|
|
{
|
|
protected $sources;
|
|
protected $finder;
|
|
protected $fs;
|
|
|
|
protected function setUp()
|
|
{
|
|
$fs = new Filesystem;
|
|
$this->fs = $fs;
|
|
|
|
$this->sources = $fs->normalizePath(
|
|
$this->getUniqueTmpDirectory()
|
|
);
|
|
|
|
$fileTree = array(
|
|
'A/prefixA.foo',
|
|
'A/prefixB.foo',
|
|
'A/prefixC.foo',
|
|
'A/prefixD.foo',
|
|
'A/prefixE.foo',
|
|
'A/prefixF.foo',
|
|
'B/sub/prefixA.foo',
|
|
'B/sub/prefixB.foo',
|
|
'B/sub/prefixC.foo',
|
|
'B/sub/prefixD.foo',
|
|
'B/sub/prefixE.foo',
|
|
'B/sub/prefixF.foo',
|
|
'C/prefixA.foo',
|
|
'C/prefixB.foo',
|
|
'C/prefixC.foo',
|
|
'C/prefixD.foo',
|
|
'C/prefixE.foo',
|
|
'C/prefixF.foo',
|
|
'D/prefixA',
|
|
'D/prefixB',
|
|
'D/prefixC',
|
|
'D/prefixD',
|
|
'D/prefixE',
|
|
'D/prefixF',
|
|
'E/subtestA.foo',
|
|
'F/subtestA.foo',
|
|
'G/subtestA.foo',
|
|
'H/subtestA.foo',
|
|
'I/J/subtestA.foo',
|
|
'K/dirJ/subtestA.foo',
|
|
'toplevelA.foo',
|
|
'toplevelB.foo',
|
|
'prefixA.foo',
|
|
'prefixB.foo',
|
|
'prefixC.foo',
|
|
'prefixD.foo',
|
|
'prefixE.foo',
|
|
'prefixF.foo',
|
|
'parameters.yml',
|
|
'parameters.yml.dist',
|
|
'!important!.txt',
|
|
'!important_too!.txt',
|
|
'#weirdfile',
|
|
);
|
|
|
|
foreach ($fileTree as $relativePath) {
|
|
$path = $this->sources.'/'.$relativePath;
|
|
$fs->ensureDirectoryExists(dirname($path));
|
|
file_put_contents($path, '');
|
|
}
|
|
}
|
|
|
|
protected function tearDown()
|
|
{
|
|
$fs = new Filesystem;
|
|
$fs->removeDirectory($this->sources);
|
|
}
|
|
|
|
public function testManualExcludes()
|
|
{
|
|
$excludes = array(
|
|
'prefixB.foo',
|
|
'!/prefixB.foo',
|
|
'/prefixA.foo',
|
|
'prefixC.*',
|
|
'!*/*/*/prefixC.foo',
|
|
);
|
|
|
|
$this->finder = new ArchivableFilesFinder($this->sources, $excludes);
|
|
|
|
$this->assertArchivableFiles(array(
|
|
'/!important!.txt',
|
|
'/!important_too!.txt',
|
|
'/#weirdfile',
|
|
'/A/prefixA.foo',
|
|
'/A/prefixD.foo',
|
|
'/A/prefixE.foo',
|
|
'/A/prefixF.foo',
|
|
'/B/sub/prefixA.foo',
|
|
'/B/sub/prefixC.foo',
|
|
'/B/sub/prefixD.foo',
|
|
'/B/sub/prefixE.foo',
|
|
'/B/sub/prefixF.foo',
|
|
'/C/prefixA.foo',
|
|
'/C/prefixD.foo',
|
|
'/C/prefixE.foo',
|
|
'/C/prefixF.foo',
|
|
'/D/prefixA',
|
|
'/D/prefixB',
|
|
'/D/prefixC',
|
|
'/D/prefixD',
|
|
'/D/prefixE',
|
|
'/D/prefixF',
|
|
'/E/subtestA.foo',
|
|
'/F/subtestA.foo',
|
|
'/G/subtestA.foo',
|
|
'/H/subtestA.foo',
|
|
'/I/J/subtestA.foo',
|
|
'/K/dirJ/subtestA.foo',
|
|
'/parameters.yml',
|
|
'/parameters.yml.dist',
|
|
'/prefixB.foo',
|
|
'/prefixD.foo',
|
|
'/prefixE.foo',
|
|
'/prefixF.foo',
|
|
'/toplevelA.foo',
|
|
'/toplevelB.foo',
|
|
));
|
|
}
|
|
|
|
public function testGitExcludes()
|
|
{
|
|
// Ensure that git is available for testing.
|
|
if (!$this->isProcessAvailable('git')) {
|
|
return $this->markTestSkipped('git is not available.');
|
|
}
|
|
|
|
file_put_contents($this->sources.'/.gitignore', implode("\n", array(
|
|
'# gitignore rules with comments and blank lines',
|
|
'',
|
|
'prefixE.foo',
|
|
'# and more',
|
|
'# comments',
|
|
'',
|
|
'!/prefixE.foo',
|
|
'/prefixD.foo',
|
|
'prefixF.*',
|
|
'!/*/*/prefixF.foo',
|
|
'',
|
|
'refixD.foo',
|
|
'/C',
|
|
'D/prefixA',
|
|
'E',
|
|
'F/',
|
|
'G/*',
|
|
'H/**',
|
|
'J/',
|
|
'parameters.yml',
|
|
'\!important!.txt',
|
|
'\#*',
|
|
)));
|
|
|
|
// git does not currently support negative git attributes
|
|
file_put_contents($this->sources.'/.gitattributes', implode("\n", array(
|
|
'',
|
|
'# gitattributes rules with comments and blank lines',
|
|
'prefixB.foo export-ignore',
|
|
//'!/prefixB.foo export-ignore',
|
|
'/prefixA.foo export-ignore',
|
|
'prefixC.* export-ignore',
|
|
//'!/*/*/prefixC.foo export-ignore',
|
|
)));
|
|
|
|
$this->finder = new ArchivableFilesFinder($this->sources, array());
|
|
|
|
$this->assertArchivableFiles($this->getArchivedFiles('git init && '.
|
|
'git config user.email "you@example.com" && '.
|
|
'git config user.name "Your Name" && '.
|
|
'git add .git* && '.
|
|
'git commit -m "ignore rules" && '.
|
|
'git add . && '.
|
|
'git commit -m "init" && '.
|
|
'git archive --format=zip --prefix=archive/ -o archive.zip HEAD'
|
|
));
|
|
}
|
|
|
|
public function testHgExcludes()
|
|
{
|
|
// Ensure that Mercurial is available for testing.
|
|
if (!$this->isProcessAvailable('hg')) {
|
|
return $this->markTestSkipped('Mercurial is not available.');
|
|
}
|
|
|
|
file_put_contents($this->sources.'/.hgignore', implode("\n", array(
|
|
'# hgignore rules with comments, blank lines and syntax changes',
|
|
'',
|
|
'pre*A.foo',
|
|
'prefixE.foo',
|
|
'# and more',
|
|
'# comments',
|
|
'',
|
|
'^prefixD.foo',
|
|
'D/prefixA',
|
|
'parameters.yml',
|
|
'\!important!.txt',
|
|
'E',
|
|
'F/',
|
|
'syntax: glob',
|
|
'prefixF.*',
|
|
'B/*',
|
|
'H/**',
|
|
)));
|
|
|
|
$this->finder = new ArchivableFilesFinder($this->sources, array());
|
|
|
|
$expectedFiles = $this->getArchivedFiles('hg init && '.
|
|
'hg add && '.
|
|
'hg commit -m "init" && '.
|
|
'hg archive archive.zip'
|
|
);
|
|
|
|
// Remove .hg_archival.txt from the expectedFiles
|
|
$archiveKey = array_search('/.hg_archival.txt', $expectedFiles);
|
|
array_splice($expectedFiles, $archiveKey, 1);
|
|
|
|
$this->assertArchivableFiles($expectedFiles);
|
|
}
|
|
|
|
protected function getArchivableFiles()
|
|
{
|
|
$files = array();
|
|
foreach ($this->finder as $file) {
|
|
if (!$file->isDir()) {
|
|
$files[] = preg_replace('#^'.preg_quote($this->sources, '#').'#', '', $this->fs->normalizePath($file->getRealPath()));
|
|
}
|
|
}
|
|
|
|
sort($files);
|
|
|
|
return $files;
|
|
}
|
|
|
|
protected function getArchivedFiles($command)
|
|
{
|
|
$process = new Process($command, $this->sources);
|
|
$process->run();
|
|
|
|
$archive = new \PharData($this->sources.'/archive.zip');
|
|
$iterator = new \RecursiveIteratorIterator($archive);
|
|
|
|
$files = array();
|
|
foreach ($iterator as $file) {
|
|
$files[] = preg_replace('#^phar://'.preg_quote($this->sources, '#').'/archive\.zip/archive#', '', $this->fs->normalizePath($file));
|
|
}
|
|
|
|
unset($archive, $iterator, $file);
|
|
unlink($this->sources.'/archive.zip');
|
|
|
|
return $files;
|
|
}
|
|
|
|
protected function assertArchivableFiles($expectedFiles)
|
|
{
|
|
$actualFiles = $this->getArchivableFiles();
|
|
|
|
$this->assertEquals($expectedFiles, $actualFiles);
|
|
}
|
|
|
|
/**
|
|
* Check whether or not the given process is available.
|
|
*
|
|
* @param string $process The name of the binary to test.
|
|
*
|
|
* @return bool True if the process is available, false otherwise.
|
|
*/
|
|
protected function isProcessAvailable($process)
|
|
{
|
|
$finder = new ExecutableFinder();
|
|
|
|
return (bool) $finder->find($process);
|
|
}
|
|
}
|