From 4cf069535fca7ab64fdfeb6d281e2c98e6f8e259 Mon Sep 17 00:00:00 2001 From: johnstevenson Date: Tue, 12 Feb 2019 15:05:37 +0000 Subject: [PATCH 1/6] Improve safe junction logic --- src/Composer/Downloader/PathDownloader.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Composer/Downloader/PathDownloader.php b/src/Composer/Downloader/PathDownloader.php index a63a3d82d..4c71fb4f4 100644 --- a/src/Composer/Downloader/PathDownloader.php +++ b/src/Composer/Downloader/PathDownloader.php @@ -180,24 +180,21 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter } /** - * Returns true if junctions can be safely used on Windows + * Returns true if junctions can be created and safely used on Windows * * A PHP bug makes junction detection fragile, leading to possible data loss * when removing a package. See https://bugs.php.net/bug.php?id=77552 * * For safety we require a minimum version of Windows 7, so we can call the - * system rmdir which can detect junctions and not delete target content. + * system rmdir which will preserve target content if given a junction. + * + * The PHP bug was fixed in 7.2.16 and 7.3.3 (requires at least Windows 7). * * @return bool */ private function safeJunctions() { - // Bug fixed in 7.3.3 and 7.2.16 - if (PHP_VERSION_ID >= 70303 || (PHP_VERSION_ID >= 70216 && PHP_VERSION_ID < 70300)) { - return true; - } - - // Windows 7 is version 6.1 + // We need to call mklink, and rmdir on Windows 7 (version 6.1) return function_exists('proc_open') && (PHP_WINDOWS_VERSION_MAJOR > 6 || (PHP_WINDOWS_VERSION_MAJOR === 6 && PHP_WINDOWS_VERSION_MINOR >= 1)); From 61cd8664e56cfd71ed88537edabf616262518a9a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 20 Feb 2019 08:43:33 +0100 Subject: [PATCH 2/6] Avoid creating empty bitbucket files if there was no composer.json present in the original branch/tag --- .../Repository/Vcs/BitbucketDriver.php | 76 ++++++++++--------- src/Composer/Repository/Vcs/GitHubDriver.php | 2 +- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/Composer/Repository/Vcs/BitbucketDriver.php b/src/Composer/Repository/Vcs/BitbucketDriver.php index 24a4af4dd..556ca5012 100644 --- a/src/Composer/Repository/Vcs/BitbucketDriver.php +++ b/src/Composer/Repository/Vcs/BitbucketDriver.php @@ -124,50 +124,52 @@ abstract class BitbucketDriver extends VcsDriver $composer = $this->getBaseComposerInformation($identifier); - // specials for bitbucket - if (!isset($composer['support']['source'])) { - $label = array_search( - $identifier, - $this->getTags() - ) ?: array_search( - $identifier, - $this->getBranches() - ) ?: $identifier; + if ($composer) { + // specials for bitbucket + if (!isset($composer['support']['source'])) { + $label = array_search( + $identifier, + $this->getTags() + ) ?: array_search( + $identifier, + $this->getBranches() + ) ?: $identifier; - if (array_key_exists($label, $tags = $this->getTags())) { - $hash = $tags[$label]; - } elseif (array_key_exists($label, $branches = $this->getBranches())) { - $hash = $branches[$label]; + if (array_key_exists($label, $tags = $this->getTags())) { + $hash = $tags[$label]; + } elseif (array_key_exists($label, $branches = $this->getBranches())) { + $hash = $branches[$label]; + } + + if (! isset($hash)) { + $composer['support']['source'] = sprintf( + 'https://%s/%s/%s/src', + $this->originUrl, + $this->owner, + $this->repository + ); + } else { + $composer['support']['source'] = sprintf( + 'https://%s/%s/%s/src/%s/?at=%s', + $this->originUrl, + $this->owner, + $this->repository, + $hash, + $label + ); + } } - - if (! isset($hash)) { - $composer['support']['source'] = sprintf( - 'https://%s/%s/%s/src', + if (!isset($composer['support']['issues']) && $this->hasIssues) { + $composer['support']['issues'] = sprintf( + 'https://%s/%s/%s/issues', $this->originUrl, $this->owner, $this->repository ); - } else { - $composer['support']['source'] = sprintf( - 'https://%s/%s/%s/src/%s/?at=%s', - $this->originUrl, - $this->owner, - $this->repository, - $hash, - $label - ); } - } - if (!isset($composer['support']['issues']) && $this->hasIssues) { - $composer['support']['issues'] = sprintf( - 'https://%s/%s/%s/issues', - $this->originUrl, - $this->owner, - $this->repository - ); - } - if (!isset($composer['homepage'])) { - $composer['homepage'] = empty($this->website) ? $this->homeUrl : $this->website; + if (!isset($composer['homepage'])) { + $composer['homepage'] = empty($this->website) ? $this->homeUrl : $this->website; + } } $this->infoCache[$identifier] = $composer; diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index d0b721af9..40a75b4dd 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -152,8 +152,8 @@ class GitHubDriver extends VcsDriver } $composer = $this->getBaseComposerInformation($identifier); - if ($composer) { + if ($composer) { // specials for github if (!isset($composer['support']['source'])) { $label = array_search($identifier, $this->getTags()) ?: array_search($identifier, $this->getBranches()) ?: $identifier; From ba346ef04d7cc6fdbf9423b06f51e48485d20b77 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 21 Feb 2019 12:57:27 +0100 Subject: [PATCH 3/6] Add forward compatibility for upcoming v2 installed.json format, refs #7999 --- src/Composer/Repository/FilesystemRepository.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Composer/Repository/FilesystemRepository.php b/src/Composer/Repository/FilesystemRepository.php index bde55aad3..204aa095d 100644 --- a/src/Composer/Repository/FilesystemRepository.php +++ b/src/Composer/Repository/FilesystemRepository.php @@ -51,6 +51,11 @@ class FilesystemRepository extends WritableArrayRepository try { $packages = $this->file->read(); + // forward compatibility for composer v2 installed.json + if (isset($packages['packages'])) { + $packages = $packages['packages']; + } + if (!is_array($packages)) { throw new \UnexpectedValueException('Could not parse package list from the repository'); } From 427116749558f99e4c04ffa3fe358ebfd74d2fa5 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 21 Feb 2019 13:39:12 +0100 Subject: [PATCH 4/6] Improve version reporting --- src/Composer/Compiler.php | 1 + src/Composer/Composer.php | 37 ++++++++++++++++++++++ src/Composer/Console/Application.php | 6 ++-- src/Composer/Util/StreamContextFactory.php | 2 +- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/Composer/Compiler.php b/src/Composer/Compiler.php index 27b1f4816..2c763d053 100644 --- a/src/Composer/Compiler.php +++ b/src/Composer/Compiler.php @@ -193,6 +193,7 @@ class Compiler $content = str_replace('@package_version@', $this->version, $content); $content = str_replace('@package_branch_alias_version@', $this->branchAliasVersion, $content); $content = str_replace('@release_date@', $this->versionDate->format('Y-m-d H:i:s'), $content); + $content = preg_replace('{SOURCE_VERSION = \'[^\']+\';}', 'SOURCE_VERSION = \'\';', $content); } $phar->addFromString($path, $content); diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index a3972f44f..7b60b28af 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -29,9 +29,46 @@ use Composer\Package\Archiver\ArchiveManager; */ class Composer { + /* + * Examples of the following constants in the various configurations they can be in + * + * releases (phar): + * const VERSION = '1.8.2'; + * const BRANCH_ALIAS_VERSION = ''; + * const RELEASE_DATE = '2019-01-29 15:00:53'; + * const SOURCE_VERSION = ''; + * + * snapshot builds (phar): + * const VERSION = 'd3873a05650e168251067d9648845c220c50e2d7'; + * const BRANCH_ALIAS_VERSION = '1.9-dev'; + * const RELEASE_DATE = '2019-02-20 07:43:56'; + * const SOURCE_VERSION = ''; + * + * source (git clone): + * const VERSION = '@package_version@'; + * const BRANCH_ALIAS_VERSION = '@package_branch_alias_version@'; + * const RELEASE_DATE = '@release_date@'; + * const SOURCE_VERSION = '1.8-dev+source'; + */ const VERSION = '@package_version@'; const BRANCH_ALIAS_VERSION = '@package_branch_alias_version@'; const RELEASE_DATE = '@release_date@'; + const SOURCE_VERSION = '1.8-dev+source'; + + public static function getVersion() + { + // no replacement done, this must be a source checkout + if (self::VERSION === '@package_version'.'@') { + return self::SOURCE_VERSION; + } + + // we have a branch alias and version is a commit id, this must be a snapshot build + if (self::BRANCH_ALIAS_VERSION !== '' && preg_match('{^[a-f0-9]{40}$}', self::VERSION)) { + return self::BRANCH_ALIAS_VERSION.'+'.self::VERSION; + } + + return self::VERSION; + } /** * @var Package\RootPackageInterface diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index ccf83c943..a829ac38a 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -89,7 +89,7 @@ class Application extends BaseApplication $this->io = new NullIO(); - parent::__construct('Composer', Composer::VERSION); + parent::__construct('Composer', Composer::getVersion()); } /** @@ -181,7 +181,7 @@ class Application extends BaseApplication if (!$isProxyCommand) { $io->writeError(sprintf( 'Running %s (%s) with %s on %s', - Composer::VERSION, + Composer::getVersion(), Composer::RELEASE_DATE, defined('HHVM_VERSION') ? 'HHVM '.HHVM_VERSION : 'PHP '.PHP_VERSION, function_exists('php_uname') ? php_uname('s') . ' / ' . php_uname('r') : 'Unknown OS' @@ -425,7 +425,7 @@ class Application extends BaseApplication */ public function getLongVersion() { - if (Composer::BRANCH_ALIAS_VERSION) { + if (Composer::BRANCH_ALIAS_VERSION && Composer::BRANCH_ALIAS_VERSION !== '@package_branch_alias_version'.'@') { return sprintf( '%s version %s (%s) %s', $this->getName(), diff --git a/src/Composer/Util/StreamContextFactory.php b/src/Composer/Util/StreamContextFactory.php index 8dfd6624a..da3e578bd 100644 --- a/src/Composer/Util/StreamContextFactory.php +++ b/src/Composer/Util/StreamContextFactory.php @@ -142,7 +142,7 @@ final class StreamContextFactory if (!isset($options['http']['header']) || false === stripos(implode('', $options['http']['header']), 'user-agent')) { $options['http']['header'][] = sprintf( 'User-Agent: Composer/%s (%s; %s; %s%s)', - Composer::VERSION === '@package_version@' ? 'source' : Composer::VERSION, + Composer::getVersion(), function_exists('php_uname') ? php_uname('s') : 'Unknown', function_exists('php_uname') ? php_uname('r') : 'Unknown', $phpVersion, From 0f36a42d614deb4638f5e00cd3a86309df78db72 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 21 Feb 2019 14:05:56 +0100 Subject: [PATCH 5/6] Allow filtering of warning/info msgs by composer version --- .../Repository/ComposerRepository.php | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 8a5da2b23..b9de0d7ea 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -20,6 +20,7 @@ use Composer\DependencyResolver\Pool; use Composer\Json\JsonFile; use Composer\Cache; use Composer\Config; +use Composer\Composer; use Composer\Factory; use Composer\IO\IOInterface; use Composer\Util\RemoteFilesystem; @@ -699,12 +700,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } $data = JsonFile::parseJson($json, $filename); - if (!empty($data['warning'])) { - $this->io->writeError('Warning from '.$this->url.': '.$data['warning'].''); - } - if (!empty($data['info'])) { - $this->io->writeError('Info from '.$this->url.': '.$data['info'].''); - } + $this->outputWarnings($data); if ($cacheKey) { if ($storeLastModifiedTime) { @@ -769,12 +765,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } $data = JsonFile::parseJson($json, $filename); - if (!empty($data['warning'])) { - $this->io->writeError('Warning from '.$this->url.': '.$data['warning'].''); - } - if (!empty($data['info'])) { - $this->io->writeError('Info from '.$this->url.': '.$data['info'].''); - } + $this->outputWarnings($data); $lastModifiedDate = $rfs->findHeaderValue($rfs->getLastHeaders(), 'last-modified'); if ($lastModifiedDate) { @@ -835,4 +826,24 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito // wipe rootData as it is fully consumed at this point and this saves some memory $this->rootData = true; } + + private function outputWarnings($data) + { + foreach (array('warning', 'info') as $type) { + if (empty($data[$type])) { + continue; + } + + if (!empty($data[$type . '-versions'])) { + $versionParser = new VersionParser(); + $constraint = $versionParser->parseConstraints($data[$type . '-versions']); + $composer = new Constraint('==', $versionParser->normalize(Composer::getVersion())); + if (!$constraint->matches($composer)) { + continue; + } + } + + $this->io->writeError('<'.$type.'>'.ucfirst($type).' from '.$this->url.': '.$data[$type].''); + } + } } From 60f198c17d99728b0c1adb5b17e581fe274e34e8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 21 Feb 2019 14:06:41 +0100 Subject: [PATCH 6/6] Update target version --- src/Composer/Composer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Composer.php b/src/Composer/Composer.php index 7b60b28af..0d5faceb2 100644 --- a/src/Composer/Composer.php +++ b/src/Composer/Composer.php @@ -53,7 +53,7 @@ class Composer const VERSION = '@package_version@'; const BRANCH_ALIAS_VERSION = '@package_branch_alias_version@'; const RELEASE_DATE = '@release_date@'; - const SOURCE_VERSION = '1.8-dev+source'; + const SOURCE_VERSION = '1.9-dev+source'; public static function getVersion() {