Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,39 @@
// 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.Documentation.AppliesTo;
using Elastic.Documentation.Configuration.LegacyUrlMappings;
using Elastic.Documentation.Configuration.Products;

namespace Elastic.Documentation.Configuration.Versions;

public interface IVersionInferrerService
{
VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<LegacyPageMapping>? legacyPages);
VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<LegacyPageMapping>? legacyPages, IReadOnlyCollection<Product>? products, ApplicableTo? applicableTo);
}

public class ProductVersionInferrerService(ProductsConfiguration productsConfiguration, VersionsConfiguration versionsConfiguration) : IVersionInferrerService
{
private ProductsConfiguration ProductsConfiguration { get; } = productsConfiguration;
private VersionsConfiguration VersionsConfiguration { get; } = versionsConfiguration;
public VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<LegacyPageMapping>? legacyPages)
public VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<LegacyPageMapping>? legacyPages, IReadOnlyCollection<Product>? products, ApplicableTo? applicableTo)
{
var versioning = legacyPages is not null && legacyPages.Count > 0
? legacyPages.ElementAt(0).Product.VersioningSystem! // If the page has a legacy page mapping, use the versioning system of the legacy page
: ProductsConfiguration.Products.TryGetValue(repositoryName, out var belonging)
// docs-content handles content from multiple products which should preferably be inferred through frontmatter metadata
if (repositoryName.Equals("docs-content", StringComparison.OrdinalIgnoreCase))
{
if (products is { Count: > 0 }) // If the page is from multiple products, use the versioning system of the first product
return products.First().VersioningSystem!;
if (applicableTo is not null)
{
var versioningFromApplicability = VersioningFromApplicability(applicableTo); // Try to infer the versioning system from the applicability metadata
if (versioningFromApplicability is not null)
return versioningFromApplicability;
}
}
if (legacyPages is { Count: > 0 })
return legacyPages.ElementAt(0).Product.VersioningSystem!; // If the page has a legacy page mapping, use the versioning system of the legacy page

var versioning = ProductsConfiguration.Products.TryGetValue(repositoryName, out var belonging)
? belonging.VersioningSystem! //If the page's docset has a name with a direct product match, use the versioning system of the product
: ProductsConfiguration.Products.Values.SingleOrDefault(p =>
p.Repository is not null && p.Repository.Equals(repositoryName, StringComparison.OrdinalIgnoreCase)) is { } repositoryMatch
Expand All @@ -29,11 +43,59 @@ public VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<

return versioning;
}

private VersioningSystem? VersioningFromApplicability(ApplicableTo applicableTo)
{
VersioningSystem? versioning = null;
if (applicableTo.ProductApplicability is not null)
{
versioning = applicableTo.ProductApplicability switch
{
{ ApmAgentAndroid: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentAndroid],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should have an exhaustive ProductFromApplicability and have a unit test to ensure all known products are handled.

{ ApmAgentIos: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentIos],
{ ApmAgentJava: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentJava],
{ ApmAgentDotnet: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentDotnet],
{ ApmAgentGo: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentGo],
{ ApmAgentNode: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentNode],
{ ApmAgentPhp: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentPhp],
{ ApmAgentPython: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentPython],
{ ApmAgentRuby: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentRuby],
{ ApmAgentRumJs: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.ApmAgentRumJs],
{ Curator: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.Curator],
{ Ecctl: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.Ecctl],
{ EdotAndroid: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotAndroid],
{ EdotCfAws: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotCfAws],
{ EdotCfAzure: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotCfAzure],
{ EdotCollector: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotCollector],
{ EdotIos: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotIos],
{ EdotJava: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotJava],
{ EdotNode: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotNode],
{ EdotDotnet: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotDotnet],
{ EdotPhp: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotPhp],
{ EdotPython: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.EdotPython],
_ => null
};
}
if (versioning is not null)
return versioning;
if (applicableTo.Deployment is not null)
{
versioning = applicableTo.Deployment switch
{
{ Ece: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.Ece],
{ Eck: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.Eck],
{ Ess: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.Ess],
{ Self: not null } => VersionsConfiguration.VersioningSystems[VersioningSystemId.Self],
_ => null
};
}
return versioning;
}
}

public class NoopVersionInferrer : IVersionInferrerService
{
public VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<LegacyPageMapping>? legacyPages) => new()
public VersioningSystem InferVersion(string repositoryName, IReadOnlyCollection<LegacyPageMapping>? legacyPages, IReadOnlyCollection<Product>? products, ApplicableTo? applicableTo) => new()
{
Id = VersioningSystemId.Stack,
Base = new SemVersion(0, 0, 0),
Expand Down
3 changes: 2 additions & 1 deletion src/Elastic.Markdown/HtmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private async Task<RenderResult> RenderLayout(MarkdownFile markdown, MarkdownDoc
fullNavigationRenderResult
);

var pageVersioning = VersionInferrerService.InferVersion(DocumentationSet.Context.Git.RepositoryName, legacyPages);
var pageVersioning = VersionInferrerService.InferVersion(DocumentationSet.Context.Git.RepositoryName, legacyPages, markdown.YamlFrontMatter?.Products, markdown.YamlFrontMatter?.AppliesTo);

var currentBaseVersion = $"{pageVersioning.Base.Major}.{pageVersioning.Base.Minor}+";

Expand Down Expand Up @@ -147,6 +147,7 @@ private async Task<RenderResult> RenderLayout(MarkdownFile markdown, MarkdownDoc
LegacyPages = legacyPages?.ToArray(),
VersionDropdownItems = VersionDropDownItemViewModel.FromLegacyPageMappings(legacyPages?.ToArray()),
Products = pageProducts,
VersioningSystem = pageVersioning,
VersionsConfig = DocumentationSet.Context.VersionsConfiguration,
StructuredBreadcrumbsJson = structuredBreadcrumbsJsonString
});
Expand Down
15 changes: 10 additions & 5 deletions src/Elastic.Markdown/Layout/_TableOfContents.cshtml
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
@using Elastic.Documentation.Configuration.Versions
@inherits RazorSlice<Elastic.Markdown.MarkdownLayoutViewModel>
<aside class="sidebar md:block w-full lg:max-w-65 md:order-2 px-6 md:px-10 lg:px-0">
<nav id="toc-nav" class="sidebar-nav lg:h-full flex flex-row-reverse lg:block items-center gap-4">
<div class="mt-6">
<version-dropdown all-versions-url="@Model.AllVersionsUrl" current-version='@(Model.CurrentVersion)' items='@(new HtmlString(Model.VersionDropdownSerializedModel))'>
<div class="h-8">@*height of dropdown button*@</div>
</version-dropdown>
</div>
@if (Model.VersioningSystem.Id is not
(VersioningSystemId.All or VersioningSystemId.Serverless or VersioningSystemId.Ech or VersioningSystemId.Ess))
{
<div class="mt-6">
<version-dropdown all-versions-url="@Model.AllVersionsUrl" current-version='@(Model.CurrentVersion)' items='@(new HtmlString(Model.VersionDropdownSerializedModel))'>
<div class="h-8">@*height of dropdown button*@</div>
</version-dropdown>
</div>
}
<ul class="mt-6 hidden md:flex items-center lg:block gap-4">
<li class="view-as-markdown hidden lg:block lg:not-first:mt-1">
<a href="@Model.MarkdownUrl" class="link text-sm" target="_blank">
Expand Down
4 changes: 3 additions & 1 deletion src/Elastic.Markdown/MarkdownLayoutViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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.Documentation.Configuration.LegacyUrlMappings;
using Elastic.Documentation.Configuration.Versions;
using Elastic.Documentation.Site;
using Elastic.Documentation.Site.Navigation;

Expand All @@ -23,6 +23,8 @@ public record MarkdownLayoutViewModel : GlobalLayoutViewModel

public required MarkdownPageLayout? Layout { get; init; }

public required VersioningSystem VersioningSystem { get; init; }

public required string? VersionDropdownSerializedModel { get; init; }

public required string? CurrentVersion { get; init; }
Expand Down
1 change: 1 addition & 0 deletions src/Elastic.Markdown/Page/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
Breadcrumbs = Model.Breadcrumbs,
CurrentVersion = Model.CurrentDocument.YamlFrontMatter?.Layout == MarkdownPageLayout.LandingPage ? Model.VersionsConfig.VersioningSystems[0].Current : Model.CurrentVersion,
AllVersionsUrl = Model.AllVersionsUrl,
VersioningSystem = Model.VersioningSystem,
VersionDropdownSerializedModel = JsonSerializer.Serialize(Model.VersionDropdownItems,
ViewModelSerializerContext.Default.VersionDropDownItemViewModelArray),
};
Expand Down
2 changes: 1 addition & 1 deletion src/Elastic.Markdown/Page/IndexViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Elastic.Documentation.Site.FileProviders;
using Elastic.Documentation.Site.Navigation;
using Elastic.Markdown.IO;
using Elastic.Markdown.IO.Navigation;

namespace Elastic.Markdown.Page;

Expand Down Expand Up @@ -55,6 +54,7 @@ public class IndexViewModel

public required HashSet<Product> Products { get; init; }

public required VersioningSystem VersioningSystem { get; init; }
public required VersionsConfiguration VersionsConfig { get; init; }

// https://developers.google.com/search/docs/appearance/structured-data/breadcrumb#json-ld
Expand Down
Loading