-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial support for page level annotations for product support (#103
- Loading branch information
Showing
18 changed files
with
605 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
--- | ||
title: Product Availability | ||
applies: | ||
stack: ga 8.1 | ||
serverless: tech-preview | ||
hosted: beta 8.1.1 | ||
eck: beta 3.0.2 | ||
ece: unavailable | ||
--- | ||
|
||
|
||
Using yaml frontmatter pages can explicitly indicate to each deployment targets availability and lifecycle status | ||
|
||
|
||
```yaml | ||
applies: | ||
stack: ga 8.1 | ||
serverless: tech-preview | ||
hosted: beta 8.1.1 | ||
eck: beta 3.0.2 | ||
ece: unavailable | ||
``` | ||
Its syntax is | ||
``` | ||
<product>: <lifecycle> [version] | ||
``` | ||
Where version is optional. | ||
`all` and empty string mean generally available for all active versions | ||
|
||
```yaml | ||
applies: | ||
stack: | ||
serverless: all | ||
``` | ||
|
||
`all` and empty string can also be specified at a version level | ||
|
||
```yaml | ||
applies: | ||
stack: beta all | ||
serverless: beta | ||
``` | ||
|
||
Are equivalent, note `all` just means we won't be rendering the version portion in the html. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Licensed to Elasticsearch B.V under one or more agreements. | ||
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. | ||
// See the LICENSE file in the project root for more information | ||
|
||
using Elastic.Markdown.Helpers; | ||
using YamlDotNet.Core; | ||
using YamlDotNet.Core.Events; | ||
using YamlDotNet.Serialization; | ||
|
||
namespace Elastic.Markdown.Myst.FrontMatter; | ||
|
||
public class AllVersions() : SemVersion(9999, 9999, 9999) | ||
{ | ||
public static AllVersions Instance { get; } = new (); | ||
} | ||
|
||
public class SemVersionConverter : IYamlTypeConverter | ||
{ | ||
public bool Accepts(Type type) => type == typeof(SemVersion); | ||
|
||
public object? ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) | ||
{ | ||
var value = parser.Consume<Scalar>(); | ||
if (string.IsNullOrWhiteSpace(value.Value)) | ||
return AllVersions.Instance; | ||
if (string.Equals(value.Value.Trim(), "all", StringComparison.InvariantCultureIgnoreCase)) | ||
return AllVersions.Instance; | ||
return (SemVersion)value.Value; | ||
} | ||
|
||
public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) | ||
{ | ||
if (value == null) | ||
return; | ||
emitter.Emit(new Scalar(value.ToString()!)); | ||
} | ||
|
||
public static bool TryParse(string? value, out SemVersion? version) | ||
{ | ||
version = value?.Trim().ToLowerInvariant() switch | ||
{ | ||
null => AllVersions.Instance, | ||
"all" => AllVersions.Instance, | ||
"" => AllVersions.Instance, | ||
_ => SemVersion.TryParse(value, out var v) ? v : SemVersion.TryParse(value + ".0", out v) ? v : null | ||
}; | ||
return version is not null; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// Licensed to Elasticsearch B.V under one or more agreements. | ||
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. | ||
// See the LICENSE file in the project root for more information | ||
|
||
using YamlDotNet.Core; | ||
using YamlDotNet.Core.Events; | ||
using YamlDotNet.Serialization; | ||
|
||
namespace Elastic.Markdown.Myst.FrontMatter; | ||
|
||
[YamlSerializable] | ||
public record Deployment | ||
{ | ||
[YamlMember(Alias = "self")] | ||
public SelfManagedDeployment? SelfManaged { get; set; } | ||
|
||
[YamlMember(Alias = "cloud")] | ||
public CloudManagedDeployment? Cloud { get; set; } | ||
|
||
public static Deployment All { get; } = new() | ||
{ | ||
Cloud = CloudManagedDeployment.All, | ||
SelfManaged = SelfManagedDeployment.All | ||
}; | ||
} | ||
|
||
[YamlSerializable] | ||
public record SelfManagedDeployment | ||
{ | ||
[YamlMember(Alias = "stack")] | ||
public ProductAvailability? Stack { get; set; } | ||
|
||
[YamlMember(Alias = "ece")] | ||
public ProductAvailability? Ece { get; set; } | ||
|
||
[YamlMember(Alias = "eck")] | ||
public ProductAvailability? Eck { get; set; } | ||
|
||
public static SelfManagedDeployment All { get; } = new() | ||
{ | ||
Stack = ProductAvailability.GenerallyAvailable, | ||
Ece = ProductAvailability.GenerallyAvailable, | ||
Eck = ProductAvailability.GenerallyAvailable | ||
}; | ||
} | ||
|
||
[YamlSerializable] | ||
public record CloudManagedDeployment | ||
{ | ||
[YamlMember(Alias = "hosted")] | ||
public ProductAvailability? Hosted { get; set; } | ||
|
||
[YamlMember(Alias = "serverless")] | ||
public ProductAvailability? Serverless { get; set; } | ||
|
||
public static CloudManagedDeployment All { get; } = new() | ||
{ | ||
Hosted = ProductAvailability.GenerallyAvailable, | ||
Serverless = ProductAvailability.GenerallyAvailable | ||
}; | ||
|
||
} | ||
|
||
public class DeploymentConverter : IYamlTypeConverter | ||
{ | ||
public bool Accepts(Type type) => type == typeof(Deployment); | ||
|
||
public object? ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer) | ||
{ | ||
if (parser.TryConsume<Scalar>(out var value)) | ||
{ | ||
if (string.IsNullOrWhiteSpace(value.Value)) | ||
return Deployment.All; | ||
if (string.Equals(value.Value, "all", StringComparison.InvariantCultureIgnoreCase)) | ||
return Deployment.All; | ||
} | ||
var x = rootDeserializer.Invoke(typeof(Dictionary<string, string>)); | ||
if (x is not Dictionary<string, string> { Count: > 0 } dictionary) | ||
return null; | ||
|
||
var deployment = new Deployment(); | ||
|
||
if (TryGetVersion("stack", out var version)) | ||
{ | ||
deployment.SelfManaged ??= new SelfManagedDeployment(); | ||
deployment.SelfManaged.Stack = version; | ||
} | ||
if (TryGetVersion("ece", out version)) | ||
{ | ||
deployment.SelfManaged ??= new SelfManagedDeployment(); | ||
deployment.SelfManaged.Ece = version; | ||
} | ||
if (TryGetVersion("eck", out version)) | ||
{ | ||
deployment.SelfManaged ??= new SelfManagedDeployment(); | ||
deployment.SelfManaged.Eck = version; | ||
} | ||
if (TryGetVersion("hosted", out version)) | ||
{ | ||
deployment.Cloud ??= new CloudManagedDeployment(); | ||
deployment.Cloud.Hosted = version; | ||
} | ||
if (TryGetVersion("serverless", out version)) | ||
{ | ||
deployment.Cloud ??= new CloudManagedDeployment(); | ||
deployment.Cloud.Serverless = version; | ||
} | ||
return deployment; | ||
|
||
bool TryGetVersion(string key, out ProductAvailability? semVersion) | ||
{ | ||
semVersion = null; | ||
return dictionary.TryGetValue(key, out var v) && ProductAvailability.TryParse(v, out semVersion); | ||
} | ||
|
||
} | ||
|
||
public void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer) => | ||
serializer.Invoke(value, type); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/Elastic.Markdown/Myst/FrontMatter/ProductAvailability.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Licensed to Elasticsearch B.V under one or more agreements. | ||
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. | ||
// See the LICENSE file in the project root for more information | ||
|
||
using Elastic.Markdown.Helpers; | ||
using YamlDotNet.Serialization; | ||
|
||
namespace Elastic.Markdown.Myst.FrontMatter; | ||
|
||
[YamlSerializable] | ||
public record ProductAvailability | ||
{ | ||
public ProductLifecycle Lifecycle { get; init; } | ||
public SemVersion? Version { get; init; } | ||
|
||
public static ProductAvailability GenerallyAvailable { get; } = new() | ||
{ | ||
Lifecycle = ProductLifecycle.GenerallyAvailable, Version = AllVersions.Instance | ||
}; | ||
|
||
// <lifecycle> [version] | ||
public static bool TryParse(string? value, out ProductAvailability? availability) | ||
{ | ||
if (string.IsNullOrWhiteSpace(value) || string.Equals(value.Trim(), "all", StringComparison.InvariantCultureIgnoreCase)) | ||
{ | ||
availability = GenerallyAvailable; | ||
return true; | ||
} | ||
|
||
var tokens = value.Split(" ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries); | ||
if (tokens.Length < 1) | ||
{ | ||
availability = null; | ||
return false; | ||
} | ||
var lifecycle = tokens[0].ToLowerInvariant() switch | ||
{ | ||
"preview" => ProductLifecycle.TechnicalPreview, | ||
"tech-preview" => ProductLifecycle.TechnicalPreview, | ||
"beta" => ProductLifecycle.Beta, | ||
"dev" => ProductLifecycle.Development, | ||
"development" => ProductLifecycle.Development, | ||
"deprecated" => ProductLifecycle.Deprecated, | ||
"coming" => ProductLifecycle.Coming, | ||
"discontinued" => ProductLifecycle.Discontinued, | ||
"unavailable" => ProductLifecycle.Unavailable, | ||
"ga" => ProductLifecycle.GenerallyAvailable, | ||
_ => throw new ArgumentOutOfRangeException(nameof(tokens), tokens, $"Unknown product lifecycle: {tokens[0]}") | ||
}; | ||
|
||
var version = tokens.Length < 2 ? null : tokens[1] switch | ||
{ | ||
null => AllVersions.Instance, | ||
"all" => AllVersions.Instance, | ||
"" => AllVersions.Instance, | ||
var t => SemVersionConverter.TryParse(t, out var v) ? v : null | ||
}; | ||
availability = new ProductAvailability { Version = version, Lifecycle = lifecycle }; | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Licensed to Elasticsearch B.V under one or more agreements. | ||
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. | ||
// See the LICENSE file in the project root for more information | ||
|
||
using YamlDotNet.Serialization; | ||
|
||
namespace Elastic.Markdown.Myst.FrontMatter; | ||
|
||
[YamlSerializable] | ||
public enum ProductLifecycle | ||
{ | ||
// technical preview (exists in current docs system per https://github.com/elastic/docs?tab=readme-ov-file#beta-dev-and-preview-experimental) | ||
[YamlMember(Alias = "preview")] | ||
TechnicalPreview, | ||
// beta (ditto) | ||
[YamlMember(Alias = "beta")] | ||
Beta, | ||
// dev (ditto, though it's uncertain whether it's ever used or still needed) | ||
[YamlMember(Alias = "development")] | ||
Development, | ||
// deprecated (exists in current docs system per https://github.com/elastic/docs?tab=readme-ov-file#additions-and-deprecations) | ||
[YamlMember(Alias = "deprecated")] | ||
Deprecated, | ||
// coming (ditto) | ||
[YamlMember(Alias = "coming")] | ||
Coming, | ||
// discontinued (historically we've immediately removed content when the feature ceases to be supported, but this might not be the case with pages that contain information that spans versions) | ||
[YamlMember(Alias = "discontinued")] | ||
Discontinued, | ||
// unavailable (for content that doesn't exist in a specific context and is never coming or not coming anytime soon) | ||
[YamlMember(Alias = "unavailable")] | ||
Unavailable, | ||
// ga (replaces "added" in the current docs system since it was not entirely clear how/if that overlapped with beta/preview states) | ||
[YamlMember(Alias = "ga")] | ||
GenerallyAvailable | ||
} |
Oops, something went wrong.