Problem/Motivation

Libraries can be deprecated, but we don't tell themes that are overriding or extending existing libraries that they need to update (only users of the library itself). If a theme only overrides, it might never see the deprecation error if the library is unused.

Follow-up from #3113400: Deprecate more jQuery UI library definitions

Steps to reproduce

Proposed resolution

When a library being overridden or extended is deprecated, trigger a deprecation error.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

catch created an issue. See original summary.

JeroenT’s picture

Status: Active » Needs review
FileSize
2.08 KB
catch’s picture

Issue summary: View changes
catch’s picture

Priority: Normal » Critical
Issue tags: +Drupal 10

Following lauriii's review of #3113400: Deprecate more jQuery UI library definitions let's make this a pre-requisite rather than a follow-up.

nod_’s picture

Issue tags: +JavaScript
jungle’s picture

Issue tags: +Needs tests
lauriii’s picture

Added some tests and adjusted the deprecation messages to display the change record.

lauriii’s picture

While I was working on this, I opened #3166553: Move libraries-extend and libraries-override processing to a more logical class too to make the processing easier to understand and more logical.

Status: Needs review » Needs work

The last submitted patch, 7: 3163500-7-test-only.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

lauriii’s picture

Status: Needs work » Needs review

Moving back to NR since the fails are in the test only patch

longwave’s picture

Status: Needs review » Needs work

Looks pretty good so far!

  1. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php
    @@ -136,6 +136,11 @@ protected function applyLibrariesExtend($extension, $library_name, $library_defi
    +          $library_deprecation = str_replace('%library_id%', "$extension/$library_name", $library_definition['deprecated']);
    

    Nice, I like how this is similar to service deprecation in Symfony.

  2. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryCollector.php
    @@ -136,6 +136,11 @@ protected function applyLibrariesExtend($extension, $library_name, $library_defi
    +          @trigger_error(sprintf('%s %s', $extend_message, $library_deprecation), E_USER_DEPRECATED);
    

    Is sprintf('%s %s') really necessary, we can just use concatenation?

  3. +++ b/core/tests/Drupal/KernelTests/Core/Asset/LibraryDiscoveryIntegrationTest.php
    @@ -208,6 +213,33 @@ public function testLibrariesExtend() {
    +    $expected_derecations = [
    

    Typo in "deprecations"

lauriii’s picture

Status: Needs work » Needs review
FileSize
3.63 KB
19.8 KB

Thanks for the review @longwave!

#11.2 I don't have a strong preference on to which approach we should use. I changed this to double quotes but I'm fine with concatenation too.

#11.3 Fixed

jungle’s picture

longwave’s picture

  1. +++ b/core/tests/Drupal/KernelTests/Core/Asset/LibraryDiscoveryIntegrationTest.php
    @@ -208,6 +213,35 @@ public function testLibrariesExtend() {
    +    $expected_deprecations = [
    +      'Theme "theme_test" is overriding a deprecated library. The "theme_test/deprecated_library" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com',
    +      'Theme "theme_test" is extending a deprecated library. The "theme_test/another_deprecated_library" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com',
    +      'The "theme_test/deprecated_library" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com',
    +      'The "theme_test/another_deprecated_library" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com',
    +    ];
    +    $this->assertSame($expected_deprecations, $deprecations);
    

    Why do we need the error handler dance in the test, can't we use the @expectedDeprecation tag?

  2. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryCollectorTest.php
    @@ -150,4 +166,95 @@ public function testDestruct() {
    +    catch (\ErrorException $e) {
    +      $this->assertSame('Theme "test" is extending a deprecated library. The "test/test_4" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use the test_3 library instead. See https://www.example.com', $e->getMessage());
    +    }
    

    Similar here, we have ExpectDeprecationTrait to use in unit tests.

lauriii’s picture

Both, Symfony\Bridge\PhpUnit\ExpectDeprecationTrait and @expectedDeprecation requires adding the test to the @group legacy. I'm not sure we want that here because we are not testing deprecated code but our own APIs that allow deprecating code. Similar approach was taken in #3064017: Create a means to mark an asset library as deprecated in a *.libraries.yml file.

longwave’s picture

Hm, we have lots of tests that test deprecation implementations, that do use @group legacy with @expectedDeprecation, some examples:

core/tests/Drupal/FunctionalJavascriptTests/JavascriptDeprecationTest.php:   * @expectedDeprecation Javascript Deprecation: This function is deprecated for testing purposes.
core/tests/Drupal/FunctionalTests/Core/Test/PhpUnitBridgeTest.php:   * @expectedDeprecation This is the deprecation message for deprecation_test_function().
core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookTest.php:   * @expectedDeprecation The deprecated alter hook hook_deprecated_alter_alter() is implemented in these functions: deprecation_test_deprecated_alter_alter. Alter something else.
core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookTest.php:   * @expectedDeprecation The deprecated hook hook_deprecated_hook() is implemented in these functions: deprecation_test_deprecated_hook(). Use something else.
core/tests/Drupal/KernelTests/Core/Extension/ModuleHandlerDeprecatedHookTest.php:   * @expectedDeprecation The deprecated hook hook_deprecated_hook() is implemented in these functions: deprecation_test_deprecated_hook(). Use something else.
core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php:   * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
core/tests/Drupal/KernelTests/Core/Test/PhpUnitBridgeTest.php:   * @expectedDeprecation This is the deprecation message for deprecation_test_function().
core/tests/Drupal/Tests/Core/Security/DoTrustedCallbackTraitTest.php:   * @expectedDeprecation Drupal\Tests\Core\Security\UntrustedObject::callback is not trusted
core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeIsolatedTest.php:   * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.
core/tests/Drupal/Tests/Core/Test/PhpUnitBridgeTest.php:   * @expectedDeprecation Drupal\deprecation_test\Deprecation\FixtureDeprecatedClass is deprecated.

I wonder if we need a new @group that will let us test things like this without implying they are actually going to be removed.

catch’s picture

A wide definition of @legacy would include APIs for deprecating other code, although yeah being able to distinguish between the two would be good. I do think we should probably use @legacy for now since the functionality it provides is fine.

lauriii’s picture

This implements the tests using @expectedDeprecation ✌️

larowlan’s picture

Status: Needs review » Needs work

This looks great, just a couple of minor items

  1. +++ b/core/.phpunit.result.cache
    @@ -0,0 +1 @@
    +C:37:"PHPUnit\Runner\DefaultTestResultCache":533:{a:2:{s:7:"defects";a:2:{s:84:"Drupal\KernelTests\Core\Asset\LibraryDiscoveryIntegrationTest::testDeprecatedLibrary";i:3;s:84:"Drupal\Tests\Core\Asset\LibraryDiscoveryCollectorTest::testLibrariesExtendDeprecated";i:4;}s:5:"times";a:3:{s:84:"Drupal\KernelTests\Core\Asset\LibraryDiscoveryIntegrationTest::testDeprecatedLibrary";d:2.714;s:84:"Drupal\Tests\Core\Asset\LibraryDiscoveryCollectorTest::testLibrariesExtendDeprecated";d:0.035;s:81:"Drupal\Tests\Core\Asset\LibraryDiscoveryParserTest::testLibraryOverrideDeprecated";d:0.037;}}}
    

    this shouldn't be in the patch, might be worth adding to your .git/info/exclude

  2. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -544,6 +551,98 @@ public function testLibraryWithLicenses() {
    +    $this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface');
    +    $this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
    ...
    +    $this->themeManager = $this->createMock('Drupal\Core\Theme\ThemeManagerInterface');
    +    $this->activeTheme = $this->getMockBuilder('Drupal\Core\Theme\ActiveTheme')
    

    Should we be using class constants for new code?

raman.b’s picture

Status: Needs work » Needs review
FileSize
19.32 KB
4.93 KB
longwave’s picture

+++ b/core/modules/system/tests/modules/theme_test/theme_test.libraries.yml
@@ -5,3 +5,17 @@ theme_stylesheets_override_and_remove_test:
+  deprecated: 'The "%library_id%" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com'
...
+  deprecated: 'The "%library_id%" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com'

I know this is just test code but I realised the version numbers make no sense, we deprecate it after we remove it. In the other test case we say "is removed from drupal:10.0.0".

Out of scope for here but to avoid confusing test deprecations with real deprecations should we use fake version numbers like X.0.0 and Y.0.0 in tests?

jungle’s picture

+1 to use fake version numbers and updated the patch accordingly.

Status: Needs review » Needs work

The last submitted patch, 22: 3163500-22.patch, failed testing. View results

jungle’s picture

Status: Needs work » Needs review
FileSize
19.32 KB
1021 bytes

One usage missied

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Hmm, I thought changing this might need a policy discussion as we haven't done it anywhere else yet. But as you agree, let's be bold and mark RTBC and see what core committers think. Otherwise the patch is good, this was just a last-minute nit.

catch’s picture

+++ b/core/modules/system/tests/modules/theme_test/theme_test.libraries.yml
@@ -11,11 +11,11 @@ deprecated_library:
       css/foo.css: {}
-  deprecated: 'The "%library_id%" asset library is deprecated in drupal:9.1.0 and is removed from drupal:9.0.0. Use another library instead. See https://www.example.com'
+  deprecated: 'The "%library_id%" asset library is deprecated in drupal:X.0.0 and is removed from drupal:Y.0.0. Use another library instead. See https://www.example.com'
 
 another_deprecated_library:

+1 to the fake version numbers, means this won't look out of date every two years. Will try to give this a more in-depth review asap (but not likely this afternoon).

  • catch committed 07daa79 on 9.1.x
    Issue #3163500 by lauriii, jungle, raman.b, JeroenT, catch, longwave,...
catch’s picture

Status: Reviewed & tested by the community » Fixed

OK so the only issue here is that @expectedDeprecation is itself deprecated per #3172438: Since symfony/phpunit-bridge 5.1: Using "@expectedDeprecation" annotations in tests is deprecated, use the "ExpectDeprecationTrait::expectDeprecation()" method instead., but I think it's OK to defer changing how we test deprecations to that issue.

Committed 07daa79 and pushed to 9.1.x. Thanks!

This issue doesn't need its own change record, but I added it to https://www.drupal.org/node/3064022 for background.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.