From 690232b0b88aec2e2e2691ff6d5fed6df54bef8b Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Tue, 3 Jun 2025 10:51:22 +0200 Subject: [PATCH 1/4] Reproducible IDs Generate the ID based on a stable unique attribute --- src/Elastic.Markdown/IO/MarkdownFile.cs | 5 ++++- .../IO/Navigation/DocumentationGroup.cs | 5 ++++- src/Elastic.Markdown/Slices/Directives/_ViewModels.cs | 10 +++++++++- src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml | 4 +--- src/Elastic.Markdown/Slices/_ViewModels.cs | 5 ----- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Elastic.Markdown/IO/MarkdownFile.cs b/src/Elastic.Markdown/IO/MarkdownFile.cs index 3c533824e..8c1dbf136 100644 --- a/src/Elastic.Markdown/IO/MarkdownFile.cs +++ b/src/Elastic.Markdown/IO/MarkdownFile.cs @@ -4,6 +4,8 @@ using System.IO.Abstractions; using System.Runtime.InteropServices; +using System.Security.Cryptography; +using System.Text; using Elastic.Documentation.Diagnostics; using Elastic.Documentation.Navigation; using Elastic.Markdown.Diagnostics; @@ -51,6 +53,7 @@ DocumentationSet set _configurationFile = build.Configuration.SourceFile; _globalSubstitutions = build.Configuration.Substitutions; _set = set; + Id = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(FilePath)))[..8]; //may be updated by DocumentationGroup.ProcessTocItems //todo refactor mutability of MarkdownFile as a whole ScopeDirectory = build.Configuration.ScopeDirectory; @@ -65,7 +68,7 @@ DocumentationSet set public Uri NavigationSource { get; set; } - public string Id { get; } = Guid.NewGuid().ToString("N")[..8]; + public string Id { get; } private IDiagnosticsCollector Collector { get; } diff --git a/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs b/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs index 1c31bcf8c..d2d2c3025 100644 --- a/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs +++ b/src/Elastic.Markdown/IO/Navigation/DocumentationGroup.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; +using System.Text; using Elastic.Documentation; using Elastic.Documentation.Configuration.TableOfContents; @@ -125,7 +127,7 @@ public class DocumentationGroup : INavigationGroup { private readonly TableOfContentsTreeCollector _treeCollector; - public string Id { get; } = Guid.NewGuid().ToString("N")[..8]; + public string Id { get; } public string NavigationRootId => NavigationRoot.Id; @@ -196,6 +198,7 @@ protected DocumentationGroup( GroupsInOrder = groups; FilesInOrder = files; NavigationItems = navigationItems; + Id = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(FolderName + depth)))[..8]; if (Index is not null) FilesInOrder = [.. FilesInOrder.Except([Index])]; diff --git a/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs b/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs index f9b8ed0b6..168d992ce 100644 --- a/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs +++ b/src/Elastic.Markdown/Slices/Directives/_ViewModels.cs @@ -1,6 +1,8 @@ // 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 System.Security.Cryptography; using System.Text; using Elastic.Markdown.Myst.Settings; @@ -56,7 +58,13 @@ public class ImageViewModel public required string? Target { get; init; } public required string? Width { get; init; } public required string? ImageUrl { get; init; } - public string UniqueImageId { get; } = Guid.NewGuid().ToString("N")[..8]; + + private string? _uniqueImageId; + + public string UniqueImageId => + _uniqueImageId ??= string.IsNullOrEmpty(ImageUrl) + ? Guid.NewGuid().ToString("N")[..8] // fallback to a random ID if ImageUrl is null or empty + : Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(ImageUrl)))[..8]; public required string? Screenshot { get; init; } public string Style diff --git a/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml b/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml index 43b34754b..b4288a441 100644 --- a/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml +++ b/src/Elastic.Markdown/Slices/Layout/_PagesNav.cshtml @@ -2,9 +2,7 @@