3

I have a composer managed Drupal project based on drupal/recommended-project.

I'm installing a contrib module, domain_group, and I'm seeing that composer is auto-including a required dependency, even though it's not listed in the module's composer.json. (I'm checking some other contrib modules and it seems that this is not specific to this module, but a consistent pattern across many modules.)

I run:

composer require drupal/domain_group

and it installs domain_group and domain_site_settings.

Then when I run:

composer why drupal/domain_site_settings

and it tells me that drupal/domain_group requires it.

While the dependency is not listed in domain_group/composer.json, I do see that it is listed in domain_group.info.yml.

Is composer somehow looking to the .info.yml to check for dependencies? Is this some kind of Drupal magic? What causes this? How does it work?

Update:

It seems that it's not checking the .info.yml, at least not locally. From @Clive, in the comments:

[composer why still lists the dependency] even when [the reference to domain_site_settings] is not in domain_group's local composer.json, composer.lock is deleted, the require line in domain_group.info.yml is commented out and composer cache is cleared (just checked). Where is it getting the reference?

I'm now wondering if composer why checks the remote repositories, e.g. https://packages.drupal.org/8, and if there's something special about the d.o repository that compiles extra package dependencies from .info.yml files.

domain_group/composer.json

{
    "name": "drupal/domain_group",
    "type": "drupal-module",
    "description": "This module provides integration between Domain and Group modules",
    "homepage": "http://drupal.org/project/domain_group",
    "authors": [], // etc... 
    "support": {}, // etc...
    "license": "GPL-2.0+",
    "minimum-stability": "dev",
    "require": {
        "drupal/core": "^8.8 || ^9",
        "drupal/group": "~1.0",
        "drupal/domain": "~1.0"
    }
}

domain_group/domain_group.info.yml

name: 'Domain Group'
type: module
description: 'This module provides integration between Domain and Group modules.'
core: 8.x
core_version_requirement: ^8 || ^9
package: 'Domain'
dependencies:
  - group:group
  - domain:domain
  - domain_site_settings:domain_site_settings # Is composer somehow respecting this?
6
  • git.drupalcode.org/project/domain_group/-/blob/2.x/… 🤷
    – leymannx
    Commented Apr 22, 2021 at 14:41
  • That's interesting.. That's not what I see after installing the module OR when I download the 2.0.0 tar.gz from the project page. Though I do see it when I download 2.x-dev version from the project page. (I guess you can see that it was committed there after the release)
    – sonfd
    Commented Apr 22, 2021 at 14:45
  • Is composer somehow looking to the .info.yml to check for dependencies? Yes, always. Is this some kind of Drupal magic? You betcha.
    – No Sssweat
    Commented Apr 22, 2021 at 18:03
  • 3
    The Drupal packager does do some magic with .info.yml files, but that doesn't really explain why a local composer why finds that package, even when it's not in domain_group's local composer.json, composer.lock is deleted, the require line in domain_group.info.yml is commented out and composer cache is cleared (just checked). Where is it getting the reference?
    – Clive
    Commented Apr 22, 2021 at 19:05
  • Thanks for the additional info, Clive. I added it to the question.
    – sonfd
    Commented Apr 23, 2021 at 12:54

2 Answers 2

2

I think this is what's happening:

  1. The Drupal packager gets dependencies from domain_group.info.yml, and adds them to the dependencies for the package record that composer will use.
  2. When composer installs the package, it downloads the current version of the module code (which doesn't have the dependency in composer.json)
  3. Composer doesn't use that composer.json for its record keeping - it stores the dependency from the packager in composer.lock, and also in vendor/composer/installed.json
  4. composer why seems to use composer.lock first for its info, falling back to installed.json if unavailable.

So it doesn't really matter what's in the module's composer.json as far as Composer commands are concerned - it's looking at composer.lock or installed.json, which has domain_site_settings as a requirement from the original install.

2
  • Yeah, this matches what I see. The Drupal packager must be working some magic here to mark to list the initial dependency. Thanks.
    – sonfd
    Commented Apr 23, 2021 at 20:26
  • Is there any documentation out there about the "Drupal packager"? Seems rather hard to find something about it. Commented Apr 25, 2021 at 10:13
0

This happens if you download a Drupal module with Composer from packages.drupal.org, meaning the Drupal repository is defined in your composer.json file:

"repositories": [
    {
        "type": "composer",
        "url": "https://packages.drupal.org/7"
    }
],

In this case, the dependency info for Composer comes from the .info file of the drupal module. This allows Composer to work with Drupal modules without any composer.json file, but hosted on Drupal package repository.

I think the magic happens around packages.drupal.org module running on drupal.org:

It is intended to be run on drupal.org infrastructure to provide a shim that can translate drupal modules, submodules and their drupal specific versioning scheme into something that can be consumed by the composer command line utility.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.