Page MenuHomePhabricator

CirrusSearch should include dependencies in composer.json
Closed, InvalidPublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

  • Install a fresh version of Mediawiki with Elastica and CirrusSearch extensions
  • Run composer install --no-dev from the project root
  • Run maintenance jobs such as w/maintenance/run update --wiki $wid --quick --doshared

What happens?:
You will get an error Class Elastica/Client not found.

What should have happened instead?:
composer install --no-dev should have taken care of installing all dependencies for all extensions.

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):
MW 1.43

Other information (browser name/version, screenshots, etc.):
I believe this is caused by the fact that the CirrusSearch extension does not declare the dependency on ruflin/elastica in its composer.json, which is where the class Elastica/Client is coming from.

The Elastica extension does declare this dependency in its composer.json. I believe each extension should clearly declare / require its dependencies in composer.json, so there should be an entry for "ruflin/elastica": "7.3.1" in the CirrusSearch composer.json .

Other users have encountered the same problem in previous versions of MW, see https://www.mediawiki.org/wiki/Topic:V5ronoam552ge9f0 where the MW version was 1.33.

I am about to do another fresh install of MW 1.44 so I will test that this is what is causing this problem.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

CirrusSearch depends on Elastica, Elastica depends on ruflin/elastica. I'd rather not repeat the same version numbers all over the place if possible, it only makes updating things more tedious.

If the install doesn't install ruflin/elastica to the vendors dir that is a problem, but it's probably worthwhile to understand how exactly that comes about. I would naively expect the transitive dependency to fulfill the requirements. If you run the test install, what exception is printed? Is there a full stack trace? I took a quick look over CirrusSearch and I didn't see anywhere where we either construct or access a static method on Elastica\Client. Outside of test cases it's always a client object provided by the Elastica extension.

But I understand what you're saying that it should be pulled in be Elastica, which is a dependency. I'll try to dig around and see better what is happening.

The dependency on the Elastica extension is declared in extension.json, not in composer.json. So this could still be a problem. I might add that I'm pulling in extensions via git, and then running composer install from the MediaWiki root after all extensions are installed.

A little bit of insight from ChatGPT (always to be taken with a grain of salt, but can have some useful information):

CirrusSearch should explicitly declare ruflin/elastica in its own composer.json if it directly uses Elastica\Client (or anything else from that package).

Here’s why:

Composer dependency resolution is per project root, not per extension.
When you run composer install from the MediaWiki root, Composer only looks at the root composer.json and the composer.json files of extensions that are declared as dependencies there. If CirrusSearch does not list ruflin/elastica, Composer has no reason to pull it in on CirrusSearch’s behalf.

Relying on transitive dependencies (via another extension, in this case Elastica) is fragile:

If the Elastica extension changes or drops its explicit dependency on ruflin/elastica, CirrusSearch would break.

It creates confusion about where a class really comes from.

The fact that you can "fix" the missing class only by running composer install inside the Elastica extension folder means CirrusSearch is not ensuring its own requirements are met.

The best practice in Composer (and PHP in general) is:
👉 If your code uses a class from a package, you must declare that package as a dependency in your composer.json.

So CirrusSearch’s composer.json should contain something like:

"require": {

"ruflin/elastica": "^7.0"

}

(Version constraint should match what it’s actually compatible with.)

The CirrusSearch extension can still list the Elastica extension as a MediaWiki extension dependency (in extension.json), but that’s separate from Composer’s PHP-level dependency resolution.


✅ Conclusion: CirrusSearch should declare ruflin/elastica in its composer.json. Relying on another extension’s dependency is not safe.

@Lwangaman the way this problem is generally solved in mediawiki is by using the composer merge plugin at https://www.mediawiki.org/wiki/Composer#Using_composer-merge-plugin

Gehel moved this task from Incoming to Done on the Discovery-Search (2025.09.05 - 2025.09.26) board.
Gehel subscribed.

Closing as this seems to be working as expected when following manual.