On 3/15/20 3:46 PM, Markus Armbruster wrote:
> Unlike regular feature flags, the new special feature flag
> "deprecated" is recognized by the QAPI generator. For now, it's only
> permitted with commands, events, and struct members. It will be put
> to use shortly.
What about using a '@DeprecatedSince' tag?
Ah, that would apply to the whole structure and not a particular member...
I am wondering because sometimes we deprecate something for 2 releases
but then once the deadline passed we forgot to remove it. Having the
release version deadline along with deprecation would help automating
removal checks.
Maybe we can use a tag with release version, such 'deprecated_since:5.0'?
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>
> ---
> docs/devel/qapi-code-gen.txt | 6 ++++++
> scripts/qapi/schema.py | 6 ++++++
> tests/Makefile.include | 1 +
> tests/qapi-schema/features-deprecated-type.err | 2 ++
> tests/qapi-schema/features-deprecated-type.json | 3 +++
> tests/qapi-schema/features-deprecated-type.out | 0
> tests/qapi-schema/qapi-schema-test.json | 6 +++---
> tests/qapi-schema/qapi-schema-test.out | 6 +++---
> 8 files changed, 24 insertions(+), 6 deletions(-)
> create mode 100644 tests/qapi-schema/features-deprecated-type.err
> create mode 100644 tests/qapi-schema/features-deprecated-type.json
> create mode 100644 tests/qapi-schema/features-deprecated-type.out
>
> diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
> index a1ef1cfd61..823adbabda 100644
> --- a/docs/devel/qapi-code-gen.txt
> +++ b/docs/devel/qapi-code-gen.txt
> @@ -683,6 +683,12 @@ Intended use is to have each feature string signal that this build of
> QEMU shows a certain behaviour.
>
>
> +==== Special features ====
> +
> +Feature "deprecated" makes a command, event, or struct member as
> +deprecated. It is not supported elsewhere so far.
> +
> +
> === Naming rules and reserved names ===
>
> All names must begin with a letter, and contain only ASCII letters,
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index 6ee3677215..78309a00f0 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -193,6 +193,12 @@ class QAPISchemaType(QAPISchemaEntity):
> return None
> return self.name
>
> + def check(self, schema):
> + QAPISchemaEntity.check(self, schema)
> + if 'deprecated' in [f.name for f in self.features]:
> + raise QAPISemError(
> + self.info, "feature 'deprecated' is not supported for types")
> +
> def describe(self):
> assert self.meta
> return "%s type '%s'" % (self.meta, self.name)
> diff --git a/tests/Makefile.include b/tests/Makefile.include
> index 67e8fcddda..d1340301b2 100644
> --- a/tests/Makefile.include
> +++ b/tests/Makefile.include
> @@ -242,6 +242,7 @@ qapi-schema += event-case.json
> qapi-schema += event-member-invalid-dict.json
> qapi-schema += event-nest-struct.json
> qapi-schema += features-bad-type.json
> +qapi-schema += features-deprecated-type.json
> qapi-schema += features-duplicate-name.json
> qapi-schema += features-if-invalid.json
> qapi-schema += features-missing-name.json
> diff --git a/tests/qapi-schema/features-deprecated-type.err b/tests/qapi-schema/features-deprecated-type.err
> new file mode 100644
> index 0000000000..af4ffe20aa
> --- /dev/null
> +++ b/tests/qapi-schema/features-deprecated-type.err
> @@ -0,0 +1,2 @@
> +features-deprecated-type.json: In struct 'S':
> +features-deprecated-type.json:2: feature 'deprecated' is not supported for types
> diff --git a/tests/qapi-schema/features-deprecated-type.json b/tests/qapi-schema/features-deprecated-type.json
> new file mode 100644
> index 0000000000..4b5bf5b86e
> --- /dev/null
> +++ b/tests/qapi-schema/features-deprecated-type.json
> @@ -0,0 +1,3 @@
> +# Feature 'deprecated' is not supported for types
> +{ 'struct': 'S', 'data': {},
> + 'features': [ 'deprecated' ] }
> diff --git a/tests/qapi-schema/features-deprecated-type.out b/tests/qapi-schema/features-deprecated-type.out
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
> index f576c337af..6b1f05afa7 100644
> --- a/tests/qapi-schema/qapi-schema-test.json
> +++ b/tests/qapi-schema/qapi-schema-test.json
> @@ -258,7 +258,7 @@
> 'data': { 'foo': 'int' },
> 'features': [] }
> { 'struct': 'FeatureStruct1',
> - 'data': { 'foo': { 'type': 'int', 'features': [ 'member-feature1' ] } },
> + 'data': { 'foo': { 'type': 'int', 'features': [ 'deprecated' ] } },
> 'features': [ 'feature1' ] }
> { 'struct': 'FeatureStruct2',
> 'data': { 'foo': 'int' },
> @@ -308,7 +308,7 @@
> 'features': [] }
>
> { 'command': 'test-command-features1',
> - 'features': [ 'feature1' ] }
> + 'features': [ 'deprecated' ] }
> { 'command': 'test-command-features3',
> 'features': [ 'feature1', 'feature2' ] }
>
> @@ -322,4 +322,4 @@
> 'defined(TEST_IF_COND_2)'] } ] }
>
> { 'event': 'TEST-EVENT-FEATURES1',
> - 'features': [ 'feature1' ] }
> + 'features': [ 'deprecated' ] }
> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
> index cd863ae966..891b4101e0 100644
> --- a/tests/qapi-schema/qapi-schema-test.out
> +++ b/tests/qapi-schema/qapi-schema-test.out
> @@ -359,7 +359,7 @@ object FeatureStruct0
> member foo: int optional=False
> object FeatureStruct1
> member foo: int optional=False
> - feature member-feature1
> + feature deprecated
> feature feature1
> object FeatureStruct2
> member foo: int optional=False
> @@ -419,7 +419,7 @@ command test-features0 q_obj_test-features0-arg -> None
> gen=True success_response=True boxed=False oob=False preconfig=False
> command test-command-features1 None -> None
> gen=True success_response=True boxed=False oob=False preconfig=False
> - feature feature1
> + feature deprecated
> command test-command-features3 None -> None
> gen=True success_response=True boxed=False oob=False preconfig=False
> feature feature1
> @@ -440,7 +440,7 @@ command test-command-cond-features3 None -> None
> if ['defined(TEST_IF_COND_1)', 'defined(TEST_IF_COND_2)']
> event TEST-EVENT-FEATURES1 None
> boxed=False
> - feature feature1
> + feature deprecated
> module include/sub-module.json
> include sub-sub-module.json
> object SecondArrayRef
>