1
0
Fork 0

Merge remote-tracking branch 'upstream/master'

pull/6097/head
Kael Shipman 2017-01-23 13:07:22 -06:00
commit 9a755fa7d4
15 changed files with 115 additions and 36 deletions

View File

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

View File

@ -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 This is also the repository type that packagist uses. To reference a
`composer` repository, just supply the path before the `packages.json` file. `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 the repository would be `packagist.org`. For `example.org/packages.json` the
repository URL would be `example.org`. repository URL would be `example.org`.

View File

@ -45,6 +45,7 @@ class ArchiveCommand extends BaseCommand
new InputOption('dir', null, InputOption::VALUE_REQUIRED, 'Write the archive to this directory'), 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.' new InputOption('file', null, InputOption::VALUE_REQUIRED, 'Write the archive with the given file name.'
.' Note that the format will be appended.'), .' Note that the format will be appended.'),
new InputOption('ignore-filters', false, InputOption::VALUE_NONE, 'Ignore filters when saving package')
)) ))
->setHelp(<<<EOT ->setHelp(<<<EOT
The <info>archive</info> command creates an archive of the specified format The <info>archive</info> command creates an archive of the specified format
@ -82,7 +83,8 @@ EOT
$input->getArgument('version'), $input->getArgument('version'),
$input->getOption('format'), $input->getOption('format'),
$input->getOption('dir'), $input->getOption('dir'),
$input->getOption('file') $input->getOption('file'),
$input->getOption('ignore-filters')
); );
if (0 === $returnCode && $composer) { if (0 === $returnCode && $composer) {
@ -92,7 +94,7 @@ EOT
return $returnCode; 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; $factory = new Factory;
$downloadManager = $factory->createDownloadManager($io, $config); $downloadManager = $factory->createDownloadManager($io, $config);
@ -109,7 +111,7 @@ EOT
} }
$io->writeError('<info>Creating the archive into "'.$dest.'".</info>'); $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; $fs = new Filesystem;
$shortPath = $fs->findShortestPath(getcwd(), $packagePath, true); $shortPath = $fs->findShortestPath(getcwd(), $packagePath, true);

View File

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

View File

@ -39,13 +39,13 @@ class OutdatedCommand extends ShowCommand
->setHelp(<<<EOT ->setHelp(<<<EOT
The outdated command is just a proxy for `composer show -l` 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. - <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 - <comment>yellow</comment> (~): Dependency has a new version available that includes backwards
compatibility breaks according to semver, so upgrade when you can but it compatibility breaks according to semver, so upgrade when you can but it
may involve work. 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 EOT

View File

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

View File

@ -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>'); $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>'); $io->writeError('<warning>You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.org/xdebug</warning>');
} }

View File

@ -175,12 +175,7 @@ class EventDispatcher
$args = $event->getArguments(); $args = $event->getArguments();
$flags = $event->getFlags(); $flags = $event->getFlags();
if (substr($callable, 0, 10) === '@composer ') { if (substr($callable, 0, 10) === '@composer ') {
$finder = new PhpExecutableFinder(); $exec = $this->getPhpExecCommand() . ' ' . ProcessExecutor::escape(getenv('COMPOSER_BINARY')) . substr($callable, 9);
$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);
if (0 !== ($exitCode = $this->process->execute($exec))) { 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())); $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 ') { if (substr($exec, 0, 5) === '@php ') {
$finder = new PhpExecutableFinder(); $exec = $this->getPhpExecCommand() . ' ' . substr($exec, 5);
$phpPath = $finder->find();
if (!$phpPath) {
throw new \RuntimeException('Failed to locate PHP binary to execute "'.$exec.'"');
}
$exec = $phpPath . ' ' . substr($exec, 5);
} }
if (0 !== ($exitCode = $this->process->execute($exec))) { if (0 !== ($exitCode = $this->process->execute($exec))) {
@ -259,6 +249,19 @@ class EventDispatcher
return $return; 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 $className
* @param string $methodName * @param string $methodName

View File

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

View File

@ -37,18 +37,23 @@ class ArchivableFilesFinder extends \FilterIterator
* *
* @param string $sources Path to source files to be archived * @param string $sources Path to source files to be archived
* @param array $excludes Composer's own exclude rules from composer.json * @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(); $fs = new Filesystem();
$sources = $fs->normalizePath($sources); $sources = $fs->normalizePath($sources);
$filters = array( if ($ignoreFilters) {
new HgExcludeFilter($sources), $filters = array();
new GitExcludeFilter($sources), } else {
new ComposerExcludeFilter($sources, $excludes), $filters = array(
); new HgExcludeFilter($sources),
new GitExcludeFilter($sources),
new ComposerExcludeFilter($sources, $excludes),
);
}
$this->finder = new Finder(); $this->finder = new Finder();

View File

@ -99,11 +99,12 @@ class ArchiveManager
* @param string $targetDir The directory where to build the archive * @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 * @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 * 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 \InvalidArgumentException
* @throws \RuntimeException * @throws \RuntimeException
* @return string The path of the created archive * @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)) { if (empty($format)) {
throw new \InvalidArgumentException('Format must be specified'); throw new \InvalidArgumentException('Format must be specified');
@ -163,7 +164,7 @@ class ArchiveManager
$tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format; $tempTarget = sys_get_temp_dir().'/composer_archive'.uniqid().'.'.$format;
$filesystem->ensureDirectoryExists(dirname($tempTarget)); $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); $filesystem->rename($archivePath, $target);
// cleanup temporary download // cleanup temporary download

View File

@ -29,7 +29,7 @@ interface ArchiverInterface
* *
* @return string The path to the written archive file * @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. * Format supported by the archiver.

View File

@ -34,7 +34,7 @@ class PharArchiver implements ArchiverInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function archive($sources, $target, $format, array $excludes = array()) public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
{ {
$sources = realpath($sources); $sources = realpath($sources);
@ -53,7 +53,7 @@ class PharArchiver implements ArchiverInterface
} }
$phar = new \PharData($target, null, null, static::$formats[$format]); $phar = new \PharData($target, null, null, static::$formats[$format]);
$files = new ArchivableFilesFinder($sources, $excludes); $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
$filesOnly = new ArchivableFilesFilter($files); $filesOnly = new ArchivableFilesFilter($files);
$phar->buildFromIterator($filesOnly, $sources); $phar->buildFromIterator($filesOnly, $sources);
$filesOnly->addEmptyDir($phar, $sources); $filesOnly->addEmptyDir($phar, $sources);

View File

@ -27,7 +27,7 @@ class ZipArchiver implements ArchiverInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function archive($sources, $target, $format, array $excludes = array()) public function archive($sources, $target, $format, array $excludes = array(), $ignoreFilters = false)
{ {
$fs = new Filesystem(); $fs = new Filesystem();
$sources = $fs->normalizePath($sources); $sources = $fs->normalizePath($sources);
@ -35,7 +35,7 @@ class ZipArchiver implements ArchiverInterface
$zip = new ZipArchive(); $zip = new ZipArchive();
$res = $zip->open($target, ZipArchive::CREATE); $res = $zip->open($target, ZipArchive::CREATE);
if ($res === true) { if ($res === true) {
$files = new ArchivableFilesFinder($sources, $excludes); $files = new ArchivableFilesFinder($sources, $excludes, $ignoreFilters);
foreach ($files as $file) { foreach ($files as $file) {
/** @var $file \SplFileInfo */ /** @var $file \SplFileInfo */
$filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/'); $filepath = strtr($file->getPath()."/".$file->getFilename(), '\\', '/');

View File

@ -235,6 +235,61 @@ class ArchivableFilesFinderTest extends TestCase
$this->assertArchivableFiles($expectedFiles); $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() protected function getArchivableFiles()
{ {
$files = array(); $files = array();