diff --git a/doc/articles/troubleshooting.md b/doc/articles/troubleshooting.md index 58989f6f2..13ed340ed 100644 --- a/doc/articles/troubleshooting.md +++ b/doc/articles/troubleshooting.md @@ -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 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 - dependency), the problem might be that Composer is not able to detect the version - of the package properly. If it is a git clone it is generally alright and Composer - will detect the version of the current branch, but travis does shallow clones so - that process can fail when testing pull requests and feature branches in general. +1. During development, if you are on a branch like `dev-main` and the branch has no + [branch-alias](aliases.md#branch-alias) defined, and the dependency on the root package + requires version `^2.0` for example, the `dev-main` version will not satisfy it. + The best solution here is to make sure you first define a branch alias. + +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 - called COMPOSER_ROOT_VERSION. You set it to `dev-master` for example to define - the root package's version as `dev-master`. - Use: `before_script: COMPOSER_ROOT_VERSION=dev-master composer install` to export - the variable for the call to composer. + called COMPOSER_ROOT_VERSION. You set it to `dev-main` for example to define + the root package's version as `dev-main`. + Use for example: `COMPOSER_ROOT_VERSION=dev-main composer install` to export + 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 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 - a result, Composer is 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 - the "Additional Behaviours" -> "Check out to specific local branch" in your Git-settings - for your Jenkins-job, where your "local branch" shall be the same branch as you are - checking out. Using this, the checkout will not be in detached state any more and cyclic - dependency is recognized correctly. + +2. The git-clone / checkout within Jenkins leaves the branch in a "detached HEAD"-state. As + a result, Composer may not able to identify the version of the current checked out branch + and may not be able to resolve a [dependency on the root package](#dependencies-on-the-root-package). + To solve this problem, you can use the "Additional Behaviours" -> "Check out to specific local + branch" in your Git-settings for your Jenkins-job, where your "local branch" shall be the same + branch as you are checking out. Using this, the checkout will not be in detached state any more + 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. diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 3f7f8d000..4b91bae8a 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -14,6 +14,7 @@ namespace Composer\DependencyResolver; use Composer\Package\CompletePackageInterface; use Composer\Package\AliasPackage; +use Composer\Package\RootPackageInterface; use Composer\Repository\RepositorySet; use Composer\Repository\LockArrayRepository; 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) { $singular = count($higherRepoPackages) === 1; diff --git a/tests/Composer/Test/Fixtures/installer/circular-dependency-errors.test b/tests/Composer/Test/Fixtures/installer/circular-dependency-errors.test new file mode 100644 index 000000000..1cf2458a1 --- /dev/null +++ b/tests/Composer/Test/Fixtures/installer/circular-dependency-errors.test @@ -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--