1
0
Fork 0

Detect and output a better hint for dependencies on the root package, fixes #9837

pull/9902/head
Jordi Boggiano 2021-05-21 11:14:11 +02:00
parent 8a3f4a8400
commit cbef7b9172
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC
3 changed files with 83 additions and 19 deletions

View File

@ -47,32 +47,39 @@ This is a list of common pitfalls on using Composer, and how to avoid them.
In this case add the `--with-dependencies` argument **or** add all dependencies which In this case add the `--with-dependencies` argument **or** add all dependencies which
need an update to the command. need an update to the command.
## Package not found on travis-ci.org ## Dependencies on the root package
1. Check the ["Package not found"](#package-not-found) item above. When your root package depends on a package which ends up depending (directly or
indirectly) back on the root package itself, issues can occur in two cases:
2. If the package tested is a dependency of one of its dependencies (cyclic 1. During development, if you are on a branch like `dev-main` and the branch has no
dependency), the problem might be that Composer is not able to detect the version [branch-alias](aliases.md#branch-alias) defined, and the dependency on the root package
of the package properly. If it is a git clone it is generally alright and Composer requires version `^2.0` for example, the `dev-main` version will not satisfy it.
will detect the version of the current branch, but travis does shallow clones so The best solution here is to make sure you first define a branch alias.
that process can fail when testing pull requests and feature branches in general.
2. In CI (Continuous Integration) runs, the problem might be that Composer is not able
to detect the version of the root package properly. If it is a git clone it is
generally alright and Composer will detect the version of the current branch,
but some CIs do shallow clones so that process can fail when testing pull requests
and feature branches. In these cases the branch alias may then not be recognized.
The best solution is to define the version you are on via an environment variable The best solution is to define the version you are on via an environment variable
called COMPOSER_ROOT_VERSION. You set it to `dev-master` for example to define called COMPOSER_ROOT_VERSION. You set it to `dev-main` for example to define
the root package's version as `dev-master`. the root package's version as `dev-main`.
Use: `before_script: COMPOSER_ROOT_VERSION=dev-master composer install` to export Use for example: `COMPOSER_ROOT_VERSION=dev-main composer install` to export
the variable for the call to composer. the variable only for the call to composer, or you can define it globally in the
CI env vars.
## Package not found in a Jenkins-build ## Package not found in a Jenkins-build
1. Check the ["Package not found"](#package-not-found) item above. 1. Check the ["Package not found"](#package-not-found) item above.
2. Reason for failing is similar to the problem which can occur on travis-ci.org: The
git-clone / checkout within Jenkins leaves the branch in a "detached HEAD"-state. As 2. The git-clone / checkout within Jenkins leaves the branch in a "detached HEAD"-state. As
a result, Composer is not able to identify the version of the current checked out branch a result, Composer may not able to identify the version of the current checked out branch
and may not be able to resolve a cyclic dependency. To solve this problem, you can use and may not be able to resolve a [dependency on the root package](#dependencies-on-the-root-package).
the "Additional Behaviours" -> "Check out to specific local branch" in your Git-settings To solve this problem, you can use the "Additional Behaviours" -> "Check out to specific local
for your Jenkins-job, where your "local branch" shall be the same branch as you are branch" in your Git-settings for your Jenkins-job, where your "local branch" shall be the same
checking out. Using this, the checkout will not be in detached state any more and cyclic branch as you are checking out. Using this, the checkout will not be in detached state any more
dependency is recognized correctly. and the dependency on the root package should become satisfied.
## I have a dependency which contains a "repositories" definition in its composer.json, but it seems to be ignored. ## I have a dependency which contains a "repositories" definition in its composer.json, but it seems to be ignored.

View File

@ -14,6 +14,7 @@ namespace Composer\DependencyResolver;
use Composer\Package\CompletePackageInterface; use Composer\Package\CompletePackageInterface;
use Composer\Package\AliasPackage; use Composer\Package\AliasPackage;
use Composer\Package\RootPackageInterface;
use Composer\Repository\RepositorySet; use Composer\Repository\RepositorySet;
use Composer\Repository\LockArrayRepository; use Composer\Repository\LockArrayRepository;
use Composer\Semver\Constraint\Constraint; use Composer\Semver\Constraint\Constraint;
@ -420,6 +421,17 @@ class Problem
} }
} }
if ($higherRepoPackages) {
$topPackage = reset($higherRepoPackages);
if ($topPackage instanceof RootPackageInterface) {
$singular = count($nextRepoPackages) === 1;
return array(
"- Root composer.json requires $packageName".self::constraintToText($constraint).', it is ',
'satisfiable by '.self::getPackageList($nextRepoPackages, $isVerbose).' from '.$nextRepo->getRepoName().' but '.$topPackage->getPrettyName().' is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.'
);
}
}
if ($nextRepo instanceof LockArrayRepository) { if ($nextRepo instanceof LockArrayRepository) {
$singular = count($higherRepoPackages) === 1; $singular = count($higherRepoPackages) === 1;

View File

@ -0,0 +1,45 @@
--TEST--
Circular dependencies errors uses helpful message
--COMPOSER--
{
"name": "root/pkg",
"version": "dev-master",
"require": {
"requires/root": "1.0.0"
},
"repositories": [
{
"type": "package",
"package": [
{
"name": "requires/root",
"version": "1.0.0",
"source": { "reference": "some.branch", "type": "git", "url": "" },
"require": {
"root/pkg": "^1.0"
}
},
{
"name": "root/pkg",
"version": "1.0.0"
}
]
}
]
}
--RUN--
update -v
--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 requires/root 1.0.0 -> satisfiable by requires/root[1.0.0].
- requires/root 1.0.0 requires root/pkg ^1.0 -> satisfiable by root/pkg[1.0.0] from package repo (defining 2 packages) but root/pkg is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.
--EXPECT--