1
0
Fork 0

Merge branch '2.0'

pull/9734/head
Jordi Boggiano 2021-03-09 15:29:19 +01:00
commit 8392508e23
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
13 changed files with 290 additions and 22 deletions

View File

@ -22,7 +22,7 @@ jobs:
coverage: "none"
extensions: "intl"
ini-values: "memory_limit=-1"
php-version: "7.4"
php-version: "8.0"
- name: "Install dependencies from composer.lock using composer binary provided by system"
run: "composer install ${{ env.COMPOSER_FLAGS }}"

View File

@ -268,7 +268,7 @@ class Problem
});
if (!$nonLockedPackages) {
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose).' in lock file but not in remote repositories, make sure you avoid updating this package to keep the one from lock file.');
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose).' in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.');
}
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', ', 'found '.self::getPackageList($packages, $isVerbose).' but these were not loaded, likely because '.(self::hasMultipleNames($packages) ? 'they conflict' : 'it conflicts').' with another require.');
@ -404,6 +404,13 @@ class Problem
}
}
if ($nextRepo instanceof LockArrayRepository) {
$singular = count($higherRepoPackages) === 1;
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ',
'found '.self::getPackageList($nextRepoPackages, $isVerbose).' in the lock file and '.self::getPackageList($higherRepoPackages, $isVerbose).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' but ' . ($singular ? 'it does' : 'these do') . ' not match your '.$reason.' and ' . ($singular ? 'is' : 'are') . ' therefore not installable. Make sure you either fix the '.$reason.' or avoid updating this package to keep the one from the lock file.');
}
return array("- Root composer.json requires $packageName".self::constraintToText($constraint) . ', it is ', 'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose).' from '.$nextRepo->getRepoName().' but '.self::getPackageList($higherRepoPackages, $isVerbose).' from '.reset($higherRepoPackages)->getRepository()->getRepoName().' has higher repository priority. The packages with higher priority do not match your '.$reason.' and are therefore not installable. See https://getcomposer.org/repoprio for details and assistance.');
}

View File

@ -107,6 +107,34 @@ abstract class ArchiveDownloader extends FileDownloader
return iterator_to_array($finder);
};
$renameRecursively = null;
/**
* Renames (and recursively merges if needed) a folder into another one
*
* For custom installers, where packages may share paths, and given Composer 2's parallelism, we need to make sure
* that the source directory gets merged into the target one if the target exists. Otherwise rename() by default would
* put the source into the target e.g. src/ => target/src/ (assuming target exists) instead of src/ => target/
*
* @param string $from Directory
* @param string $to Directory
* @return void
*/
$renameRecursively = function ($from, $to) use ($filesystem, $getFolderContent, $package, &$renameRecursively) {
$contentDir = $getFolderContent($from);
// move files back out of the temp dir
foreach ($contentDir as $file) {
$file = (string) $file;
if (is_dir($to . '/' . basename($file))) {
if (!is_dir($file)) {
throw new \RuntimeException('Installing '.$package.' would lead to overwriting the '.$to.'/'.basename($file).' directory with a file from the package, invalid operation.');
}
$renameRecursively($file, $to . '/' . basename($file));
} else {
$filesystem->rename($file, $to . '/' . basename($file));
}
}
};
$renameAsOne = false;
if (!file_exists($path) || ($filesystem->isDirEmpty($path) && $filesystem->removeDirectory($path))) {
@ -126,15 +154,12 @@ abstract class ArchiveDownloader extends FileDownloader
$filesystem->rename($extractedDir, $path);
} else {
// only one dir in the archive, extract its contents out of it
$from = $temporaryDir;
if ($singleDirAtTopLevel) {
$contentDir = $getFolderContent((string) reset($contentDir));
$from = (string) reset($contentDir);
}
// move files back out of the temp dir
foreach ($contentDir as $file) {
$file = (string) $file;
$filesystem->rename($file, $path . '/' . basename($file));
}
$renameRecursively($from, $path);
}
$promise = $filesystem->removeDirectoryAsync($temporaryDir);

View File

@ -27,6 +27,7 @@ use Composer\Plugin\PostFileDownloadEvent;
use Composer\Plugin\PreFileDownloadEvent;
use Composer\EventDispatcher\EventDispatcher;
use Composer\Util\Filesystem;
use Composer\Util\Silencer;
use Composer\Util\HttpDownloader;
use Composer\Util\Url as UrlUtil;
use Composer\Util\ProcessExecutor;
@ -313,6 +314,16 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
$this->filesystem->emptyDirectory($path);
$this->filesystem->ensureDirectoryExists($path);
$this->filesystem->rename($this->getFileName($package, $path), $path . '/' . pathinfo(parse_url($package->getDistUrl(), PHP_URL_PATH), PATHINFO_BASENAME));
if ($package->getBinaries()) {
// Single files can not have a mode set like files in archives
// so we make sure if the file is a binary that it is executable
foreach ($package->getBinaries() as $bin) {
if (file_exists($path . '/' . $bin) && !is_executable($path . '/' . $bin)) {
Silencer::call('chmod', $path . '/' . $bin, 0777 & ~umask());
}
}
}
}
/**

View File

@ -192,15 +192,19 @@ class BinaryInstaller
$binFile = basename($binPath);
$binContents = file_get_contents($bin);
// For php files, we generate a PHP proxy instead of a shell one,
// which allows calling the proxy with a custom php process
if (preg_match('{^(?:#!(?:/usr)?/bin/env php|#!(?:/usr)?/bin/php|<?php)\r?\n}', $binContents, $match)) {
$proxyCode = trim($match[0]);
// carry over the existing shebang if present, otherwise add our own
if ($proxyCode === "<?php") {
$proxyCode = "#!/usr/bin/env php";
}
$binPathExported = var_export($binPath, true);
// verify the file is not a phar file, because those do not support php-proxying
if (false === ($pos = strpos($binContents, '__HALT_COMPILER')) || false === strpos(substr($binContents, 0, $pos), 'Phar::mapPhar')) {
$proxyCode = trim($match[0]);
// carry over the existing shebang if present, otherwise add our own
if ($proxyCode === "<?php") {
$proxyCode = "#!/usr/bin/env php";
}
$binPathExported = var_export($binPath, true);
return $proxyCode . "\n" . <<<PROXY
return $proxyCode . "\n" . <<<PROXY
<?php
/**
@ -226,6 +230,7 @@ if (\$replaced) {
include \$binPath;
PROXY;
}
}
$proxyCode = <<<PROXY

View File

@ -76,8 +76,12 @@ class VersionParser extends SemverVersionParser
return true;
}
$normalizedFrom = str_replace(array('dev-master', 'dev-trunk', 'dev-default'), VersionParser::DEFAULT_BRANCH_ALIAS, $normalizedFrom);
$normalizedTo = str_replace(array('dev-master', 'dev-trunk', 'dev-default'), VersionParser::DEFAULT_BRANCH_ALIAS, $normalizedTo);
if (in_array($normalizedFrom, array('dev-master', 'dev-trunk', 'dev-default'), true)) {
$normalizedFrom = VersionParser::DEFAULT_BRANCH_ALIAS;
}
if (in_array($normalizedTo, array('dev-master', 'dev-trunk', 'dev-default'), true)) {
$normalizedTo = VersionParser::DEFAULT_BRANCH_ALIAS;
}
if (strpos($normalizedFrom, 'dev-') === 0 || strpos($normalizedTo, 'dev-') === 0) {
return true;

View File

@ -1053,9 +1053,9 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
}
}
$packages = $this->loader->loadPackages($packages, 'Composer\Package\CompletePackage');
$packageInstances = $this->loader->loadPackages($packages, 'Composer\Package\CompletePackage');
foreach ($packages as $package) {
foreach ($packageInstances as $package) {
if (isset($this->sourceMirrors[$package->getSourceType()])) {
$package->setSourceMirrors($this->sourceMirrors[$package->getSourceType()]);
}
@ -1063,7 +1063,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
$this->configurePackageTransportOptions($package);
}
return $packages;
return $packageInstances;
} catch (\Exception $e) {
throw new \RuntimeException('Could not load packages '.(isset($packages[0]['name']) ? $packages[0]['name'] : json_encode($packages)).' in '.$this->getRepoName().($source ? ' from '.$source : '').': ['.get_class($e).'] '.$e->getMessage(), 0, $e);
}

View File

@ -43,7 +43,7 @@ Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- locked/pkg dev-master requires locked/dependency 1.0.0 -> found locked/dependency[1.0.0] in lock file but not in remote repositories, make sure you avoid updating this package to keep the one from lock file.
- locked/pkg dev-master requires locked/dependency 1.0.0 -> found locked/dependency[1.0.0] in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.
- locked/pkg is locked to version dev-master and an update of this package was not requested.
Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.

View File

@ -43,7 +43,7 @@ Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- locked/pkg dev-master requires locked/dependency 1.0.0 -> found locked/dependency[1.0.0] in lock file but not in remote repositories, make sure you avoid updating this package to keep the one from lock file.
- locked/pkg dev-master requires locked/dependency 1.0.0 -> found locked/dependency[1.0.0] in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.
- locked/pkg is locked to version dev-master and an update of this package was not requested.
--EXPECT--

View File

@ -0,0 +1,52 @@
--TEST--
Update package which is in lock file but not in remote repo at all should show this error correctly
--COMPOSER--
{
"minimum-stability": "dev",
"repositories": [
{"type": "package", "package": [
{"name": "main/dep", "version": "1.0.0", "require": {"locked/dep": "^2.1"}}
]}
],
"require": {
"main/dep": "*"
}
}
--LOCK--
{
"packages": [
{
"name": "main/dep", "version": "1.0.0",
"require": {"locked/dep": "^2.1"},
"type": "library"
},
{
"name": "locked/dep", "version": "2.1.0",
"type": "library"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
--RUN--
update main/dep --with-all-dependencies
--EXPECT-EXIT-CODE--
2
--EXPECT-OUTPUT--
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Root composer.json requires main/dep * -> satisfiable by main/dep[1.0.0].
- main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.1.0] in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file.
--EXPECT--

View File

@ -0,0 +1,54 @@
--TEST--
Update package which is in lock file but not remote repo due to min-stability should show this error correctly
--COMPOSER--
{
"minimum-stability": "stable",
"repositories": [
{"type": "package", "package": [
{"name": "main/dep", "version": "1.0.0", "require": {"locked/dep": "^2.1"}},
{"name": "locked/dep", "version": "2.x-dev"},
{"name": "locked/dep", "version": "2.0.5"}
]}
],
"require": {
"main/dep": "*"
}
}
--LOCK--
{
"packages": [
{
"name": "main/dep", "version": "1.0.0",
"require": {"locked/dep": "^2.1"},
"type": "library"
},
{
"name": "locked/dep", "version": "2.1.0",
"type": "library"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
--RUN--
update main/dep --with-all-dependencies
--EXPECT-EXIT-CODE--
2
--EXPECT-OUTPUT--
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Root composer.json requires main/dep * -> satisfiable by main/dep[1.0.0].
- main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.1.0] in the lock file and locked/dep[2.x-dev] from package repo (defining 3 packages) but it does not match your minimum-stability and is therefore not installable. Make sure you either fix the minimum-stability or avoid updating this package to keep the one from the lock file.
--EXPECT--

View File

@ -0,0 +1,53 @@
--TEST--
Update package which is in lock file but not in remote repo in the correct version should show this error correctly
--COMPOSER--
{
"minimum-stability": "dev",
"repositories": [
{"type": "package", "package": [
{"name": "main/dep", "version": "1.0.0", "require": {"locked/dep": "^2.1"}},
{"name": "locked/dep", "version": "2.0.5"}
]}
],
"require": {
"main/dep": "*"
}
}
--LOCK--
{
"packages": [
{
"name": "main/dep", "version": "1.0.0",
"require": {"locked/dep": "^2.1"},
"type": "library"
},
{
"name": "locked/dep", "version": "2.1.0",
"type": "library"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
--RUN--
update main/dep --with-all-dependencies
--EXPECT-EXIT-CODE--
2
--EXPECT-OUTPUT--
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Root composer.json requires main/dep * -> satisfiable by main/dep[1.0.0].
- main/dep 1.0.0 requires locked/dep ^2.1 -> found locked/dep[2.1.0] in the lock file and locked/dep[2.0.5] from package repo (defining 2 packages) but it does not match your constraint and is therefore not installable. Make sure you either fix the constraint or avoid updating this package to keep the one from the lock file.
--EXPECT--

View File

@ -0,0 +1,57 @@
--TEST--
Update package which is in lower prio repo but not main repo due to min-stability should show this error correctly
--COMPOSER--
{
"minimum-stability": "stable",
"repositories": [
{"type": "package", "package": [
{"name": "main/dep", "version": "1.0.0", "require": {"lower/dep": "^2.1"}},
{"name": "lower/dep", "version": "2.x-dev"},
{"name": "lower/dep", "version": "2.0.5"}
]},
{"type": "package", "package": [
{"name": "lower/dep", "version": "2.1.0"}
]}
],
"require": {
"main/dep": "*"
}
}
--LOCK--
{
"packages": [
{
"name": "main/dep", "version": "1.0.0",
"require": {"lower/dep": "^2.1"},
"type": "library"
},
{
"name": "lower/dep", "version": "2.1.0",
"type": "library"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
--RUN--
update main/dep --with-all-dependencies
--EXPECT-EXIT-CODE--
2
--EXPECT-OUTPUT--
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Root composer.json requires main/dep * -> satisfiable by main/dep[1.0.0].
- main/dep 1.0.0 requires lower/dep ^2.1 -> satisfiable by lower/dep[2.1.0] from package repo (defining 1 package) but lower/dep[2.x-dev] from package repo (defining 3 packages) has higher repository priority. The packages with higher priority do not match your minimum-stability and are therefore not installable. See https://getcomposer.org/repoprio for details and assistance.
--EXPECT--