Skip to content

Commit 3c1f7ad

Browse files
committed
Refactor applies_to
1 parent 91c0ddc commit 3c1f7ad

File tree

6 files changed

+436
-342
lines changed

6 files changed

+436
-342
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Elastic.Documentation.AppliesTo;
6+
7+
namespace Elastic.Markdown.Myst.Components;
8+
9+
public record ApplicabilityItem(
10+
string Key,
11+
Applicability Applicability,
12+
ApplicabilityRenderer.ApplicabilityRenderData RenderData
13+
);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Elastic.Documentation.Configuration.Versions;
6+
7+
namespace Elastic.Markdown.Myst.Components;
8+
9+
public static class ApplicabilityMappings
10+
{
11+
public record ApplicabilityDefinition(string Key, string DisplayName, VersioningSystemId VersioningSystemId);
12+
13+
private static readonly Dictionary<string, ApplicabilityDefinition> Mappings = new()
14+
{
15+
// Stack
16+
["stack"] = new ApplicabilityDefinition("Stack", "Elastic&nbsp;Stack", VersioningSystemId.Stack),
17+
18+
// Serverless
19+
["serverless"] = new ApplicabilityDefinition("Serverless", "Elastic&nbsp;Cloud&nbsp;Serverless", VersioningSystemId.Serverless),
20+
["serverless-elasticsearch"] = new ApplicabilityDefinition("Serverless Elasticsearch", "Serverless&nbsp;Elasticsearch projects", VersioningSystemId.ElasticsearchProject),
21+
["serverless-observability"] = new ApplicabilityDefinition("Serverless Observability", "Serverless&nbsp;Observability projects", VersioningSystemId.ObservabilityProject),
22+
["serverless-security"] = new ApplicabilityDefinition("Serverless Security", "Serverless&nbsp;Security projects", VersioningSystemId.SecurityProject),
23+
24+
// Deployment
25+
["ech"] = new ApplicabilityDefinition("ECH", "Elastic&nbsp;Cloud&nbsp;Hosted", VersioningSystemId.Ess),
26+
["eck"] = new ApplicabilityDefinition("ECK", "Elastic&nbsp;Cloud&nbsp;on&nbsp;Kubernetes", VersioningSystemId.Eck),
27+
["ece"] = new ApplicabilityDefinition("ECE", "Elastic&nbsp;Cloud&nbsp;Enterprise", VersioningSystemId.Ece),
28+
["self"] = new ApplicabilityDefinition("Self-Managed", "Self-managed Elastic&nbsp;deployments", VersioningSystemId.Self),
29+
30+
// Product Applicability
31+
["ecctl"] = new ApplicabilityDefinition("ECCTL", "Elastic&nbsp;Cloud&nbsp;Control", VersioningSystemId.Ecctl),
32+
["curator"] = new ApplicabilityDefinition("Curator", "Curator", VersioningSystemId.Curator),
33+
34+
// EDOT Products
35+
["edot-android"] = new ApplicabilityDefinition("EDOT Android", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;Android", VersioningSystemId.EdotAndroid),
36+
["edot-cf-aws"] = new ApplicabilityDefinition("EDOT CF AWS", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;Cloud&nbsp;Forwarder for AWS", VersioningSystemId.EdotCfAws),
37+
["edot-collector"] = new ApplicabilityDefinition("EDOT Collector", "Elastic Distribution of OpenTelemetry Collector", VersioningSystemId.EdotCollector),
38+
["edot-dotnet"] = new ApplicabilityDefinition("EDOT .NET", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;.NET", VersioningSystemId.EdotDotnet),
39+
["edot-ios"] = new ApplicabilityDefinition("EDOT iOS", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;iOS", VersioningSystemId.EdotIos),
40+
["edot-java"] = new ApplicabilityDefinition("EDOT Java", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;Java", VersioningSystemId.EdotJava),
41+
["edot-node"] = new ApplicabilityDefinition("EDOT Node.js", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;Node.js", VersioningSystemId.EdotNode),
42+
["edot-php"] = new ApplicabilityDefinition("EDOT PHP", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;PHP", VersioningSystemId.ApmAgentPhp),
43+
["edot-python"] = new ApplicabilityDefinition("EDOT Python", "Elastic&nbsp;Distribution of OpenTelemetry&nbsp;Python", VersioningSystemId.EdotPython),
44+
45+
// APM Agents
46+
["apm-agent-android"] = new ApplicabilityDefinition("APM Agent Android", "Application&nbsp;Performance&nbsp;Monitoring Agent for Android", VersioningSystemId.ApmAgentAndroid),
47+
["apm-agent-dotnet"] = new ApplicabilityDefinition("APM Agent .NET", "Application&nbsp;Performance&nbsp;Monitoring Agent for .NET", VersioningSystemId.ApmAgentDotnet),
48+
["apm-agent-go"] = new ApplicabilityDefinition("APM Agent Go", "Application&nbsp;Performance&nbsp;Monitoring Agent for Go", VersioningSystemId.ApmAgentGo),
49+
["apm-agent-ios"] = new ApplicabilityDefinition("APM Agent iOS", "Application&nbsp;Performance&nbsp;Monitoring Agent for iOS", VersioningSystemId.ApmAgentIos),
50+
["apm-agent-java"] = new ApplicabilityDefinition("APM Agent Java", "Application&nbsp;Performance&nbsp;Monitoring Agent for Java", VersioningSystemId.ApmAgentJava),
51+
["apm-agent-node"] = new ApplicabilityDefinition("APM Agent Node.js", "Application&nbsp;Performance&nbsp;Monitoring Agent for Node.js", VersioningSystemId.ApmAgentNode),
52+
["apm-agent-php"] = new ApplicabilityDefinition("APM Agent PHP", "Application&nbsp;Performance&nbsp;Monitoring Agent for PHP", VersioningSystemId.ApmAgentPhp),
53+
["apm-agent-python"] = new ApplicabilityDefinition("APM Agent Python", "Application&nbsp;Performance&nbsp;Monitoring Agent for Python", VersioningSystemId.ApmAgentPython),
54+
["apm-agent-ruby"] = new ApplicabilityDefinition("APM Agent Ruby", "Application&nbsp;Performance&nbsp;Monitoring Agent for Ruby", VersioningSystemId.ApmAgentRuby),
55+
["apm-agent-rum"] = new ApplicabilityDefinition("APM Agent RUM", "Application&nbsp;Performance&nbsp;Monitoring Agent for Real&nbsp;User&nbsp;Monitoring", VersioningSystemId.ApmAgentRum),
56+
57+
// Generic product
58+
["product"] = new ApplicabilityDefinition("", "", VersioningSystemId.All)
59+
};
60+
61+
public static ApplicabilityDefinition GetProductDefinition(string productKey) => Mappings.TryGetValue(productKey, out var definition)
62+
? definition
63+
: throw new ArgumentException($"Unknown product key: {productKey}");
64+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Diagnostics.CodeAnalysis;
6+
using Elastic.Documentation;
7+
using Elastic.Documentation.AppliesTo;
8+
using Elastic.Documentation.Configuration.Versions;
9+
10+
namespace Elastic.Markdown.Myst.Components;
11+
12+
public class ApplicabilityRenderer
13+
{
14+
public record ApplicabilityRenderData(
15+
string BadgeText,
16+
string Version,
17+
string TooltipText,
18+
string LifecycleClass,
19+
bool ShowLifecycle,
20+
bool ShowVersion
21+
);
22+
23+
public ApplicabilityRenderData RenderApplicability(
24+
Applicability applicability,
25+
ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition,
26+
VersioningSystem versioningSystem,
27+
AppliesCollection allApplications)
28+
{
29+
var lifecycleClass = applicability.GetLifeCycleName().ToLowerInvariant().Replace(" ", "-");
30+
var lifecycleFull = GetLifecycleFullText(applicability.Lifecycle);
31+
var realVersion = TryGetRealVersion(applicability, out var v) ? v : null;
32+
33+
var tooltipText = BuildTooltipText(applicability, applicabilityDefinition, versioningSystem, realVersion, lifecycleFull);
34+
var badgeText = BuildBadgeText(applicability, applicabilityDefinition, versioningSystem, realVersion, allApplications);
35+
var badgeTextChanged = badgeText != applicabilityDefinition.Key;
36+
37+
var showLifecycle = applicability.Lifecycle != ProductLifecycle.GenerallyAvailable && !badgeTextChanged;
38+
var showVersion = applicability.Version is not null and not AllVersions;
39+
40+
var version = showVersion && versioningSystem.Current >= applicability.Version!
41+
? applicability.Version!.ToString()
42+
: badgeText;
43+
44+
return new ApplicabilityRenderData(
45+
BadgeText: badgeText,
46+
Version: version,
47+
TooltipText: tooltipText,
48+
LifecycleClass: lifecycleClass,
49+
ShowLifecycle: showLifecycle,
50+
ShowVersion: showVersion
51+
);
52+
}
53+
54+
private static string GetLifecycleFullText(ProductLifecycle lifecycle) => lifecycle switch
55+
{
56+
ProductLifecycle.GenerallyAvailable => "Available",
57+
ProductLifecycle.Beta => "Available in beta",
58+
ProductLifecycle.TechnicalPreview => "Available in technical preview",
59+
ProductLifecycle.Deprecated => "Deprecated",
60+
ProductLifecycle.Removed => "Removed",
61+
ProductLifecycle.Unavailable => "Not available",
62+
_ => ""
63+
};
64+
65+
private static string BuildTooltipText(
66+
Applicability applicability,
67+
ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition,
68+
VersioningSystem versioningSystem,
69+
SemVersion? realVersion,
70+
string lifecycleFull)
71+
{
72+
var tooltipText = "";
73+
74+
tooltipText = realVersion is not null
75+
? realVersion <= versioningSystem.Current
76+
? $"{lifecycleFull} on {applicabilityDefinition.DisplayName} version {realVersion} and later unless otherwise specified."
77+
: applicability.Lifecycle switch
78+
{
79+
ProductLifecycle.GenerallyAvailable
80+
or ProductLifecycle.Beta
81+
or ProductLifecycle.TechnicalPreview
82+
or ProductLifecycle.Planned =>
83+
$"We plan to add this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.",
84+
ProductLifecycle.Deprecated => $"We plan to deprecate this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.",
85+
ProductLifecycle.Removed => $"We plan to remove this functionality in a future {applicabilityDefinition.DisplayName} update. Subject to change.",
86+
_ => tooltipText
87+
}
88+
: $"{lifecycleFull} on {applicabilityDefinition.DisplayName} unless otherwise specified.";
89+
90+
var disclaimer = GetDisclaimer(applicability.Lifecycle, versioningSystem.Id);
91+
if (disclaimer is not null)
92+
tooltipText = $"{tooltipText}\n\n{disclaimer}";
93+
94+
return tooltipText;
95+
}
96+
97+
private static string? GetDisclaimer(ProductLifecycle lifecycle, VersioningSystemId versioningSystemId) => lifecycle switch
98+
{
99+
ProductLifecycle.Beta => "Beta features are subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features.",
100+
ProductLifecycle.TechnicalPreview => "This functionality may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.",
101+
ProductLifecycle.GenerallyAvailable => versioningSystemId is VersioningSystemId.Stack
102+
? "If this functionality is unavailable or behaves differently when deployed on ECH, ECE, ECK, or a self-managed installation, it will be indicated on the page."
103+
: null,
104+
_ => null
105+
};
106+
107+
private static string BuildBadgeText(
108+
Applicability applicability,
109+
ApplicabilityMappings.ApplicabilityDefinition applicabilityDefinition,
110+
VersioningSystem versioningSystem,
111+
SemVersion? realVersion,
112+
AppliesCollection allApplications)
113+
{
114+
var badgeText = applicabilityDefinition.Key;
115+
116+
if (realVersion is not null && realVersion > versioningSystem.Current)
117+
{
118+
badgeText = applicability.Lifecycle switch
119+
{
120+
ProductLifecycle.TechnicalPreview => "Planned",
121+
ProductLifecycle.Beta => "Planned",
122+
ProductLifecycle.GenerallyAvailable =>
123+
allApplications.Any(a => a.Lifecycle is ProductLifecycle.TechnicalPreview or ProductLifecycle.Beta)
124+
? "GA planned"
125+
: "Planned",
126+
ProductLifecycle.Deprecated => "Deprecation planned",
127+
ProductLifecycle.Removed => "Removal planned",
128+
ProductLifecycle.Planned => "Planned",
129+
_ => badgeText
130+
};
131+
}
132+
133+
return badgeText;
134+
}
135+
136+
private static bool TryGetRealVersion(Applicability applicability, [NotNullWhen(true)] out SemVersion? version)
137+
{
138+
version = null;
139+
if (applicability.Version is not null && applicability.Version != AllVersions.Instance)
140+
{
141+
version = applicability.Version;
142+
return true;
143+
}
144+
145+
return false;
146+
}
147+
}

0 commit comments

Comments
 (0)