Problem/Motivation

The dependency system in drupal is lacking certain features that we need going forward to support several desired use cases.

Current dependency management is handled in two ways:

  • There is a 'core' key in the info.yml files that expresses whether or not an extension should be able to be used on an existing drupal core installation.
  • There are 'dependency' keys in info.yml files that expresses whether or not an extension has all of its required dependencies in order to be installed.

We would like to be able to support the following use cases:

  1. A drupal 8 extension, that is not using any deprecated code, should be able to be used with both drupal 8 and 9. (or 10/11 etc)
  2. An extension should be able to express specifically which version of core it requires. i.e. A module taking advantage of an API introduced in Drupal 8.7.0, and bugfixed in 8.7.2, should be able to say it requires *at least* drupal 8.7.2.
  3. An extension maintainer should be able to use semantic versioning for their modules, and should be able to express dependencies on other modules using semver constraint syntax.
  4. Drupal should prevent users from installing modules that do not have all of their dependencies available, including 3rd party Composer libraries.

Proposed resolution

There are several issues in the queue attempting to tackle these problems somewhat independently, but they are all interlinked, and an overall strategy has emerged.

Option 1. ❌

Deprecate dependency management inside of .info.yml files, and move dependency related functionality to composer.json. The core key, dependencies, and test-dependencies would all move to composer.json. All other keys would stay in the .info.yml files. Deprecate in 8.8.x and remove before 9.0.0.
Much work and discussion has happened here:

Option 2. ❌

Enhance what our .info.yml files are capable of so that they can support multiple core versions, as well as allow the dependency specifications to use semver so that contrib maintainers can start using semver.
Many issues. Much work:

Option 3. ✅ (per @catch in #6, @tedbow in #8, @larowlan in #9, @Mixologic in #11 and strategy call with @catch/@xjm/@larowlan/@Gábor Hojtsy/@tedbow/@Mixologic in #14)

Enhance .info.yml files to allow for multiple versions of core, and add *optional* support for composer.json
Allowing for multiple versions of core:

And take most of the work from the following issue, and adapt it to work in parallel with the existing system.

In various discussions with release managers and other core contributors, the was a general sense that the deprecating dependency management in .info.yml files in favor of composer.json seemed unlikely to happen before Drupal 9, and is a fundamentally structural change that affects all existing Drupal 8 modules. Option 1 seemed unlikely and/or risky.

The second option has several limitations, and essentially duplicates a lot of the functionality that we get with composer by default, and still cannot solve some other longstanding issues like "should a user be able to enable a module if its 3rd party dependencies are not there"

The third option emerged as a potential best possible scenario, given the timing and goals.
We would enhance our core key in .info.yml files to allow maintainers to have their modules work with both drupal 8 and 9, with very little effort on their part. At the same time, we would add in *optional* support for using a composer.json as the source of dependency metadata.

This would allow users to continue to do what they were doing before, however, if they needed any of the more advanced features of dependency management (semver requirements, third party libs, conflicts, ~/^ operators etc) then they would be able to use the more feature-rich option of having a composer.json.

Remaining tasks

Confirm with release mangers and other stakeholders preferences for this path.

Comments

Mixologic created an issue. See original summary.

Mixologic’s picture

Issue summary: View changes
Mixologic’s picture

Issue summary: View changes
gábor hojtsy’s picture

Issue tags: +Drupal 9
Mixologic’s picture

Issue summary: View changes
catch’s picture

So I think option #3 is a good plan. Ideally we'd land #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning asap so that as soon as the 9.x branch opens, contrib modules can start testing against it. We can then continue to work on the other issues but it might just mean deprecation for Drupal 10 instead of for Drupal 9.

Mixologic’s picture

Issue summary: View changes
tedbow’s picture

+1 for option 3.
re

And take most of the work from the following issue, and adapt it to work in parallel with the existing system.

I think #3005229: Provide optional support for using composer.json for dependency metadata actually does allow it to work in parallel already it would just be matter of deprecating in 9 instead of 8.

It seems like we would have to introduce the support for using composer.json to replace the core and dependencies keys in info.yml in the 8.x branch though even if we weren't going to stop support those until 10.x.

Otherwise it really takes away the benefit of #2807145: [policy, no patch] Allow contrib projects to specify multiple major core branches(now covered by #3005229) because you would still need different versions of your module for 8 & 9 if you wanted to use only composer.json for dependencies in 9(unless you just duplicated in both info.yml and composer.json but then what is the point?)

It would probably be simpler though if we could wait till 9.x to do #3005229(also because there so much else to do) but then we would probably have to advice people to keep using core and dependencies in .info.yml if they want there module to compatible with both 8 & 9.

Additionally if we don't do #3005229 in 8.x then modules won't be able to set module dependency constraints once #3054391: [META] Support semantic versioning on drupal.org for contributed projects once is implemented unless we just did #2641658: Module version dependency in .info.yml is ineffective for patch releases(the last patch there simplifies this)

larowlan’s picture

+1 for option 3 too

tedbow’s picture

I think one thing we should consider doing before 9.0 is deprecating own Drupal specific constraint string format.

So not remove version constraints in .info.yml dependencies but rather just deprecate support for handling of formats that won't to valid composer formats. and keep our current
- 'drupal:[module] ([constraint])'
pattern.

So
- "drupal:weform (>=2.0)
or
- "drupal:weform (2.x)
Would still be valid.

What would not be valid is
- "drupal:weform (>=2.x)
Composer semver doesn't allow and operator with a range.
For composer semver 2.x gets parsed as [>= 2.0.0.0-dev < 3.0.0.0-dev]
which is the same thing it means to our constraints.

Of course this would also mean anything that started with 8.x- would also not be valid unless we put logic in just to strip that as there is now.

The latest patch in #2641658-50: Module version dependency in .info.yml is ineffective for patch releases solves that problem by using \Composer\Semver\Semver::satisfies() directly when possible(no exception) and only falling back to our current logic when it can't. So basically in Drupal 9 we would just use \Composer\Semver\Semver::satisfies() directly always.

I think this would 3 benefits

  1. #3054391: [META] Support semantic versioning on drupal.org for contributed projects would not have to wait till #3005229: Provide optional support for using composer.json for dependency metadata so it would make the timing not as critical as far as timing with drupal.org changes
  2. If we did #3005229: Provide optional support for using composer.json for dependency metadata after 9.0 then the update script in that is currently in that patch that moves dependencies from the info.yml file to the composer.json could be much simpler because we would know that if it is a valid Drupal 9 module the constraints would be valid for \Composer\Semver\VersionParser which \Composer\Semver\Semver::satisfies() uses. And we won't have edge case in our current format when converting to composer.json.
  3. So far everyone is in favor of option 3 which depends on #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning which allow any valid composer constraints in the core key for info.yml files. If we also use composer constraints in dependencies in would be much simpler to document(which really don't describe in detail now.). Otherwise we have to explain use composer constraint format for core and this drupal specific one which overlaps almost completely but not quite for dependencies.
Mixologic’s picture

#2641658: Module version dependency in .info.yml is ineffective for patch releases is very much option 2, and is essentially blocked on drupal.org. The dependency keys are more than just "can we enable this extension".

  • The dependency declarations in .info.yml converted by the composer facade into composer compatible contraint syntax.
  • The constraints are then 'merged' with any existing composer.json files.

This is a weird case of "the strings and their formats in the dependencies key are a defacto API that packages.drupal.org depends on, please don't change whats possible there".

If we start adding new things to .info.yml, we'll need to adjust the project_composer/drupal.org to expect any/all of these new possibilities and handle them all properly, without a clear indicator as to which .info.yml's are in the deprecated format and which ones should be just passed through. It may be easy or hard to handle those changes. But any change at all on that side carries a different risk calculus.

If, we do like option 3 suggests and do nothing to the .info.yml files, and move all new functionality to composer.json, then we get that version string deprecation as a side effect, because the composer compliant versions are all thats allowed in your composer.json files.

So we don't really gain anything in complexity reduction by adding to the number of possible constraints/versions we allow developers to put in their .info.yml - if anything It becomes more complex, and the complexity gets pushed to drupal.org, and the users don't end up with something as powerful as composer.json files. Additionally we lose on the opportunity to encourage maintainers to convert composer.json files, which is also a goal here. I don't want to both tell maintainers that "you can use semver in .info.yml depencencies" and then turn around and say "now that's deprecated, you should use composer.json from now on for dependencies."

The update script in https://www.drupal.org/project/drupal/issues/3005229 isn't altogether essential, and is really just a nice to have to help maintainers transfer data from one metadata format to another. Im almost go so far as to say we shouldn't even include it so that if/when maintainers add a composer.json, they have an opportunity to learn what its for, and what features they now have so they can add one going forward.

The timing of drupal.org related changes required for semver arent really blocked on either solution, it's really just been a preference to delay until core handled semver before we offered it. But we already offer semver, just only for core itself at this point. So, we're not really blocked on waiting if we know that something is going to enhance core to support this feature.

tedbow’s picture

@Mixologic thanks for the extra info.

I added a comment to #2641658-51: Module version dependency in .info.yml is ineffective for patch releases and mentioning the options now that we know should be super careful not to introduce any new capabilities such as ~/^ support accidentally.

Also related to here

Related, I wanted to see how many contrib dependencies constraints actually would throw an error if used with `\Composer\Semver\VersionParser::parseConstraints()`. So I made https://github.com/tedbow/drupal_contrib_dependencies. tldr, 99% don't throw an error.

Mixologic’s picture

This is a weird case of "the strings and their formats in the dependencies key are a defacto API that packages.drupal.org depends on, please don't change whats possible there"

Looking at what we've already got in project_composer, I believe that I had anticipated a change like this already, and as such, it is probably already compatible based off the test cases that currently pass: https://git.drupalcode.org/project/project_composer/blob/7.x-1.x/project..., so the blocked on drupal.org part isn't actually true.

Mixologic’s picture

Strategy per call with @catch/@xjm/@larowlan/@Gábor Hojtsy/@tedbow/@Mixologic

1. Changes to #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning

  • remove the .info.yml changes from this patch and put into a followup.
  • backport to 8.7, probably even 8.6.
  • Get the .info.yml file changes into 8.8.x

Then contrib maintainers can, at will, use ^8 | ^9 to express that they are compatible with 8 and 9, and not have to worry about an 8.7/8.6 breaking issue where somebody on a security supported site cant get a security update for a module.

2. Refactor #3005229: Provide optional support for using composer.json for dependency metadata such that if an .info.yml file exists, and has a core: key, use the existing logic in core. If there is a composer.json, and no keys for core/deps/test_deps in .info.yml, use composer.json as the source of truth. The goal here is to not intermix the two options. Using .info.yml will not be deprecated until drupal 10. Having a composer.json alongside your modules will be the preferred method if you need/want ~/^ operators, as well as patch level dependency specifications. This will also enable an eventual 'subtree split' for modules (though the module/projectname collisions need additional thought).

3. Close/wont fix #3004459: [PP-1] Fold in dependency parsing wisdom from project_composer because if we can avoid manipulating the existing parsing thats better. If we still want this code for a potential, optional conversion script, we could leverage it for that.

4. Mark #2641658: Module version dependency in .info.yml is ineffective for patch releases: as a duplicate of #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning because we'll get the core key functionality as a result of #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning, and we can hold off on the contrib semver part until #3005229: Provide optional support for using composer.json for dependency metadata.

5. Harden test deps for existing code. #3066448: Harden test coverage for dependency Constraint class There can never be too many tests.

wim leers’s picture

First: thanks to everyone involved with creating this issue and discussing it. This issue brings clarity in a cluster of seemingly overlapping issues that were hard to make sense of (at least for me). The options listed in the "proposed resolution" section in the issue summary made it crystal clear. 👏👍

@tedbow was kind enough to walk me through the discussion and thought process. He pointed out one very interesting aspect of the first and second option that I had not considered yet (it may be obvious to some of you, it was not to me) that I don't see listed in the issue summary yet: even though it seems unlikely that we'd break something along the way, if we get something wrong, it may break the Drupal 8 to 9 upgrade process in a subtle way that we will only discover when it is too late. This is what convinced me beyond doubt that the risk in options one and two is unacceptable.

@Mixologic in #13: wow, impressive foresight! 😲

The plan that came out of a meeting with key people that is documented in #14 is crystal clear. 👍The only clarification that I think would be helpful there is

we can hold off on the contrib semver part until #3005229: Provide optional support for using composer.json for dependency metadata

Does this mean we want to do #3005229 only in Drupal 9, not in Drupal 8? (#3005229 is currently marked for 8.8.x-dev.)

Mixologic’s picture

The wording there is a little bit unclear.

There was a general feeling that adding semver support by adding optional support for composer.json files was going to be 'bigger' or 'more complex'. The 'hold off' part was really "lets not manipulate the existing system, and simply add the optional support in a different code path". The other thing that means is that since we do not plan on deprecating using .info.yml files for dependency resolution until drupal 10, then essentially, we can add that new option 'as soon as we can get it in' which might be possible in 8.8.x, but, may also require that we wait until the 9.1 cycle, based on timing/workload other factors.

Some of the 'bigger/more complex' parts is that when we get into the extension system, we definitely trip over weird vestigal things that are awkward or hard to work with, and need a refresh, aka #3053832: Refactor ModuleListForm. Those are the kinds of things where we find that maybe the original stuff wasn't tested very well, or has built in assumptions about how it works that arent documented etc.

Anyhow I think we want to do #3005229: Provide optional support for using composer.json for dependency metadata as soon as we can, but the window for 'soon' is rapidly shrinking. However it may be something we *have* to make happen because we've needed semver for contrib for quite a long time now.

wim leers’s picture

That's crystal clear. Thanks, @Mixologic!

xjm’s picture

Issue tags: +mwds2019
tedbow’s picture

Relating #3074998: Add explicit information about core compatibility to update data because currently information in the update XML doesn't explicitly specify which core version and update is compatible with.

wim leers’s picture

Issue summary: View changes

Updated the issue summary to make it clear we chose option #3.

wim leers’s picture

So, how are we executing our detailed strategy from #14?

  1. 🏃‍♀️#2313917: Core version key in module's .info.yml doesn't respect core semantic versioning saw many more iterations, many refinements, many edge cases discovered and addressed. It's currently RTBC to get release manager and framework manager feedback wrt the name of the new key and to get release manager feedback wrt a potential 8.7 backport.
  2. 🏃‍♀️#3005229: Provide optional support for using composer.json for dependency metadata is in progress and the patch @tedbow is currently working on and I am reviewing.
  3. #3004459: [PP-1] Fold in dependency parsing wisdom from project_composer was closed.
  4. #2641658: Module version dependency in .info.yml is ineffective for patch releases was closed.
  5. #3066448: Harden test coverage for dependency Constraint class was committed.
wim leers’s picture

Issue summary: View changes

🤦‍♂️

gogowitsch’s picture

Issue summary: View changes

I only updated the grammar of the issue description.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

dww’s picture

Not sure if this is the right place to mention this, or if I should spin off a child issue, or what, but...

#3116581: Use core_version_requirement, not a version dependency on drupal:views

VBO made a 8.x-3.5 release with bold text on the release notes saying "this version of VBO will require Drupal core >= 8.8. If for some reason 8.7 or lower is used on your project - don't update."

However, it defines this requirement via:

core: 8.x
dependencies:
  - drupal:views (>=8.8)

Not:

core_version_requirement: ^8.8

So none of our tooling knows about it. :(

Do we care? Should we do anything to try to handle this case, or do we punt and say: "that way of defining core requirements is deprecated, go fish."?

Oh, except I searched and couldn't find any issue where we actually "deprecate" using dependencies: to define a specific version of a core module you need. So what VBO did is actually totally fine, and I don't believe that's been deprecated at all. :( Seems like a big gap in this whole plan, and I don't see it mentioned in this issue. In #10 @tedbow wants to deprecate the Drupal-specific range operators in dependencies:, but there's no talk of using dependencies to refer to core. I don't think we can deprecate this behavior, since not all core module are required, and contrib needs to be able to have dependencies on optional core modules. So I think we've got to keep supporting that. But maybe we can deprecate defining a core version that way?

Can the project_dependencies world notice this kind of thing and make sure that the <core_compatibility> in the release history XML feeds takes these sorts of core compatibility constraints into account, too? Basically, define <core_compatibility> as the most restrictive requirements from all of core, core_version_requirement and dependencies ?

Also, does anything stop contrib authors from getting this totally wrong and doing things like:

core_version_requirement: ^8.7 || ^9
dependencies:
  drupal:system (>=8.8)

? Not sure where we can/should try to notice that and prevent them from doing it. It'd sorta be nice to notice before they try to make a broken release, but I don't think that's possible. I know we've got code that makes sure you don't do core_version_requirement: ^8.5 or something, since 8.5.x core didn't support that key. But I don't think we've got anything that tries to notice conflicts / incompatibilities between core_version_requirement and dependencies.

Thoughts?

Thanks/sorry,
-Derek

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

xjm’s picture

Title: [META] Improve dependency management » [meta] Improve dependency management for extensions

Clarifying that this is about downstream modules and themes, not upstream dependencies.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.