Skip to content

[Composer] Target lowest version for any distributed package type, only 'project' is an application - #8363

Merged
TomasVotruba merged 1 commit into
mainfrom
extend-composer-library-types
Aug 22, 2026
Merged

[Composer] Target lowest version for any distributed package type, only 'project' is an application#8363
TomasVotruba merged 1 commit into
mainfrom
extend-composer-library-types

Conversation

@TomasVotruba

@TomasVotruba TomasVotruba commented Aug 22, 2026

Copy link
Copy Markdown
Member

What

Two related changes to how composer-package versions drive version-bound rules.

1. Lowest declared version for distributed packages

InstalledPackageResolver treated only "type": "library" as a distributed package. Now any non-project type (library, symfony-bundle, rector-extension, ...) targets the lowest declared version, while a missing type or an explicit "project" stays an application on the installed version.

-        return ($projectComposerJson['type'] ?? null) === 'library';
+        $type = $projectComposerJson['type'] ?? null;
+
+        return is_string($type) && $type !== 'project';

2. Honor a test-provided composer.json for composer-bound rules

RectorConfig::ruleWithConfigurationComposerVersionBound() resolved the version through a private new InstalledPackageResolver() reading the project root, ignoring the resolver a test configures via AbstractRectorTestCase::provideComposerJsonFilePath(). It now resolves through the container-bound singleton, so a test-specific composer.json drives the version:

-        $this->installedPackageResolver ??= new InstalledPackageResolver();
-        return $this->installedPackageResolver->resolvePackageVersion($packageName);
+        if (! $this->bound(InstalledPackageResolver::class)) {
+            $this->singleton(InstalledPackageResolver::class);
+        }
+        return $this->make(InstalledPackageResolver::class)->resolvePackageVersion($packageName);

Without this, an extension package (e.g. rector-doctrine, "type": "rector-extension") resolved its version-bound rules from its own root composer.json — so change #1 dropped it to the lowest declared floor and deactivated newer-version rules in the extension's own test suite. With this, rector-doctrine's tests/ComposerBased/composer.json (rectorphp/rector-doctrine#513) drives the version deterministically; its root composer.json and fixtures stay untouched.

Tests

  • InstalledPackageResolverTest: library test is a data provider over library + symfony-bundle; new project_composer_json fixture proves an explicit "project" keeps the installed version.
  • Verified against rector-doctrine main: ComposerBasedTest 3/3 green, fixtures unchanged.

@TomasVotruba
TomasVotruba marked this pull request as ready for review August 22, 2026 17:53
@TomasVotruba
TomasVotruba force-pushed the extend-composer-library-types branch from 0e47b0d to 2aa8814 Compare August 22, 2026 17:55
@TomasVotruba TomasVotruba changed the title [Composer] Target lowest version for all library-distributed package types, not only 'library' [Composer] Target lowest version for any distributed package type, only 'project' is an application Aug 22, 2026
$type = $projectComposerJson['type'] ?? null;

return ($projectComposerJson['type'] ?? null) === 'library';
return is_string($type) && $type !== 'project';

@samsonasik samsonasik Aug 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think additional requirement check is needed, when the package has php version range, eg: has

"php": "^8.1 || ^8.2"

Then should follow lowest.

That will usually verify that multiple major version of requirment test eg: phpunit 10 or 11 n CI is needed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already handled by PHP version and the min php version interface. Different area.

…iven by a test-provided composer.json

Treat any non-'project' composer type as a distributed package, resolving version-bound rules to the lowest declared version. Resolve those versions via the container-bound InstalledPackageResolver, so a test-provided composer.json (AbstractRectorTestCase::provideComposerJsonFilePath) drives the version instead of the project root.
@TomasVotruba
TomasVotruba force-pushed the extend-composer-library-types branch from 511f269 to 19c473a Compare August 22, 2026 19:43
@TomasVotruba
TomasVotruba enabled auto-merge (squash) August 22, 2026 19:43
@TomasVotruba
TomasVotruba merged commit bc7a659 into main Aug 22, 2026
51 checks passed
@TomasVotruba
TomasVotruba deleted the extend-composer-library-types branch August 22, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants