Browse Source

Merge branch 'master' into 2.0

Jordi Boggiano 6 years ago
parent
commit
5f988a34a6

+ 1 - 0
src/Composer/Compiler.php

@@ -194,6 +194,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);

+ 37 - 1
src/Composer/Composer.php

@@ -29,10 +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 = '2.0-source';
+    const SOURCE_VERSION = '2.0-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

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

@@ -91,7 +91,7 @@ class Application extends BaseApplication
 
         $this->io = new NullIO();
 
-        parent::__construct('Composer', Composer::VERSION);
+        parent::__construct('Composer', Composer::getVersion());
     }
 
     /**
@@ -190,7 +190,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'
@@ -440,7 +440,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(
                 '<info>%s</info> version <comment>%s (%s)</comment> %s',
                 $this->getName(),

+ 5 - 8
src/Composer/Downloader/PathDownloader.php

@@ -189,24 +189,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));

+ 24 - 18
src/Composer/Repository/ComposerRepository.php

@@ -19,6 +19,7 @@ use Composer\Package\Version\VersionParser;
 use Composer\Json\JsonFile;
 use Composer\Cache;
 use Composer\Config;
+use Composer\Composer;
 use Composer\Factory;
 use Composer\IO\IOInterface;
 use Composer\Util\HttpDownloader;
@@ -961,12 +962,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
                 }
 
                 $data = $response->decodeJson();
-                if (!empty($data['warning'])) {
-                    $this->io->writeError('<warning>Warning from '.$this->url.': '.$data['warning'].'</warning>');
-                }
-                if (!empty($data['info'])) {
-                    $this->io->writeError('<info>Info from '.$this->url.': '.$data['info'].'</info>');
-                }
+                $this->outputWarnings($data);
 
                 if ($cacheKey) {
                     if ($storeLastModifiedTime) {
@@ -1040,12 +1036,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
                 }
 
                 $data = $response->decodeJson();
-                if (!empty($data['warning'])) {
-                    $this->io->writeError('<warning>Warning from '.$this->url.': '.$data['warning'].'</warning>');
-                }
-                if (!empty($data['info'])) {
-                    $this->io->writeError('<info>Info from '.$this->url.': '.$data['info'].'</info>');
-                }
+                $this->outputWarnings($data);
 
                 $lastModifiedDate = $response->getHeader('last-modified');
                 $response->collect();
@@ -1110,12 +1101,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
             }
 
             $data = $response->decodeJson();
-            if (!empty($data['warning'])) {
-                $io->writeError('<warning>Warning from '.$url.': '.$data['warning'].'</warning>');
-            }
-            if (!empty($data['info'])) {
-                $io->writeError('<info>Info from '.$url.': '.$data['info'].'</info>');
-            }
+            $this->outputWarnings($data);
 
             $lastModifiedDate = $response->getHeader('last-modified');
             $response->collect();
@@ -1175,4 +1161,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].'</'.$type.'>');
+        }
+    }
 }

+ 5 - 0
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');
             }

+ 40 - 38
src/Composer/Repository/Vcs/BitbucketDriver.php

@@ -125,50 +125,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 (array_key_exists($label, $tags = $this->getTags())) {
-                    $hash = $tags[$label];
-                } elseif (array_key_exists($label, $branches = $this->getBranches())) {
-                    $hash = $branches[$label];
-                }
+            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 (! isset($hash)) {
-                    $composer['support']['source'] = sprintf(
-                        'https://%s/%s/%s/src',
+                    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($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;

+ 1 - 1
src/Composer/Repository/Vcs/GitHubDriver.php

@@ -154,8 +154,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;

+ 1 - 1
src/Composer/Util/StreamContextFactory.php

@@ -164,7 +164,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%s)',
-                Composer::VERSION === '@package_version@' ? Composer::SOURCE_VERSION : Composer::VERSION,
+                Composer::getVersion(),
                 function_exists('php_uname') ? php_uname('s') : 'Unknown',
                 function_exists('php_uname') ? php_uname('r') : 'Unknown',
                 $phpVersion,