Browse Source

Merge remote-tracking branch 'upstream/master'

Kael Shipman 8 years ago
parent
commit
9a755fa7d4

+ 2 - 0
bin/composer

@@ -48,6 +48,8 @@ if (function_exists('ini_set')) {
     unset($memoryInBytes, $memoryLimit);
 }
 
+putenv('COMPOSER_BINARY='.realpath($_SERVER['argv'][0]));
+
 // run the command application
 $application = new Application();
 $application->run(null, $output);

+ 1 - 1
doc/05-repositories.md

@@ -58,7 +58,7 @@ The main repository type is the `composer` repository. It uses a single
 
 This is also the repository type that packagist uses. To reference a
 `composer` repository, just supply the path before the `packages.json` file.
-In case of packagist, that file is located at `/packages.json`, so the URL of
+In the case of packagist, that file is located at `/packages.json`, so the URL of
 the repository would be `packagist.org`. For `example.org/packages.json` the
 repository URL would be `example.org`.
 

+ 5 - 3
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(<<<EOT
 The <info>archive</info> 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('<info>Creating the archive into "'.$dest.'".</info>');
-        $packagePath = $archiveManager->archive($package, $format, $dest, $fileName);
+        $packagePath = $archiveManager->archive($package, $format, $dest, $fileName, $ignoreFilters);
         $fs = new Filesystem;
         $shortPath = $fs->findShortestPath(getcwd(), $packagePath, true);
 

+ 5 - 0
src/Composer/Command/CreateProjectCommand.php

@@ -23,6 +23,7 @@ use Composer\Package\BasePackage;
 use Composer\DependencyResolver\Pool;
 use Composer\DependencyResolver\Operation\InstallOperation;
 use Composer\Package\Version\VersionSelector;
+use Composer\Package\AliasPackage;
 use Composer\Repository\RepositoryFactory;
 use Composer\Repository\CompositeRepository;
 use Composer\Repository\PlatformRepository;
@@ -330,6 +331,10 @@ EOT
             $io->writeError('<info>Plugins have been disabled.</info>');
         }
 
+        if ($package instanceof AliasPackage) {
+            $package = $package->getAliasOf();
+        }
+
         if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) {
             $package->setSourceReference(substr($package->getPrettyVersion(), 4));
         }

+ 4 - 4
src/Composer/Command/OutdatedCommand.php

@@ -39,13 +39,13 @@ class OutdatedCommand extends ShowCommand
             ->setHelp(<<<EOT
 The outdated command is just a proxy for `composer show -l`
 
-The color coding for dependency versions is as such:
+The color coding (or signage if you have ANSI colors disabled) for dependency versions is as such:
 
-- <info>green</info>: Dependency is in the latest version and is up to date.
-- <comment>yellow</comment>: Dependency has a new version available that includes backwards
+- <info>green</info> (=): Dependency is in the latest version and is up to date.
+- <comment>yellow</comment> (~): Dependency has a new version available that includes backwards
   compatibility breaks according to semver, so upgrade when you can but it
   may involve work.
-- <highlight>red</highlight>: Dependency has a new version that is semver-compatible and you should upgrade it.
+- <highlight>red</highlight> (!): Dependency has a new version that is semver-compatible and you should upgrade it.
 
 
 EOT

+ 7 - 1
src/Composer/Command/ShowCommand.php

@@ -173,7 +173,7 @@ EOT
                     }
 
                     $io->writeError('Package ' . $packageFilter . ' not found in ' . $options['working-dir'] . '/composer.json');
-                    return;
+                    return 1;
                 }
             } else {
                 $versions = array($package->getPrettyVersion() => $package->getVersion());
@@ -317,6 +317,9 @@ EOT
                 $writeVersion = !$input->getOption('name-only') && !$input->getOption('path') && $showVersion && ($nameLength + $versionLength + 3 <= $width);
                 $writeLatest = $writeVersion && $showLatest && ($nameLength + $versionLength + $latestLength + 3 <= $width);
                 $writeDescription = !$input->getOption('name-only') && !$input->getOption('path') && ($nameLength + $versionLength + $latestLength + 24 <= $width);
+                if ($writeLatest && !$io->isDecorated()) {
+                    $latestLength += 2;
+                }
                 $hasOutdatedPackages = false;
                 foreach ($packages[$type] as $package) {
                     if (is_object($package)) {
@@ -339,6 +342,9 @@ EOT
                         if ($writeLatest && $latestPackackage) {
                             $latestVersion = $latestPackackage->getFullPrettyVersion();
                             $style = $this->getVersionStyle($latestPackackage, $package);
+                            if (!$io->isDecorated()) {
+                                $latestVersion = str_replace(array('info', 'highlight', 'comment'), array('=', '!', '~'), $style) . ' ' . $latestVersion;
+                            }
                             $io->write(' <'.$style.'>' . str_pad($latestVersion, $latestLength, ' ') . '</'.$style.'>', false);
                         }
 

+ 1 - 1
src/Composer/Console/Application.php

@@ -166,7 +166,7 @@ class Application extends BaseApplication
                 $io->writeError('<warning>Composer only officially supports PHP 5.3.2 and above, you will most likely encounter problems with your PHP '.PHP_VERSION.', upgrading is strongly recommended.</warning>');
             }
 
-            if (extension_loaded('xdebug') && (!getenv('COMPOSER_DISABLE_XDEBUG_WARN') || getenv('COMPOSER_ALLOW_XDEBUG'))) {
+            if (extension_loaded('xdebug') && !getenv('COMPOSER_DISABLE_XDEBUG_WARN')) {
                 $io->writeError('<warning>You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug</warning>');
             }
 

+ 15 - 12
src/Composer/EventDispatcher/EventDispatcher.php

@@ -175,12 +175,7 @@ class EventDispatcher
                 $args = $event->getArguments();
                 $flags = $event->getFlags();
                 if (substr($callable, 0, 10) === '@composer ') {
-                    $finder = new PhpExecutableFinder();
-                    $phpPath = $finder->find();
-                    if (!$phpPath) {
-                        throw new \RuntimeException('Failed to locate PHP binary to execute '.$scriptName);
-                    }
-                    $exec = $phpPath . '  ' . realpath($_SERVER['argv'][0]) . substr($callable, 9);
+                    $exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(getenv('COMPOSER_BINARY')) . substr($callable, 9);
                     if (0 !== ($exitCode = $this->process->execute($exec))) {
                         $this->io->writeError(sprintf('<error>Script %s handling the %s event returned with error code '.$exitCode.'</error>', $callable, $event->getName()));
 
@@ -234,12 +229,7 @@ class EventDispatcher
                 }
 
                 if (substr($exec, 0, 5) === '@php ') {
-                    $finder = new PhpExecutableFinder();
-                    $phpPath = $finder->find();
-                    if (!$phpPath) {
-                        throw new \RuntimeException('Failed to locate PHP binary to execute "'.$exec.'"');
-                    }
-                    $exec = $phpPath . ' ' . substr($exec, 5);
+                    $exec = $this->getPhpExecCommand() . ' ' . substr($exec, 5);
                 }
 
                 if (0 !== ($exitCode = $this->process->execute($exec))) {
@@ -259,6 +249,19 @@ class EventDispatcher
         return $return;
     }
 
+    protected function getPhpExecCommand()
+    {
+        $finder = new PhpExecutableFinder();
+        $phpPath = $finder->find();
+        if (!$phpPath) {
+            throw new \RuntimeException('Failed to locate PHP binary to execute '.$scriptName);
+        }
+
+        $memoryFlag = ' -d memory_limit='.ini_get('memory_limit');
+
+        return ProcessExecutor::escape($phpPath) . $memoryFlag;
+    }
+
     /**
      * @param string $className
      * @param string $methodName

+ 1 - 1
src/Composer/Installer.php

@@ -605,7 +605,7 @@ class Installer
                 $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation);
             }
 
-            if ($this->executeOperations) {
+            if ($this->executeOperations || $this->writeLock) {
                 $localRepo->write();
             }
         }

+ 11 - 6
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();
 

+ 3 - 2
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

+ 1 - 1
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.

+ 2 - 2
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);

+ 2 - 2
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(), '\\', '/');

+ 55 - 0
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();