Skip to content

Commit

Permalink
Make stability and deprecation independent properties (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
lmolkova authored Feb 14, 2024
1 parent f8b934b commit 974d6d0
Show file tree
Hide file tree
Showing 16 changed files with 120 additions and 168 deletions.
5 changes: 4 additions & 1 deletion semantic-conventions/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Please update the changelog as part of any significant pull request.

## Unreleased

- BREAKING: Make stability and deprecation independent properties.
([#244](https://github.com/open-telemetry/build-tools/pull/244))

## v0.23.0

- Rephrase and relax sampling-relevant description
Expand All @@ -17,7 +20,7 @@ Please update the changelog as part of any significant pull request.
([#205](https://github.com/open-telemetry/build-tools/pull/205))
- Fix referencing template attributes
([#206](https://github.com/open-telemetry/build-tools/pull/206))

## v0.21.0

- Render template-type attributes from yaml files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ class RequirementLevel(Enum):
class StabilityLevel(Enum):
STABLE = 1
EXPERIMENTAL = 2
DEPRECATED = 3


@dataclass
Expand Down Expand Up @@ -82,9 +81,7 @@ def is_enum(self):
return isinstance(self.attr_type, EnumAttributeType)

@staticmethod
def parse(
prefix, semconv_stability, yaml_attributes
) -> "Dict[str, SemanticAttribute]":
def parse(prefix, yaml_attributes) -> "Dict[str, SemanticAttribute]":
"""This method parses the yaml representation for semantic attributes
creating the respective SemanticAttribute objects.
"""
Expand Down Expand Up @@ -179,21 +176,13 @@ def parse(
raise ValidationError.from_yaml_pos(position, msg)

tag = attribute.get("tag", "").strip()
stability, deprecated = SemanticAttribute.parse_stability_deprecated(
attribute.get("stability"), attribute.get("deprecated"), position_data
stability = SemanticAttribute.parse_stability(
attribute.get("stability"), position_data
)
if (
semconv_stability == StabilityLevel.DEPRECATED
and stability is not StabilityLevel.DEPRECATED
):
position = (
position_data["stability"]
if "stability" in position_data
else position_data["deprecated"]
)
msg = f"Semantic convention stability set to deprecated but attribute '{attr_id}' is {stability}"
raise ValidationError.from_yaml_pos(position, msg)
stability = stability or semconv_stability or StabilityLevel.EXPERIMENTAL
deprecated = SemanticAttribute.parse_deprecated(
attribute.get("deprecated"), position_data
)

sampling_relevant = (
AttributeType.to_bool("sampling_relevant", attribute)
if attribute.get("sampling_relevant")
Expand Down Expand Up @@ -291,44 +280,31 @@ def parse_attribute(attribute):
return attr_type, str(brief), examples

@staticmethod
def parse_stability_deprecated(stability, deprecated, position_data):
if deprecated is not None and stability is None:
stability = "deprecated"
if deprecated is not None:
if stability is not None and stability != "deprecated":
position = position_data["deprecated"]
msg = f"There is a deprecation message but the stability is set to '{stability}'"
raise ValidationError.from_yaml_pos(position, msg)
if AttributeType.get_type(deprecated) != "string" or deprecated == "":
position = position_data["deprecated"]
msg = (
"Deprecated field expects a string that specifies why the attribute is deprecated and/or what"
" to use instead! "
)
raise ValidationError.from_yaml_pos(position, msg)
deprecated = deprecated.strip()
if stability is not None:
stability = SemanticAttribute.check_stability(
stability,
position_data["stability"]
if "stability" in position_data
else position_data["deprecated"],
)
return stability, deprecated

@staticmethod
def check_stability(stability_value, position):
def parse_stability(stability, position_data):
if stability is None:
return StabilityLevel.EXPERIMENTAL

stability_value_map = {
"deprecated": StabilityLevel.DEPRECATED,
"experimental": StabilityLevel.EXPERIMENTAL,
"stable": StabilityLevel.STABLE,
}
val = stability_value_map.get(stability_value)
val = stability_value_map.get(stability)
if val is not None:
return val
msg = f"Value '{stability_value}' is not allowed as a stability marker"
raise ValidationError.from_yaml_pos(position, msg)
msg = f"Value '{stability}' is not allowed as a stability marker"
raise ValidationError.from_yaml_pos(position_data["stability"], msg)

@staticmethod
def parse_deprecated(deprecated, position_data):
if deprecated is not None:
if AttributeType.get_type(deprecated) != "string" or deprecated == "":
msg = (
"Deprecated field expects a string that specifies why the attribute is deprecated and/or what"
" to use instead! "
)
raise ValidationError.from_yaml_pos(position_data["deprecated"], msg)
return deprecated.strip()
return None

def equivalent_to(self, other: "SemanticAttribute"):
if self.attr_id is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,18 @@ def __init__(self, group):
self.semconv_id = self.id
self.note = group.get("note", "").strip()
self.prefix = group.get("prefix", "").strip()
stability = group.get("stability")
deprecated = group.get("deprecated")
position_data = group.lc.data
self.stability, self.deprecated = SemanticAttribute.parse_stability_deprecated(
stability, deprecated, position_data
self.stability = SemanticAttribute.parse_stability(
group.get("stability"), position_data
)
self.deprecated = SemanticAttribute.parse_deprecated(
group.get("deprecated"), position_data
)
self.extends = group.get("extends", "").strip()
self.events = group.get("events", ())
self.constraints = parse_constraints(group.get("constraints", ()))
self.attrs_by_name = SemanticAttribute.parse(
self.prefix, self.stability, group.get("attributes")
self.prefix, group.get("attributes")
)

def contains_attribute(self, attr: "SemanticAttribute"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@

from opentelemetry.semconv.model.semantic_attribute import (
RequirementLevel,
SemanticAttribute,
TextWithLinks,
)
from opentelemetry.semconv.model.semantic_convention import SemanticConventionSet
from opentelemetry.semconv.model.semantic_convention import (
BaseSemanticConvention,
SemanticConventionSet,
)
from opentelemetry.semconv.model.utils import ID_RE


Expand Down Expand Up @@ -156,6 +160,10 @@ def to_camelcase(name: str, first_upper=False) -> str:
return first + "".join(word.capitalize() for word in rest)


def is_deprecated(obj: typing.Union[SemanticAttribute, BaseSemanticConvention]) -> bool:
return obj.deprecated is not None


class CodeRenderer:
pattern = f"{{{ID_RE.pattern}}}"

Expand Down Expand Up @@ -209,6 +217,8 @@ def setup_environment(env: Environment, trim_whitespace: bool):
env.filters["to_html_links"] = to_html_links
env.filters["regex_replace"] = regex_replace
env.filters["render_markdown"] = render_markdown
env.filters["is_deprecated"] = is_deprecated
env.tests["is_deprecated"] = is_deprecated
env.trim_blocks = trim_whitespace
env.lstrip_blocks = trim_whitespace

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,19 @@ def to_markdown_attr(
if "deprecated" in attribute.deprecated.lower():
description = f"**{attribute.deprecated}**<br>"
else:
deprecated_msg = self.options.md_snippet_by_stability_level[
StabilityLevel.DEPRECATED
].format(attribute.deprecated)
deprecated_msg = self.options.deprecated_md_snippet().format(
attribute.deprecated
)
description = f"{deprecated_msg}<br>"
elif (
attribute.stability == StabilityLevel.STABLE and self.options.enable_stable
):
description = f"{self.options.md_snippet_by_stability_level[StabilityLevel.STABLE]}<br>"
description = f"{self.options.stable_md_snippet()}<br>"
elif (
attribute.stability == StabilityLevel.EXPERIMENTAL
and self.options.enable_experimental
):
description = f"{self.options.md_snippet_by_stability_level[StabilityLevel.EXPERIMENTAL]}<br>"
description = f"{self.options.experimental_md_snippet()}<br>"
description += attribute.brief
if attribute.note:
self.render_ctx.add_note(attribute.note)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,9 @@
from dataclasses import dataclass, field
from typing import List

from opentelemetry.semconv.model.semantic_attribute import StabilityLevel


@dataclass()
class MarkdownOptions:

_badge_map = {
StabilityLevel.DEPRECATED: "![Deprecated](https://img.shields.io/badge/-deprecated-red)",
StabilityLevel.EXPERIMENTAL: "![Experimental](https://img.shields.io/badge/-experimental-blue)",
StabilityLevel.STABLE: "![Stable](https://img.shields.io/badge/-stable-lightgreen)",
}

_label_map = {
StabilityLevel.DEPRECATED: "**Deprecated: {}**",
StabilityLevel.EXPERIMENTAL: "**Experimental**",
StabilityLevel.STABLE: "**Stable**",
}

check_only: bool = False
enable_stable: bool = False
enable_experimental: bool = False
Expand All @@ -41,8 +26,17 @@ class MarkdownOptions:
break_count: int = 50
exclude_files: List[str] = field(default_factory=list)

@property
def md_snippet_by_stability_level(self):
def stable_md_snippet(self):
if self.use_badge:
return "![Stable](https://img.shields.io/badge/-stable-lightgreen)"
return "**Stable**"

def experimental_md_snippet(self):
if self.use_badge:
return "![Experimental](https://img.shields.io/badge/-experimental-blue)"
return "**Experimental**"

def deprecated_md_snippet(self):
if self.use_badge:
return self._badge_map
return self._label_map
return "![Deprecated](https://img.shields.io/badge/-deprecated-red)"
return "**Deprecated: {}**"
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ class AttributesTemplate {
* <p>Notes:
<ul> {{attribute_template.note | render_markdown(code="{{@code {0}}}", paragraph="<li>{0}</li>", list="{0}")}} </ul>
{%- endif %}
{%- if (attribute_template.stability | string()) == "StabilityLevel.DEPRECATED" %}
{%- if attribute_template | is_deprecated %}
*
* @deprecated {{attribute_template.brief | to_doc_brief}}.
{%- endif %}
*/
{%- if (attribute_template.stability | string()) == "StabilityLevel.DEPRECATED" %}
{%- if attribute_template | is_deprecated %}
@Deprecated
{%- endif %}
public static final AttributeKey<{{upFirst(to_java_return_type(attribute_template.instantiated_type | string))}}> {{attribute_template.fqn | to_const_name}} = {{to_java_key_type(attribute_template.instantiated_type | string)}}("{{attribute_template.fqn}}");
Expand All @@ -68,12 +68,12 @@ class AttributesTemplate {
* <p>Notes:
<ul> {{attribute.note | render_markdown(code="{{@code {0}}}", paragraph="<li>{0}</li>", list="{0}")}} </ul>
{%- endif %}
{%- if (attribute.stability | string()) == "StabilityLevel.DEPRECATED" %}
{%- if attribute | is_deprecated %}
*
* @deprecated {{attribute.brief | to_doc_brief}}.
{%- endif %}
*/
{%- if (attribute.stability | string()) == "StabilityLevel.DEPRECATED" %}
{%- if attribute | is_deprecated %}
@Deprecated
{%- endif %}
public static final AttributeKey<{{upFirst(to_java_return_type(attribute.instantiated_type | string))}}> {{attribute.fqn | to_const_name}} = {{to_java_key_type(attribute.instantiated_type | string)}}("{{attribute.fqn}}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
| Attribute | Type | Description | Examples | Requirement Level |
|---|---|---|---|---|
| [`test.def_stability`](labels_expected.md) | boolean | | | Required |
| [`test.deprecated_attr`](labels_expected.md) | boolean | | | Required |
| [`test.deprecated_attr`](labels_expected.md) | boolean | ![Deprecated](https://img.shields.io/badge/-deprecated-red)<br> | | Required |
| [`test.exp_attr`](labels_expected.md) | boolean | | | Required |
| [`test.stable_attr`](labels_expected.md) | boolean | ![Stable](https://img.shields.io/badge/-stable-lightgreen)<br> | | Required |
<!-- endsemconv -->
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
| Attribute | Type | Description | Examples | Requirement Level |
|---|---|---|---|---|
| [`test.def_stability`](labels_expected.md) | boolean | | | Required |
| [`test.deprecated_attr`](labels_expected.md) | boolean | | | Required |
| [`test.deprecated_attr`](labels_expected.md) | boolean | **Deprecated: Removed.**<br> | | Required |
| [`test.exp_attr`](labels_expected.md) | boolean | | | Required |
| [`test.stable_attr`](labels_expected.md) | boolean | | | Required |
<!-- endsemconv -->
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ groups:
- id: deprecated_attr
type: boolean
requirement_level: required
stability: deprecated
stability: stable
deprecated: "Removed."
brief: ""
- id: def_stability
type: boolean
Expand Down

This file was deleted.

Loading

0 comments on commit 974d6d0

Please sign in to comment.