2022-02-23 15:58:18 +00:00
|
|
|
<?php declare(strict_types=1);
|
2013-03-26 11:15:39 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|
2021-12-07 10:03:51 +00:00
|
|
|
use Composer\Pcre\Preg;
|
2018-11-12 14:23:32 +00:00
|
|
|
use Composer\Test\TestCase;
|
2013-03-26 11:15:39 +00:00
|
|
|
use Composer\Util\Filesystem;
|
|
|
|
use Symfony\Component\Process\Process;
|
|
|
|
|
2016-01-21 12:01:55 +00:00
|
|
|
class ArchivableFilesFinderTest extends TestCase
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
2021-10-16 08:16:06 +00:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
2013-03-26 11:15:39 +00:00
|
|
|
protected $sources;
|
2021-10-16 08:16:06 +00:00
|
|
|
/**
|
|
|
|
* @var ArchivableFilesFinder
|
|
|
|
*/
|
2013-03-26 11:15:39 +00:00
|
|
|
protected $finder;
|
2021-10-16 08:16:06 +00:00
|
|
|
/**
|
|
|
|
* @var Filesystem
|
|
|
|
*/
|
2013-04-02 09:32:11 +00:00
|
|
|
protected $fs;
|
2013-03-26 11:15:39 +00:00
|
|
|
|
2021-12-08 16:03:05 +00:00
|
|
|
protected function setUp(): void
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
|
|
|
$fs = new Filesystem;
|
2013-04-02 09:32:11 +00:00
|
|
|
$this->fs = $fs;
|
2013-03-26 11:15:39 +00:00
|
|
|
|
2013-04-02 09:32:11 +00:00
|
|
|
$this->sources = $fs->normalizePath(
|
2022-05-11 14:05:35 +00:00
|
|
|
self::getUniqueTmpDirectory()
|
2013-04-02 09:32:11 +00:00
|
|
|
);
|
2013-03-26 11:15:39 +00:00
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
$fileTree = [
|
2022-05-24 20:14:17 +00:00
|
|
|
'.foo',
|
2013-03-26 11:15:39 +00:00
|
|
|
'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',
|
2014-02-27 14:17:15 +00:00
|
|
|
'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',
|
2014-02-28 15:30:55 +00:00
|
|
|
'E/subtestA.foo',
|
|
|
|
'F/subtestA.foo',
|
|
|
|
'G/subtestA.foo',
|
|
|
|
'H/subtestA.foo',
|
|
|
|
'I/J/subtestA.foo',
|
|
|
|
'K/dirJ/subtestA.foo',
|
2013-03-26 11:15:39 +00:00
|
|
|
'toplevelA.foo',
|
|
|
|
'toplevelB.foo',
|
|
|
|
'prefixA.foo',
|
|
|
|
'prefixB.foo',
|
|
|
|
'prefixC.foo',
|
|
|
|
'prefixD.foo',
|
|
|
|
'prefixE.foo',
|
|
|
|
'prefixF.foo',
|
2014-02-28 10:43:28 +00:00
|
|
|
'parameters.yml',
|
|
|
|
'parameters.yml.dist',
|
|
|
|
'!important!.txt',
|
2015-06-29 07:42:40 +00:00
|
|
|
'!important_too!.txt',
|
|
|
|
'#weirdfile',
|
2022-08-17 12:20:07 +00:00
|
|
|
];
|
2013-03-26 11:15:39 +00:00
|
|
|
|
|
|
|
foreach ($fileTree as $relativePath) {
|
|
|
|
$path = $this->sources.'/'.$relativePath;
|
|
|
|
$fs->ensureDirectoryExists(dirname($path));
|
|
|
|
file_put_contents($path, '');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-08 16:03:05 +00:00
|
|
|
protected function tearDown(): void
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
2021-12-09 16:09:07 +00:00
|
|
|
parent::tearDown();
|
2013-03-26 11:15:39 +00:00
|
|
|
$fs = new Filesystem;
|
|
|
|
$fs->removeDirectory($this->sources);
|
|
|
|
}
|
|
|
|
|
2022-02-18 09:38:54 +00:00
|
|
|
public function testManualExcludes(): void
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
2022-08-17 12:20:07 +00:00
|
|
|
$excludes = [
|
2013-03-26 11:15:39 +00:00
|
|
|
'prefixB.foo',
|
|
|
|
'!/prefixB.foo',
|
|
|
|
'/prefixA.foo',
|
|
|
|
'prefixC.*',
|
2015-06-29 07:42:40 +00:00
|
|
|
'!*/*/*/prefixC.foo',
|
2022-05-24 20:14:17 +00:00
|
|
|
'.*',
|
2022-08-17 12:20:07 +00:00
|
|
|
];
|
2013-03-26 11:15:39 +00:00
|
|
|
|
|
|
|
$this->finder = new ArchivableFilesFinder($this->sources, $excludes);
|
|
|
|
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertArchivableFiles([
|
2014-02-28 10:43:28 +00:00
|
|
|
'/!important!.txt',
|
|
|
|
'/!important_too!.txt',
|
2015-06-29 07:42:40 +00:00
|
|
|
'/#weirdfile',
|
2013-03-26 11:15:39 +00:00
|
|
|
'/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',
|
2014-02-27 14:17:15 +00:00
|
|
|
'/C/prefixA.foo',
|
|
|
|
'/C/prefixD.foo',
|
|
|
|
'/C/prefixE.foo',
|
|
|
|
'/C/prefixF.foo',
|
|
|
|
'/D/prefixA',
|
|
|
|
'/D/prefixB',
|
|
|
|
'/D/prefixC',
|
|
|
|
'/D/prefixD',
|
|
|
|
'/D/prefixE',
|
|
|
|
'/D/prefixF',
|
2014-02-28 10:43:28 +00:00
|
|
|
'/E/subtestA.foo',
|
|
|
|
'/F/subtestA.foo',
|
|
|
|
'/G/subtestA.foo',
|
|
|
|
'/H/subtestA.foo',
|
2014-02-28 15:30:55 +00:00
|
|
|
'/I/J/subtestA.foo',
|
|
|
|
'/K/dirJ/subtestA.foo',
|
2014-02-28 10:43:28 +00:00
|
|
|
'/parameters.yml',
|
|
|
|
'/parameters.yml.dist',
|
2013-03-26 11:15:39 +00:00
|
|
|
'/prefixB.foo',
|
|
|
|
'/prefixD.foo',
|
|
|
|
'/prefixE.foo',
|
|
|
|
'/prefixF.foo',
|
|
|
|
'/toplevelA.foo',
|
|
|
|
'/toplevelB.foo',
|
2022-08-17 12:20:07 +00:00
|
|
|
]);
|
2013-03-26 11:15:39 +00:00
|
|
|
}
|
|
|
|
|
2022-02-18 09:38:54 +00:00
|
|
|
public function testGitExcludes(): void
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
2016-12-22 17:14:57 +00:00
|
|
|
$this->skipIfNotExecutable('git');
|
2013-04-25 18:57:58 +00:00
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
file_put_contents($this->sources.'/.gitattributes', implode("\n", [
|
2013-03-26 11:15:39 +00:00
|
|
|
'',
|
|
|
|
'# gitattributes rules with comments and blank lines',
|
|
|
|
'prefixB.foo export-ignore',
|
|
|
|
'/prefixA.foo export-ignore',
|
|
|
|
'prefixC.* export-ignore',
|
2021-11-24 21:44:03 +00:00
|
|
|
'',
|
|
|
|
'prefixE.foo export-ignore',
|
|
|
|
'# and more',
|
|
|
|
'# comments',
|
|
|
|
'',
|
|
|
|
'/prefixE.foo -export-ignore',
|
|
|
|
'/prefixD.foo export-ignore',
|
|
|
|
'prefixF.* export-ignore',
|
|
|
|
'/*/*/prefixF.foo -export-ignore',
|
|
|
|
'',
|
|
|
|
'refixD.foo export-ignore',
|
|
|
|
'/C export-ignore',
|
|
|
|
'D/prefixA export-ignore',
|
|
|
|
'E export-ignore',
|
|
|
|
'F/ export-ignore',
|
|
|
|
'G/* export-ignore',
|
|
|
|
'H/** export-ignore',
|
|
|
|
'J/ export-ignore',
|
|
|
|
'parameters.yml export-ignore',
|
|
|
|
'\!important!.txt export-ignore',
|
|
|
|
'\#* export-ignore',
|
2022-08-17 12:20:07 +00:00
|
|
|
]));
|
2013-03-26 11:15:39 +00:00
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
$this->finder = new ArchivableFilesFinder($this->sources, []);
|
2013-03-26 11:15:39 +00:00
|
|
|
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertArchivableFiles($this->getArchivedFiles(
|
2018-07-24 12:32:52 +00:00
|
|
|
'git init && '.
|
2015-02-16 03:20:45 +00:00
|
|
|
'git config user.email "you@example.com" && '.
|
|
|
|
'git config user.name "Your Name" && '.
|
2019-02-18 16:00:57 +00:00
|
|
|
'git config commit.gpgsign false && '.
|
2013-03-26 11:15:39 +00:00
|
|
|
'git add .git* && '.
|
|
|
|
'git commit -m "ignore rules" && '.
|
|
|
|
'git add . && '.
|
|
|
|
'git commit -m "init" && '.
|
|
|
|
'git archive --format=zip --prefix=archive/ -o archive.zip HEAD'
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2022-02-18 09:38:54 +00:00
|
|
|
public function testSkipExcludes(): void
|
2017-01-11 15:15:20 +00:00
|
|
|
{
|
2022-08-17 12:20:07 +00:00
|
|
|
$excludes = [
|
2017-01-11 15:15:20 +00:00
|
|
|
'prefixB.foo',
|
2022-08-17 12:20:07 +00:00
|
|
|
];
|
2017-01-11 15:15:20 +00:00
|
|
|
|
|
|
|
$this->finder = new ArchivableFilesFinder($this->sources, $excludes, true);
|
|
|
|
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertArchivableFiles([
|
2017-01-11 15:15:20 +00:00
|
|
|
'/!important!.txt',
|
|
|
|
'/!important_too!.txt',
|
|
|
|
'/#weirdfile',
|
2022-05-24 20:14:17 +00:00
|
|
|
'/.foo',
|
2017-01-11 15:15:20 +00:00
|
|
|
'/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',
|
|
|
|
'/parameters.yml',
|
|
|
|
'/parameters.yml.dist',
|
|
|
|
'/prefixA.foo',
|
|
|
|
'/prefixB.foo',
|
|
|
|
'/prefixC.foo',
|
|
|
|
'/prefixD.foo',
|
|
|
|
'/prefixE.foo',
|
|
|
|
'/prefixF.foo',
|
|
|
|
'/toplevelA.foo',
|
|
|
|
'/toplevelB.foo',
|
2022-08-17 12:20:07 +00:00
|
|
|
]);
|
2017-01-11 15:15:20 +00:00
|
|
|
}
|
|
|
|
|
2021-11-01 20:44:12 +00:00
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
2022-02-18 10:22:01 +00:00
|
|
|
protected function getArchivableFiles(): array
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
2022-08-17 12:20:07 +00:00
|
|
|
$files = [];
|
2013-03-26 12:02:32 +00:00
|
|
|
foreach ($this->finder as $file) {
|
2013-03-26 11:15:39 +00:00
|
|
|
if (!$file->isDir()) {
|
2021-12-07 10:03:51 +00:00
|
|
|
$files[] = Preg::replace('#^'.preg_quote($this->sources, '#').'#', '', $this->fs->normalizePath($file->getRealPath()));
|
2013-03-26 11:15:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sort($files);
|
|
|
|
|
|
|
|
return $files;
|
|
|
|
}
|
|
|
|
|
2021-11-01 20:44:12 +00:00
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
2022-02-22 15:47:09 +00:00
|
|
|
protected function getArchivedFiles(string $command): array
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
2022-01-04 09:41:33 +00:00
|
|
|
$process = Process::fromShellCommandline($command, $this->sources);
|
2013-03-26 11:15:39 +00:00
|
|
|
$process->run();
|
|
|
|
|
|
|
|
$archive = new \PharData($this->sources.'/archive.zip');
|
|
|
|
$iterator = new \RecursiveIteratorIterator($archive);
|
|
|
|
|
2022-08-17 12:20:07 +00:00
|
|
|
$files = [];
|
2013-03-26 11:15:39 +00:00
|
|
|
foreach ($iterator as $file) {
|
2022-02-23 15:57:47 +00:00
|
|
|
$files[] = Preg::replace('#^phar://'.preg_quote($this->sources, '#').'/archive\.zip/archive#', '', $this->fs->normalizePath((string) $file));
|
2013-03-26 11:15:39 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 09:32:11 +00:00
|
|
|
unset($archive, $iterator, $file);
|
2013-03-26 11:15:39 +00:00
|
|
|
unlink($this->sources.'/archive.zip');
|
2013-04-02 09:32:11 +00:00
|
|
|
|
2013-03-26 11:15:39 +00:00
|
|
|
return $files;
|
|
|
|
}
|
|
|
|
|
2021-11-01 20:44:12 +00:00
|
|
|
/**
|
|
|
|
* @param string[] $expectedFiles
|
|
|
|
*/
|
2022-02-22 15:47:09 +00:00
|
|
|
protected function assertArchivableFiles(array $expectedFiles): void
|
2013-03-26 11:15:39 +00:00
|
|
|
{
|
|
|
|
$actualFiles = $this->getArchivableFiles();
|
|
|
|
|
2024-05-29 21:12:06 +00:00
|
|
|
self::assertEquals($expectedFiles, $actualFiles);
|
2013-03-26 11:15:39 +00:00
|
|
|
}
|
|
|
|
}
|