Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: detecting and handling unfixable deprecations #30

Open
greg0ire opened this issue May 1, 2021 · 2 comments
Open

RFC: detecting and handling unfixable deprecations #30

greg0ire opened this issue May 1, 2021 · 2 comments

Comments

@greg0ire
Copy link
Member

greg0ire commented May 1, 2021

In reaction to a comment from @morozov on a PR adding deprecations to the DBAL 1, here are my thoughts on unfixable deprecations.

Definition

An unfixable deprecation is a deprecation that the user cannot fix without running composer update, and might not necessarily be able to fix by running it.

Why

Unfixable deprecations are arguably noise they cannot act on without a contribution upstream, a release, and a composer update. One might want to mute them, but it can be argued that it can also be an incentive to contribute, or useful information to know what blockers prevent you to upgrade to the next major of some package, regardless of whether you can fix that in your application or not.

What

Let's think of ways we could improve this package by letting users mute deprecations based on their type.

History

We have encountered the issue of having too many unfixable deprecations with @alcaeus on doctrine/persistence while using @trigger_error + Symfony 2 .

Also, following a question asked after a talk on deprecations by Nicolas Grekas , where somebody asked if it would be possible for the phpunit bridge to separate fixable from unfixable deprecations, I contributed to that package and implemented a separation in three types:

  • self deprecation: when a package calls its own deprecated API
  • direct deprecations: when the root package calls the deprecated API of another package
  • indirect deprecations: when the root packages calls n packages which in turn call the deprecated API of a package

As you can see 3, I was forced to add a fourth type for cases when it's unclear what the situation is.

Implementation

Using Composer's getPrefixes() and getPrefixesPsr4() API, one can determine where vendor packages reside, where the sources of the root package reside, and what package each file in a stack trace belongs to. 4
From that, it's most of the time possible to determine a type for each deprecation, and make decisions on how to handle them based on configuration: mute them, fail the build if a type reaches a given threshold, displaying them separately, etc.

Edge cases

Here are some special situations that made that a complex development:

  • a deprecation is triggered from STDIN
  • a deprecation is triggered from a phar
  • a deprecation is triggered by a library loading a configuration file written by the end user, and that file uses deprecated configuration nodes

Vocabulary

It's easy to get confused if you lack the words to express your ideas, and the vocabulary in this RFC can of course be challenged, everyone is encouraged to find alternate wording. Here is a list of names that could be challenged:

  • fixable, direct, self
  • unfixable, indirect
  • root package, application, project
@greg0ire greg0ire changed the title RFC: detecting and handling unfixable deprecation RFC: detecting and handling unfixable deprecations May 1, 2021
@morozov
Copy link
Member

morozov commented May 1, 2021

Thanks for putting this together, @greg0ire. I can't think of a proper replacement right now, but I think the vocabulary around fixable/unfixable and the intent of communicating deprecations could be improved.

I think the primary purpose of a runtime deprecation is to help the developer improve their code that uses the deprecated API. Therefore, if a runtime deprecation doesn't achieve this goal, it should not be shown to the developer. Examples are:

  1. The problem is not in their package.
  2. There's no upgrade path provided (i.e. the only way to start using the new API is to upgrade to the new version and drop the support for the old one).

An unfixable deprecation is a deprecation that the user cannot fix without running composer update, and might not necessarily be able to fix by running it.

I don't think fixable/unfixable is the right way to categorize issues. There are no unfixable issues, it's only a matter of who should fix them and how.

@malarzm
Copy link
Member

malarzm commented May 10, 2021

The problem is not in their package.

I disagree. If one of installed packages (A) is using a deprecated API from some other package (B), it's a signal I can't upgrade B without taking care of A first. Taking care may involve simply upgrading A, filing an issue, or opening a PR to fix the deprecation. This is still actionable and valuable information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants