pull/10309/head
parent
cc3b53bc2e
commit
126f95a8d7
|
@ -49,7 +49,6 @@ class ArchivableFilesFinder extends \FilterIterator
|
|||
$filters = array();
|
||||
} else {
|
||||
$filters = array(
|
||||
new HgExcludeFilter($sources),
|
||||
new GitExcludeFilter($sources),
|
||||
new ComposerExcludeFilter($sources, $excludes),
|
||||
);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
namespace Composer\Package\Archiver;
|
||||
|
||||
/**
|
||||
* An exclude filter that processes gitignore and gitattributes
|
||||
* An exclude filter that processes gitattributes
|
||||
*
|
||||
* It respects export-ignore git attributes
|
||||
*
|
||||
|
@ -22,7 +22,7 @@ namespace Composer\Package\Archiver;
|
|||
class GitExcludeFilter extends BaseExcludeFilter
|
||||
{
|
||||
/**
|
||||
* Parses .gitignore and .gitattributes files if they exist
|
||||
* Parses .gitattributes if it exists
|
||||
*
|
||||
* @param string $sourcePath
|
||||
*/
|
||||
|
@ -30,12 +30,6 @@ class GitExcludeFilter extends BaseExcludeFilter
|
|||
{
|
||||
parent::__construct($sourcePath);
|
||||
|
||||
if (file_exists($sourcePath.'/.gitignore')) {
|
||||
$this->excludePatterns = $this->parseLines(
|
||||
file($sourcePath.'/.gitignore'),
|
||||
array($this, 'parseGitIgnoreLine')
|
||||
);
|
||||
}
|
||||
if (file_exists($sourcePath.'/.gitattributes')) {
|
||||
$this->excludePatterns = array_merge(
|
||||
$this->excludePatterns,
|
||||
|
@ -47,18 +41,6 @@ class GitExcludeFilter extends BaseExcludeFilter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback line parser which process gitignore lines
|
||||
*
|
||||
* @param string $line A line from .gitignore
|
||||
*
|
||||
* @return array{0: string, 1: bool, 2: bool} An exclude pattern for filter()
|
||||
*/
|
||||
public function parseGitIgnoreLine($line)
|
||||
{
|
||||
return $this->generatePattern($line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback parser which finds export-ignore rules in git attribute lines
|
||||
*
|
||||
|
@ -74,6 +56,10 @@ class GitExcludeFilter extends BaseExcludeFilter
|
|||
return $this->generatePattern($parts[0]);
|
||||
}
|
||||
|
||||
if (count($parts) == 2 && $parts[1] === '-export-ignore') {
|
||||
return $this->generatePattern('!'.$parts[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
<?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 Symfony\Component\Finder;
|
||||
|
||||
/**
|
||||
* An exclude filter that processes hgignore files
|
||||
*
|
||||
* @author Nils Adermann <naderman@naderman.de>
|
||||
*/
|
||||
class HgExcludeFilter extends BaseExcludeFilter
|
||||
{
|
||||
const HG_IGNORE_REGEX = 1;
|
||||
const HG_IGNORE_GLOB = 2;
|
||||
|
||||
/**
|
||||
* Either HG_IGNORE_REGEX or HG_IGNORE_GLOB
|
||||
* @var int
|
||||
*/
|
||||
protected $patternMode;
|
||||
|
||||
/**
|
||||
* Parses .hgignore file if it exist
|
||||
*
|
||||
* @param string $sourcePath
|
||||
*/
|
||||
public function __construct($sourcePath)
|
||||
{
|
||||
parent::__construct($sourcePath);
|
||||
|
||||
$this->patternMode = self::HG_IGNORE_REGEX;
|
||||
|
||||
if (file_exists($sourcePath.'/.hgignore')) {
|
||||
$this->excludePatterns = $this->parseLines(
|
||||
file($sourcePath.'/.hgignore'),
|
||||
array($this, 'parseHgIgnoreLine')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback line parser which process hgignore lines
|
||||
*
|
||||
* @param string $line A line from .hgignore
|
||||
*
|
||||
* @return array{0: string, 1: bool, 2: bool}|null An exclude pattern for filter()
|
||||
*/
|
||||
public function parseHgIgnoreLine($line)
|
||||
{
|
||||
if (preg_match('#^syntax\s*:\s*(glob|regexp)$#', $line, $matches)) {
|
||||
if ($matches[1] === 'glob') {
|
||||
$this->patternMode = self::HG_IGNORE_GLOB;
|
||||
} else {
|
||||
$this->patternMode = self::HG_IGNORE_REGEX;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->patternMode == self::HG_IGNORE_GLOB) {
|
||||
return $this->patternFromGlob($line);
|
||||
}
|
||||
|
||||
return $this->patternFromRegex($line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an exclude pattern for filter() from a hg glob expression
|
||||
*
|
||||
* @param string $line A line from .hgignore in glob mode
|
||||
*
|
||||
* @return array{0: string, 1: bool, 2: bool} An exclude pattern for filter()
|
||||
*/
|
||||
protected function patternFromGlob($line)
|
||||
{
|
||||
$pattern = '#'.substr(Finder\Glob::toRegex($line), 2, -1).'#';
|
||||
$pattern = str_replace('[^/]*', '.*', $pattern);
|
||||
|
||||
return array($pattern, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an exclude pattern for filter() from a hg regexp expression
|
||||
*
|
||||
* @param string $line A line from .hgignore in regexp mode
|
||||
*
|
||||
* @return array{0: string, 1: bool, 2: bool} An exclude pattern for filter()
|
||||
*/
|
||||
public function patternFromRegex($line)
|
||||
{
|
||||
// WTF need to escape the delimiter safely
|
||||
$pattern = '#'.preg_replace('/((?:\\\\\\\\)*)(\\\\?)#/', '\1\2\2\\#', $line).'#';
|
||||
|
||||
return array($pattern, false, true);
|
||||
}
|
||||
}
|
|
@ -156,40 +156,33 @@ class ArchivableFilesFinderTest extends TestCase
|
|||
{
|
||||
$this->skipIfNotExecutable('git');
|
||||
|
||||
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',
|
||||
'',
|
||||
'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',
|
||||
)));
|
||||
|
||||
$this->finder = new ArchivableFilesFinder($this->sources, array());
|
||||
|
@ -207,46 +200,6 @@ class ArchivableFilesFinderTest extends TestCase
|
|||
));
|
||||
}
|
||||
|
||||
public function testHgExcludes()
|
||||
{
|
||||
$this->skipIfNotExecutable('hg');
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public function testSkipExcludes()
|
||||
{
|
||||
$excludes = array(
|
||||
|
|
|
@ -27,14 +27,14 @@ class GitExcludeFilterTest extends TestCase
|
|||
{
|
||||
$filter = new GitExcludeFilter('/');
|
||||
|
||||
$this->assertEquals($expected, $filter->parseGitIgnoreLine($ignore));
|
||||
$this->assertEquals($expected, $filter->parseGitAttributesLine($ignore));
|
||||
}
|
||||
|
||||
public function providePatterns()
|
||||
{
|
||||
return array(
|
||||
array('app/config/parameters.yml', array('{(?=[^\.])app/(?=[^\.])config/(?=[^\.])parameters\.yml(?=$|/)}', false, false)),
|
||||
array('!app/config/parameters.yml', array('{(?=[^\.])app/(?=[^\.])config/(?=[^\.])parameters\.yml(?=$|/)}', true, false)),
|
||||
array('app/config/parameters.yml export-ignore', array('{(?=[^\.])app/(?=[^\.])config/(?=[^\.])parameters\.yml(?=$|/)}', false, false)),
|
||||
array('app/config/parameters.yml -export-ignore', array('{(?=[^\.])app/(?=[^\.])config/(?=[^\.])parameters\.yml(?=$|/)}', true, false)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
<?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\HgExcludeFilter;
|
||||
use Composer\Test\TestCase;
|
||||
|
||||
class HgExcludeFilterTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providePatterns
|
||||
*
|
||||
* @param string $ignore
|
||||
* @param mixed[] $expected
|
||||
*/
|
||||
public function testPatternEscape($ignore, $expected)
|
||||
{
|
||||
$filter = new HgExcludeFilter('/');
|
||||
|
||||
$this->assertEquals($expected, $filter->patternFromRegex($ignore));
|
||||
}
|
||||
|
||||
public function providePatterns()
|
||||
{
|
||||
return array(
|
||||
array('.#', array('#.\\##', false, true)),
|
||||
array('.\\#', array('#.\\\\\\##', false, true)),
|
||||
array('\\.#', array('#\\.\\##', false, true)),
|
||||
array('\\\\.\\\\\\\\#', array('#\\\\.\\\\\\\\\\##', false, true)),
|
||||
array('.\\\\\\\\\\#', array('#.\\\\\\\\\\\\\\##', false, true)),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue