Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to resolve circular dependency #11879

Open
FasterPHP opened this issue Mar 8, 2024 · 3 comments
Open

Unable to resolve circular dependency #11879

FasterPHP opened this issue Mar 8, 2024 · 3 comments
Labels

Comments

@FasterPHP
Copy link

I'm in the process of updating our composer packages to be compatible with PHP 8.3, but I've run into a problem with a circular dependency that I'm really struggling to resolve.

Here's the (stripped-down) content of the current composer.json:

{
	"name": "namesco/authentication",
	"minimum-stability": "dev",
	"prefer-stable": true,
	"require": {
		"namesco/customer": "dev-feature/php83 as 999999"
	}
}

Output of composer diagnose:

Checking platform settings: OK
Checking git settings: OK git version 2.39.2
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys: 
Tags Public Key Fingerprint: 57815BA2 7E54DC31 7ECC7CC5 573090D0  87719BA6 8F3BB723 4E5D42D0 84A14642
Dev Public Key Fingerprint: 4AC45767 E5EC2265 2F0C1167 CBBB8A2B  0C708369 153E328C AD90147D AFE50952
OK
Checking Composer version: OK
Checking Composer and its dependencies for vulnerabilities: OK
Composer version: 2.7.1
PHP version: 8.3.3
PHP binary path: /usr/local/bin/php
OpenSSL version: OpenSSL 3.0.11 19 Sep 2023
cURL version: 7.88.1 libz 1.2.13 ssl OpenSSL/3.0.11
zip: extension present, unzip present, 7-Zip not available

When I run composer update, I get the following:

  Problem 1
    - Root composer.json requires namesco/customer dev-feature/php83 as 999999 -> satisfiable by namesco/customer[dev-feature/php83].
    - namesco/customer[dev-feature/php83, 999999] require namesco/authentication dev-feature/php83 as 999999 -> satisfiable by namesco/authentication[dev-feature/php83] from composer repo ([obscured]) but namesco/authentication is the root package and cannot be modified. See https://getcomposer.org/dep-on-root for details and assistance.

COMPOSER_ROOT_VERSION is set to 9999999-dev.

I've tried various workarounds, including adding an explicit version to composer.json and using a branch alias, but nothing seems to make a difference. In short, composer doesn't seem to recognise that the root package matches the one being requested.

Unfortunately, it's not possible to remove this circular dependency without a major refactor, so I really need an alternative workaround. Is anyone able to suggest a solution please?

Thanks

@fredden
Copy link
Contributor

fredden commented Mar 8, 2024

Do you have to use development versions? Do you have to alias them to a large number?

It's not clear to me why you can't make an atomic change to each package in turn and create new versions of those. If you're only adding support for a new version of PHP, then it sounds like a minor change according to semantic versioning; or if you're also dropping support for an older version, then it's a major change, but the API should be the same, so the "child" package (which seems to be both sides) would support both "old" and "new" versions, so ^1.0 || ^2.0 would be an appropriate version constraint.

I guess this would be much more complicated if you're also changing the API at the same time, which seems like something that could be optional / deferred to another version.


Edit: to clarify what I mean by making the changes in turn / independently:

  1. Start with v1.0.0 of auth requiring ^1.0 of customer, and v1.0.0 of customer requiring ^1.0 of auth.
  2. Update auth to support new PHP and drop support for old PHP, and release v2.0.0 of auth which requires ^1.0 of customer (still, no change here)
  3. Update customer to support new PHP and drop support for old PHP, and release v2.0.0 of customer which requires ^1.0 || ^2.0 of auth (because they have the same API).
  4. Update auth to require ^1.0 || ^2.0 of customer (because they have the same API), and release this as v2.0.1.

Or, if not dropping support for old PHP, it's a lot simpler:

  1. Start with v1.0.0 of auth requiring ^1.0 of customer, and v1.0.0 of customer requiring ^1.0 of auth.
  2. Update auth to support new PHP, and release v1.1.0 of auth which still requires ^1.0 of customer
  3. Update customer to support new PHP, and release v1.1.0 of customer which still requires ^1.0 of auth

@FasterPHP
Copy link
Author

Hi Fredden

Thanks for the speedy and detailed response.

I am actually doing pretty much what you described, but it's not always straight-forward to do a single package at a time, due to interface changes (primarily inherited from a shared base model package). In theory, I guess it would be possible to make the changes more incrementally, but it's already a very large undertaking and this would add to the complexity.

In answer to your specific questions:

Do you have to use development versions?
It's possible I could temporarily remove this, but we do have a deep dependency on a 3rd-party package that's only available as a development release.

Do you have to alias them to a large number?
No, it just needs to be higher than the current release. Why do you ask?

I'll take a more in-depth look at our dependency tree and try to determine whether it might be possible to tackle the packages in a different order, but I'd still like to understand why this is happening in the first place. Specifically, why does composer think there's a dependency on a version of the current package other than the current root version? ie Is this a limitation of composer's dependency resolver, a bug, or something I'm doing wrong?

Thanks

Marcus

@Seldaek
Copy link
Member

Seldaek commented Mar 11, 2024

I'm not sure why you set COMPOSER_ROOT_VERSION to 9999999-dev, but you should set it to dev-feature/php83 if the nested package depends on the root package in version dev-feature/php83. The alias does not work like you think it does I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants