Merge pull request #9902 from Seldaek/cyclic-deps
Detect and output a better hint for cyclic dependenciespull/9925/head
commit
21c70c2606
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -428,6 +429,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;
|
||||||
|
|
||||||
|
|
|
@ -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--
|
Loading…
Reference in New Issue