Problem/Motivation
On a Drupal 8.0.0 installation, if I set a module dependency to
dependencies:
- drupal:system (>= 8.1)
I correctly get, in the extend page, the module greyed out from installation and the message
but if I set the dependency to
dependencies:
- drupal:system (>= 8.0.1)
I can install the module with no warning nor check
Also, a documentation problem: while there is description of module version dependency on the D7 doc Writing module .info files (Drupal 7.x) page, the D8 page ( Let Drupal 8 know about your module with an .info.yml file) only refers to module (no version, no project) dependency
Proposed resolution
Postponed on #2677532: Move drupal_check_incompatibility() functionality to a new Dependency class and Version component.
Remaining tasks
User interface changes
API changes
Data model changes
Original report:
I tried to enter a module version dependency in a module .info.yml file
dependencies:
- system (>= 8.0.1)
but this seems not to be effective - the module installs fine on D8.0.0.
In D7 it was possible to set a dependency to the system module at a certain release level to ensure that a contrib module can be installed with minimum Drupal version.
Is there a way for this in D8? It would be quite important in contrib to make sure a module can benefit of features introduced in D8 minor releases.
Comment | File | Size | Author |
---|---|---|---|
#50 | 2641658-50.patch | 6.8 KB | tedbow |
#50 | interdiff-49-50.txt | 3.32 KB | tedbow |
#49 | 2641658-49.patch | 7.11 KB | tedbow |
#49 | interdiff-46-49.txt | 2.56 KB | tedbow |
#46 | 2641658-46-minor-x-test-only.patch | 3.24 KB | tedbow |
|
Comments
Comment #2
cilefen CreditAttribution: cilefen commentedDoes this help?
Comment #3
mondrakeThanks @cilefen. I checked docs and tested a bit, and I think we have a problem: module version dependency check seems not semver compliant.
On a Drupal 8.0.0 installation, if I set a module dependency to
I correctly get, in the extend page, the module greyed out from installation and the message
but if I set the dependency to
I can install the module with no warning nor check
Also, a documentation problem: while there is description of module version dependency on the D7 doc Writing module .info files (Drupal 7.x) page, the D8 page ( Let Drupal 8 know about your module with an .info.yml file) only refers to module (no version, no project) dependency
Comment #4
mondrakeComment #5
cilefen CreditAttribution: cilefen commentedRe: #3, that could be by design because all patch releases are backwards-compatible.
Comment #6
cilefen CreditAttribution: cilefen commentedComment #7
cilefen CreditAttribution: cilefen commentedI am tagging this "documentation" because I agree this feature seems undocumented online.
Comment #8
Crell CreditAttribution: Crell as a volunteer commentedPatch releases are supposed to be BC, but could fix bugs. It's entirely legit for a module to depend on "Drupal 8.1.2, because 8.1.1 had a bug in it that made this thing not work." So I wouldn't call this by-design. It's just a straight up bug.
Comment #9
mondrakeUpdated IS with comment in #3
Comment #10
mondrakeComment #11
jonhattanPatch version is ignored when parsing dependencies. Attached a patch that takes it into account along with a test.
Comment #12
jonhattanBtw Drush version parser is independent of Drupal's one. It is at http://api.drush.org/api/drush/commands!pm!pm.drush.inc/function/pm_pars...
Note also that Drupal is using major-minor nomenclature in code, while it is documented that contrib modules uses major-patch -> https://www.drupal.org/node/467026
Comment #13
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedWhat's TODO here? Also comments should wrap at 80 char line.
Again, comments should wrap at 80 line, in this case "is" should be moved to the next line.
This tactic will break in time, meaning we will have to update this in every 6 months. It's not horrible, but would be nice if we can make a test that will just work. Either we would have to alter the \Drupal::VERSION somehow or dynamically set/alter the dependency in the from the info.yml file.
Comment #14
jonhattan#13.1 I added this @todo@ to note that, although it works, we're not being algorithmically accurate. See comment #12
#13.2 I wonder if a shorten module name is better (
system_incompatible_module_semver_dependencies_test
)#13.3 It won't fail because Drupal::VERSION is 8.0.0-dev even in 8.1.x branch - http://cgit.drupalcode.org/drupal/tree/core/lib/Drupal.php?h=8.1.x#n81. I don't know if it is intended or a bug.
Just in case, we want to alter the dependency (via
hook_system_info_alter()
), not Drupal::VERSION.Comment #15
mondrake#13 and #14.3 note there's #2640650: Update the version number from 8.0.x to 8.1.x and also comment #5 in that issue
Comment #16
googletorp CreditAttribution: googletorp as a volunteer and at Reveal IT commentedRegarding #13.1
If we actually want to make a @todo, general practice is to use "@todo" not
@todo@", it should have a link to an issue containing an open task on the todo (so we know it's going to be done eventually) or it should be solved in this ticket. The comment should state what's left "to do".
In this case, if we want to algorithmically accurate, we should do it, if we feel like it's not needed or would make the code unnecessary complex, then there's no @todo here, but a comment explaining the reasoning would be needed.
Regarding #13.2 It's ok that the name spans over 80 chars when it's really long, but the "is" after it should be moved to the line after.
Regarding #13.3 It seems odd that 8.0.0-dev is used for all 8.x.x releases, but still it's just a matter of time (9.x.x) before the test will fail. We might as well make this future proof, so we don't make tests that will fail when the Drupal version number changes.
Comment #17
xjmHuh, the module handler doesn't use version_compare()? And I went to all that effort testing with it in #2656994: Experimental modules should have their own version numbers. ;) It would be worth investigating if and why it's not used.
For me this is legitimately a bug, since compatibility with patch releases is something that will be needed from time to time. For example, say a certain contrib module is blocked on a patch-release-safe bug, but will destroy your data horribly before that bug is fixed. Totally sensible to require the patch release as the minimum allowed version.
Comment #18
xjmModuleHandler::parseDependency() does not use
version_compare()
, with this inline comment:Comment #19
xjmThat is, or was, a bug. A release manager who rebased 8.1.x clearly did not fix this when she did so. ;) It was fixed in #2640650: Update the version number from 8.0.x to 8.1.x.
Comment #21
MixologicAs a side note, I had to pretty much re-do parse_dependency logic for the composer façade:
http://cgit.drupalcode.org/project_composer/tree/project_composer.module...
And have a test built for it:
http://cgit.drupalcode.org/project_composer/tree/project_composer.test#n54
Perhaps this can be adapted to be something used by both core and project_composer?
Comment #22
Wim Leers#21++
We're seeing this become a problem for D8 contrib modules, that need a particular minimum version of Drupal because prior versions contained show-stopping bugs.
Examples:
Comment #23
MixologicComment #28
sunAlso, the D8 docs in https://www.drupal.org/node/2000204 do not document whether it is possible to specify a minimum version for the
core:
property (as it is with thephp:
property). Is that possible?While the hack in the OP should probably work, too – it has the UX & look & feel of a hack.
The
php
property maps to acomposer require php:x.y.z
. Thecore
property would map to acomposer require drupal/core:x.y.z
. No?In any case, I would recommend module maintainers to specify the composer.json properties, as that prevents an incompatible version from being downloaded into the working directory in the first place.
Comment #29
drummI think this is currently the most-immediate blocker to Drupal.org allowing semantic versioning for contrib releases.
Comment #30
Mile23Re: #21: We could move
project_composer_parse_dependency()
to a core component. This would allow project_composer to depend on it, and libraries as per #23.Then we can fix this issue by using composer/semver after a conversion.
Comment #31
MixologicIs that somewhat what this #2677532: Move drupal_check_incompatibility() functionality to a new Dependency class and Version component is trying to do ? I mean, it moves it to 'its own class' but maybe we should make it a component from the getgo.
Comment #32
Mile23:-) See #2677532-6: Move drupal_check_incompatibility() functionality to a new Dependency class and Version component
Comment #34
Gábor Hojtsy@Mixologic suggested in #2807145: [policy, no patch] Allow contrib projects to specify multiple major core branches that we postpone that one on this, so I did so. Especially if we are going with #21 which would help us do the same logic in Drupal and on drupal.org.
Comment #35
Gábor HojtsyAlso we should postpone this on #2677532: Move drupal_check_incompatibility() functionality to a new Dependency class and Version component as per above which is RTBC now!
Comment #36
larowlan#2677532: Move drupal_check_incompatibility() functionality to a new Dependency class and Version component is now in
Comment #37
larowlanComment #38
MixologicThere's a new META in town.
Comment #39
webchickThis issue is blocking (at least) the Automatic Updates, Composer in Core, and Drupal 9 initiatives. After talking to @xjm, escalating to critical.
Comment #40
kim.pepperI think @webchick meant to change the priority too. :-)
Comment #41
andypostRe-roll of patch
Comment #42
andypostThe test only patch, btw it looks tricky because require to point exact version
Comment #43
pingwin4egSo what about #21?
Comment #44
Gábor HojtsyWhat is to do about this? The comment seem to list facts only.
Comment #45
tedbowmaybe referring to
But although we don't support "support" 8.x.1 or 8.x.x basically semantic versions with "x" in minor and a patch supplied this doe actually work in
\Drupal\Component\Version\Constraint::isCompatible()
.I am providing test-only patch for
\Drupal\Tests\Component\Version\ConstraintTest
to prove this.I don't think the current patch will change this.
Should we make a follow up to enforce validation?
\Drupal\Tests\Component\Version\ConstraintTest::providerIsCompatible()
because even though we are calling PHP'sversion_compare
if we got the regex wrong this could cause unexpected results so this should be well tested.Yes since it relies on
\Drupal::VERSION
we would have to update the test module and test with every patch version.To avoid this we should do something like
\Drupal\Tests\system\Functional\Module\VersionTest::testModuleVersions()
and usesystem_test_system_info_alter
to alter the version number of the system module and the dependency string. This allows removing the system_incompatible_module_semantic_version_dependencies_test because we can just alter the dependency of thecommon_test
module likeVersionTest
doesWe use
elementContains()
here to make sure the correct module has this message in the off chance we add a test module in the future that have a similar message and produce a false positive for this test.This is copied from other test methods in the class but we can now just replace this with
$this->assertSession()->fieldDisabled('edit-modules-common-test-enable');
which is more readable.Comment #46
tedbowThe drupalci changes to the test-only patch were wrong.
Comment #47
tedbowWanted to bring in couple related issues
\Drupal\Component\Version\Constraint
because test coverage in\Drupal\Tests\Component\Version\ConstraintTest
is so thin we could easily break functionality without knowing it.It would be great to get that in first
\Composer\Semver\Semver::satisfies()
instead ofversion_compare()
which requires parsing our constraint strings into a Composer format so that is bigger(more risky?) change. But it does get rid of a lot of own regexComment #48
Wim LeersI think @sun's observation in #28 belongs in the issue summary:
That would make it crystal clear and gets us on a path where we can migrate towards
composer
more easily in the future!I haven't updated the issue summary yet because I don't know if there's consensus about this.
#45: 👏 Thanks for getting this issue back on track!
#47:
\Composer\Semver\Semver::satisfies()
. So that answers my question. And makes the choice pretty clear to me: we should land #3004459: [PP-1] Fold in dependency parsing wisdom from project_composer, which uses Composer's logic, which removes the need for the fixes in this issue.Hah, now reviewing this to assist @tedbow, and in reading the entire issue I come across a comment of mine from three years ago 😁 (#22)
Comment #49
tedbow@Wim Leers thanks for the review
\Composer\Semver\Semver::satisfies()
it introduces more complexity to get to that simplicity.\Composer\Semver\Semver::satisfies
on the constraint string directly if it is not valid this will throw aUnexpectedValueException
and then we use existing logic. This requires no changes to\Drupal\Component\Version\Constraint::parseConstraint()
It would make the upgrade to #3005229: Provide optional support for using composer.json for dependency metadata as modules could start to use constraints that could be moved to
composer.json
directly.Also it doesn't try to support semantic versioning and our drupal version format in the same logic.
Comment #50
tedbowOne option to get away from own parsing would be to deprecate our own format which would basically mean just returning with in this catch.
If at some point we deprecated our Drupal specific format we could display a message about being incompatible or just do a scan on the status report page for any constraints that thrown an exception in
(new VersionParser())->parseConstraints($constraint)
.Removing these test cases. I am actually sure if this is problem. We generally seem to return TRUE if the constraint is nonsense which seems like the real problem.
It think this just points to the fact that we should get away from our own parsing.
Incorrect module name
Adding a test where we have semantic version constraint that passes.
Comment #51
tedbow@Mixologic commented on #3069795-11: [meta] Improve dependency management for extensions as to why the approach in #49 would be a problem
This would introduce the possibility to use
~/^
and probably other composer format changes that I am not thinking of right now.So we don't want to do this in Drupal core unless it is conjunction with changes on drupal.org/project_composer.
There a few options then
- drupal:system (>= 8.0.1)
actually not needed because you could just use thecore:
key. Others semantic versioning independencies
is not actually needed until #3054391: [META] Support semantic versioning on drupal.org for contributed projects and if by that time #3005229: Provide optional support for using composer.json for dependency metadata is committed we could rely on that.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.
.
Comment #52
tedbowre #50.2
Created #3071150: Dependency version constraints evaluate true even the constraint strings aren't valid
Comment #53
tedbowNow this is duplicate of #2313917: Core version key in module's .info.yml doesn't respect core semantic versioning. See #3069795-14: [meta] Improve dependency management for extensions for details and related issues
See #51.1 for details here