diff --git a/src/Composer/Command/ArchiveCommand.php b/src/Composer/Command/ArchiveCommand.php index d9ff8479c..23affc5b1 100644 --- a/src/Composer/Command/ArchiveCommand.php +++ b/src/Composer/Command/ArchiveCommand.php @@ -45,6 +45,7 @@ class ArchiveCommand extends BaseCommand new InputOption('dir', null, InputOption::VALUE_REQUIRED, 'Write the archive to this directory'), new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.' .' Note that the format will be appended.'), + new InputOption('ignore-filters', false, InputOption::VALUE_NONE, 'Ignore filters when saving package') )) ->setHelp(<<archive command creates an archive of the specified format @@ -82,7 +83,8 @@ EOT $input->getArgument('version'), $input->getOption('format'), $input->getOption('dir'), - $input->getOption('file') + $input->getOption('file'), + $input->getOption('ignore-filters') ); if (0 === $returnCode && $composer) { @@ -92,7 +94,7 @@ EOT return $returnCode; } - protected function archive(IOInterface $io, Config $config, $packageName = null, $version = null, $format = 'tar', $dest = '.', $fileName = null) + protected function archive(IOInterface $io, Config $config, $packageName = null, $version = null, $format = 'tar', $dest = '.', $fileName = null, $ignoreFilters) { $factory = new Factory; $downloadManager = $factory->createDownloadManager($io, $config); @@ -109,7 +111,7 @@ EOT } $io->writeError('Creating the archive into "'.$dest.'".'); - $packagePath = $archiveManager->archive($package, $format, $dest, $fileName); + $packagePath = $archiveManager->archive($package, $format, $dest, $fileName, $ignoreFilters); $fs = new Filesystem; $shortPath = $fs->findShortestPath(getcwd(), $packagePath, true); diff --git a/src/Composer/Package/Archiver/ArchivableFilesFinder.php b/src/Composer/Package/Archiver/ArchivableFilesFinder.php index f80724da7..e99f5343f 100644 --- a/src/Composer/Package/Archiver/ArchivableFilesFinder.php +++ b/src/Composer/Package/Archiver/ArchivableFilesFinder.php @@ -37,18 +37,23 @@ class ArchivableFilesFinder extends \FilterIterator * * @param string $sources Path to source files to be archived * @param array $excludes Composer's own exclude rules from composer.json + * @param boolean $ignoreFilters Ignore filters when looking for files */ - public function __construct($sources, array $excludes) + public function __construct($sources, array $excludes, $ignoreFilters = false) { $fs = new Filesystem(); $sources = $fs->normalizePath($sources); - $filters = array( - new HgExcludeFilter($sources), - new GitExcludeFilter($sources), - new ComposerExcludeFilter($sources, $excludes), - ); + if ($ignoreFilters) { + $filters = array(); + } else { + $filters = array( + new HgExcludeFilter($sources), + new GitExcludeFilter($sources), + new ComposerExcludeFilter($sources, $excludes), + ); + } $this->finder = new Finder(); diff --git a/src/Composer/Package/Archiver/ArchiveManager.php b/src/Composer/Package/Archiver/ArchiveManager.php index 52fe7bed3..e1558c1dd 100644 --- a/src/Composer/Package/Archiver/ArchiveManager.php +++ b/src/Composer/Package/Archiver/ArchiveManager.php @@ -99,11 +99,12 @@ class ArchiveManager * @param string $targetDir The directory where to build the archive * @param string|null $fileName The relative file name to use for the archive, or null to generate * the package name. Note that the format will be appended to this name + * @param boolean $ignoreFilters Ignore filters when looking for files in the package * @throws \InvalidArgumentException * @throws \RuntimeException * @return string The path of the created archive */ - public function archive(PackageInterface $package, $format, $targetDir, $fileName = null) + public function archive(PackageInterface $package, $format, $targetDir, $fileName = null, $ignoreFilters = false) { if (empty($format)) { throw new \InvalidArgumentException('Format must be specified'); @@ -163,7 +164,7 @@ class ArchiveManager $tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format; $filesystem->ensureDirectoryExists(dirname($tempTarget)); - $archivePath = $usableArchiver->archive($sourcePath, $tempTarget, $format, $package->getArchiveExcludes()); + $archivePath = $usableArchiver->archive($sourcePath, $tempTarget, $format, $package->getArchiveExcludes(), $ignoreFilters); $filesystem->rename($archivePath, $target); // cleanup temporary download diff --git a/src/Composer/Package/Archiver/ArchiverInterface.php b/src/Composer/Package/Archiver/ArchiverInterface.php index a625f5c07..4e5fa54f9 100644 --- a/src/Composer/Package/Archiver/ArchiverInterface.php +++ b/src/Composer/Package/Archiver/ArchiverInterface.php @@ -29,7 +29,7 @@ interface ArchiverInterface * * @return string The path to the written archive file */ - public function archive($sources, $target, $format, array $excludes = array()); + public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false); /** * Format supported by the archiver. diff --git a/src/Composer/Package/Archiver/PharArchiver.php b/src/Composer/Package/Archiver/PharArchiver.php index 5c9afe336..7f64c343e 100644 --- a/src/Composer/Package/Archiver/PharArchiver.php +++ b/src/Composer/Package/Archiver/PharArchiver.php @@ -34,7 +34,7 @@ class PharArchiver implements ArchiverInterface /** * {@inheritdoc} */ - public function archive($sources, $target, $format, array $excludes = array()) + public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false) { $sources = realpath($sources); @@ -53,7 +53,7 @@ class PharArchiver implements ArchiverInterface } $phar = new \PharData($target, null, null, static::$formats[$format]); - $files = new ArchivableFilesFinder($sources, $excludes); + $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters); $filesOnly = new ArchivableFilesFilter($files); $phar->buildFromIterator($filesOnly, $sources); $filesOnly->addEmptyDir($phar, $sources); diff --git a/src/Composer/Package/Archiver/ZipArchiver.php b/src/Composer/Package/Archiver/ZipArchiver.php index 87337558e..aaa41aea3 100644 --- a/src/Composer/Package/Archiver/ZipArchiver.php +++ b/src/Composer/Package/Archiver/ZipArchiver.php @@ -27,7 +27,7 @@ class ZipArchiver implements ArchiverInterface /** * {@inheritdoc} */ - public function archive($sources, $target, $format, array $excludes = array()) + public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false) { $fs = new Filesystem(); $sources = $fs->normalizePath($sources); @@ -35,7 +35,7 @@ class ZipArchiver implements ArchiverInterface $zip = new ZipArchive(); $res = $zip->open($target, ZipArchive::CREATE); if ($res === true) { - $files = new ArchivableFilesFinder($sources, $excludes); + $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters); foreach ($files as $file) { /** @var $file \SplFileInfo */ $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/'); diff --git a/tests/Composer/Test/Package/Archiver/ArchivableFilesFinderTest.php b/tests/Composer/Test/Package/Archiver/ArchivableFilesFinderTest.php index 76629276d..669ec7a3f 100644 --- a/tests/Composer/Test/Package/Archiver/ArchivableFilesFinderTest.php +++ b/tests/Composer/Test/Package/Archiver/ArchivableFilesFinderTest.php @@ -235,6 +235,61 @@ class ArchivableFilesFinderTest extends TestCase $this->assertArchivableFiles($expectedFiles); } + public function testSkipExcludes() + { + $excludes = array( + 'prefixB.foo', + ); + + $this->finder = new ArchivableFilesFinder($this->sources, $excludes, true); + + $this->assertArchivableFiles(array( + '/!important!.txt', + '/!important_too!.txt', + '/#weirdfile', + '/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', + )); + } + protected function getArchivableFiles() { $files = array();