-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
interpreter: deprecate using an array for project(license:) #9940
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
## project license keyword argument as an array has been deprecated | ||
|
||
Meson has traditionally supported using either a string or an array of strings | ||
as the `license` argument to `project`. More recently it has been strongly | ||
suggested to use an SPDX license expression string instead. SPDX is now an ISO | ||
standard, and is well understood outside of Meson. When used in a Software Bill | ||
of Materials it is natively understood by many tools. An array of licenses is | ||
ambiguous, does `['Apache-2.0', 'GPL-2.0-only']` mean `Apache-2.0 AND GPL-2.0-only` | ||
or `Apache-2.0 OR GPL-2.0-only`? These mean very different things, as the first | ||
is widely believed to be incompatible, and the latter is widely understood to | ||
mean "Apache-2.0 in general, but you may use it as GPL-2.0 for projects using | ||
that license", as Apache-2.0 and GPL-2.0 are generally understood to be | ||
incompatible. | ||
|
||
Because of this ambiguity, passing an array has been deprecated and will be | ||
removed in the future. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -600,8 +600,21 @@ def get_target_version(subproject: str) -> str: | |
def check_version(target_version: str, feature_version: str) -> bool: | ||
pass | ||
|
||
def use(self, subproject: 'SubProject', location: T.Optional['mparser.BaseNode'] = None) -> None: | ||
def use(self, subproject: 'SubProject', location: T.Optional['mparser.BaseNode'] = None, | ||
always_warn: bool = False) -> None: | ||
"""Generate a warning if necessary. | ||
|
||
:param subproject: The subproject this warning is for | ||
:param location: The location node that generated the warning, defaults to None | ||
:param always_warn: If set to True a warning is always generated. | ||
This is useful for cases where the deprecated behavior has always | ||
had a replacement, but we still wish to signal the version in which | ||
the behavior was deprecated. Defaults to False | ||
""" | ||
tv = self.get_target_version(subproject) | ||
if always_warn: | ||
self.log_usage_warning(tv, location, always=always_warn) | ||
return | ||
# No target version | ||
if tv == '': | ||
return | ||
|
@@ -618,8 +631,6 @@ def use(self, subproject: 'SubProject', location: T.Optional['mparser.BaseNode'] | |
feature_key = (self.feature_name, location) | ||
if feature_key in register[self.feature_version]: | ||
# Don't warn about the same feature multiple times | ||
# FIXME: This is needed to prevent duplicate warnings, but also | ||
# means we won't warn about a feature used in multiple places. | ||
return | ||
register[self.feature_version].add(feature_key) | ||
# Target version is new enough, don't warn even if it is registered for notice | ||
|
@@ -645,7 +656,8 @@ def report(cls, subproject: str) -> None: | |
if '\n' in warning_str: | ||
mlog.warning(warning_str) | ||
|
||
def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode']) -> None: | ||
def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode'], | ||
always: bool = False) -> None: | ||
raise InterpreterException('log_usage_warning not implemented') | ||
|
||
@staticmethod | ||
|
@@ -668,9 +680,10 @@ def wrapped(*wrapped_args: T.Any, **wrapped_kwargs: T.Any) -> T.Any: | |
|
||
@classmethod | ||
def single_use(cls, feature_name: str, version: str, subproject: 'SubProject', | ||
extra_message: str = '', location: T.Optional['mparser.BaseNode'] = None) -> None: | ||
extra_message: str = '', location: T.Optional['mparser.BaseNode'] = None, | ||
always_warn: bool = False) -> None: | ||
"""Oneline version that instantiates and calls use().""" | ||
cls(feature_name, version, extra_message).use(subproject, location) | ||
cls(feature_name, version, extra_message).use(subproject, location, always_warn) | ||
|
||
|
||
class FeatureNew(FeatureCheckBase): | ||
|
@@ -693,7 +706,9 @@ def get_warning_str_prefix(tv: str) -> str: | |
def get_notice_str_prefix(tv: str) -> str: | ||
return '' | ||
|
||
def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode']) -> None: | ||
def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode'], | ||
always: bool = False) -> None: | ||
assert not always, "Shouldn't be used with FeatureNew, only FeatureDeprecated" | ||
args = [ | ||
'Project targets', f"'{tv}'", | ||
'but uses feature introduced in', | ||
|
@@ -702,7 +717,7 @@ def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode']) - | |
] | ||
if self.extra_message: | ||
args.append(self.extra_message) | ||
mlog.warning(*args, location=location) | ||
mlog.warning(*args, location=location, fatal=not always) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should just be dropped. The default is True, but we're setting it to False iff it is an This means that a deprecation for something that is always deprecated and always wrong and always should be replaced... does NOT trigger --fatal-meson-warnings, even though it really should. |
||
|
||
class FeatureDeprecated(FeatureCheckBase): | ||
"""Checks for deprecated features""" | ||
|
@@ -726,16 +741,26 @@ def get_warning_str_prefix(tv: str) -> str: | |
def get_notice_str_prefix(tv: str) -> str: | ||
return 'Future-deprecated features used:' | ||
|
||
def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode']) -> None: | ||
args = [ | ||
'Project targets', f"'{tv}'", | ||
'but uses feature deprecated since', | ||
f"'{self.feature_version}':", | ||
f'{self.feature_name}.', | ||
] | ||
def log_usage_warning(self, tv: str, location: T.Optional['mparser.BaseNode'], | ||
always: bool = False) -> None: | ||
if always: | ||
args = [ | ||
'Project uses feature', | ||
self.feature_name, | ||
'which was deprecated in', | ||
f"'{self.feature_version}',", | ||
'and can safely be replaced without causing a regression.' | ||
] | ||
else: | ||
args = [ | ||
'Project targets', f"'{tv}'", | ||
'but uses feature deprecated since', | ||
f"'{self.feature_version}':", | ||
f'{self.feature_name}.', | ||
] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why we need 2 different messages here, what's wrong with the original one? Also it probably should be fatal when targeting Meson >=0.63 but since that's inside Sorry for nitpicking, maybe I'm just overthinking this simple PR tbh. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the normal message makes sense in this case, since you'd get a warning like: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that the dedicated warning message makes sense. However I also agree with @xclaesse that it seems weird to mark it as non-fatal, because if we always warn about it and can always use the better non-deprecated version of it, then we also do want it to trigger --fatal-meson-warnings. |
||
if self.extra_message: | ||
args.append(self.extra_message) | ||
mlog.warning(*args, location=location) | ||
mlog.warning(*args, location=location, fatal=not always) | ||
|
||
|
||
# This cannot be a dataclass due to https://github.com/python/mypy/issues/5374 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# The use of 0.52 is intentional, as the warning should always be triggered | ||
project('foo', meson_version : '>= 0.52', license : ['MIT', 'BSD2']) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"stdout": [ | ||
{ | ||
"line": "test cases/warning/7 deprecated project license array/meson.build:2: WARNING: Project uses feature project license as an array of strings which was deprecated in '0.63.0', and can safely be replaced without causing a regression. Use an SPDX license expression with AND and/or OR 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.
Good catch, but the actual fix was in 7a033c7.
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.
e.g. the discussion at #9488 (comment)