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
Add --fatal-deprecations and --future-deprecations #1820
Conversation
This adds a new `Deprecation` class that specifies an ID for each deprecated feature along with what Dart Sass version deprecated it. The compile functions allow you to pass a set of `fatalDeprecations` that will cause an error instead of a warning. You can also pass a set of `futureDeprecations`, which let you opt-in to deprecations (like `@import`) early.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also file issues to track adding this to the JS API and documenting it on the Sass website?
CHANGELOG.md
Outdated
* The optional `deprecation` boolean parameter of the `warn` function is now | ||
deprecated. Use `deprecationType` to pass the specific `Deprecation` being | ||
warned for instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if users are writing custom functions that have behavior that becomes deprecated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking they would pass Deprecation.userAuthored
, but do you think it would make more sense to just leave the boolean parameter un-deprecated? (since right now if they pass deprecation: true
with no deprecationType
, it defaults to Deprecation.userAuthored
)
Or could it be confusing to have both deprecation
and deprecationType
un-deprecated, since then you could potentially call it with a deprecation type but explicitly pass deprecation: false
? (in which case the boolean parameter would be ignored)
Would making deprecation
nullable but un-deprecated work?
If we do leave the deprecation
un-deprecated in EvaluationContext.warn
, should we also do the same for Logger.warn
? If we do that, should we just leave the warnForDeprecation
extension for Logger
as private? (since custom functions should usually be just using Deprecation.userAuthored
anyway)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we just have two separate functions for both EvaluationContext
and Logger
, one for public consumption that takes a boolean deprecation
flag and one that's private to Sass which takes a Deprecation
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
bin/sass.dart
Outdated
logger: DeprecationHandlingLogger(options.logger, | ||
fatalDeprecations: options.fatalDeprecations, | ||
futureDeprecations: options.futureDeprecations, | ||
// This logger may be reused by multiple parses, so we don't want | ||
// warnings from a previous parse to cause subsequent warnings to | ||
// be skipped. | ||
limitRepetition: false))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a couple questions here:
-
Previously, the
Options
class was responsible for setting up the logger according to the options passed. Why not do the same withDeprecationHandlingLogger
? -
If we don't limit repetitions here, under what circumstances will we limit repetitions on the CLI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wrapped logger is only used during parsing. options.logger
is wrapped by a DeprecationHandlingLogger
again during the actual compilation (this time, with limitRepetition
set to true if verbose
is false).
This matches the current behavior with the TerseLogger
that DeprecationHandlingLogger
replaces (repetitions aren't limited for deprecation warnings during parsing). The need to reset the state of DeprecationHandlingLogger
is also why we don't just have options.logger
produce it.
We could change options.logger
to just produce a single DeprecationHandlingLogger
, but we'd then need some way for StylesheetGraph
and the compiler to reset its state after each run. Do you think that makes more sense instead of wrapping the base logger multiple times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I think this is fine. It might be worth documenting more of what you just said in the comments, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
..addMultiOption('fatal-deprecation', | ||
help: 'Deprecations to treat as errors. You may also pass a Sass\n' | ||
'version to include any behavior deprecated in or before it.\n' | ||
'See https://sass-lang.com/documentation/breaking-changes for \n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update this documentation so that each breaking change includes an example of how to make it fatal as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working on a sass-site PR now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/src/deprecation.dart
Outdated
/// For deprecations that have existed in all versions of Dart Sass, this | ||
/// should be 0.0.0. For deprecations that are not yet active, this should be | ||
/// null. | ||
final String? deprecatedIn; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see... real enums strike again. I think the cleanest option given that might be to convert this to a normal class with static final
members instead of a literal enum. That's more work to declare, but nicer on the consuming end, which I think it a worthy trade-off.
CHANGELOG.md
Outdated
* The optional `deprecation` boolean parameter of the `warn` function is now | ||
deprecated. Use `deprecationType` to pass the specific `Deprecation` being | ||
warned for instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we just have two separate functions for both EvaluationContext
and Logger
, one for public consumption that takes a boolean deprecation
flag and one that's private to Sass which takes a Deprecation
?
bin/sass.dart
Outdated
logger: DeprecationHandlingLogger(options.logger, | ||
fatalDeprecations: options.fatalDeprecations, | ||
futureDeprecations: options.futureDeprecations, | ||
// This logger may be reused by multiple parses, so we don't want | ||
// warnings from a previous parse to cause subsequent warnings to | ||
// be skipped. | ||
limitRepetition: false))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I think this is fine. It might be worth documenting more of what you just said in the comments, though.
lib/src/deprecation.dart
Outdated
/// If this is true, `deprecatedIn` should be null, since we do not yet know | ||
/// what version of Dart Sass this deprecation will be live in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you make this a real class, you can also verify this in a constructor assert()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accomplished this in the enum form by having separate constructors for regular and future deprecations.
Partial fix for #633 and #1363.
This adds a new
Deprecation
enum to track the different deprecations that are ongoing or upcoming and allow users to select certain deprecations to treat as fatal (or future deprecations to begin warning for now).This adds support to the CLI and the Dart API. It does not add support for the JS API yet, but I'd like to land this first so the underlying logic isn't blocked on the language change process.