Migrated Documentation library from NetFlow.DocumentationHelper.Library

This commit is contained in:
2026-01-28 13:15:44 +00:00
parent ab700413fb
commit d20a80c44c
152 changed files with 714 additions and 94 deletions
Regular → Executable
View File
Regular → Executable
View File
View File
Regular → Executable
View File
Generated Regular → Executable
View File
Generated Regular → Executable
View File
Generated Regular → Executable
View File
View File
View File
View File
View File
View File
View File
Generated Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
+1 -1
View File
@@ -1,6 +1,6 @@
# Changelog # Changelog
## Version v1.0.0 ## Version 1.0.0
- **Class: ChangelogTool**: Created the class ChangelogTool to extract changelogs via attributes - **Class: ChangelogTool**: Created the class ChangelogTool to extract changelogs via attributes
- **Class: ChangelogAttribute**: Created ChangelogAttribute to be used to register changes in the code. - **Class: ChangelogAttribute**: Created ChangelogAttribute to be used to register changes in the code.
@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using OmegaLeo.HelperLib.Shared.Attributes;
namespace OmegaLeo.HelperLib.Changelog.Helpers
{
[Documentation(nameof(ChangelogHelper),
"Helper class to generate changelog markdown from ChangelogAttributes in the provided Assemblies.")]
[Changelog("1.2.0", "Created ChangelogHelper to generate markdown from changelog attributes.")]
public static class ChangelogHelper
{
[Documentation(nameof(GetChangelogMarkdown),
"Generates a markdown formatted changelog from the changelog attributes in the provided assemblies.")]
public static string GetChangelogMarkdown(IEnumerable<Assembly> assemblies)
{
var changelog = new StringBuilder();
var entriesByVersionDate =
new Dictionary<(string Version, string Date),
Dictionary<string, List<(string ClassName, string Description)>>>();
foreach (var assembly in assemblies)
{
try
{
foreach (var type in assembly.GetTypes())
{
// Get type-level changelog attributes
var typeAttrs = type.GetCustomAttributes<ChangelogAttribute>().ToList();
// Get member-level changelog attributes (methods, properties, fields, etc.)
var memberAttrs = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance)
.SelectMany(m => m.GetCustomAttributes<ChangelogAttribute>()
.Select(attr => (Member: m, Attribute: attr)))
.ToList();
if (typeAttrs.Any() || memberAttrs.Any())
{
var namespaceName = type.Namespace ?? "Global";
var className = type.Name.Split('`')[0];
// Process type-level attributes
foreach (var attr in typeAttrs)
{
AddEntry(entriesByVersionDate, namespaceName, className, attr.Version, attr.Date,
attr.Description);
}
// Process member-level attributes
foreach (var (member, attr) in memberAttrs)
{
var memberName = $"{className}.{member.Name}";
AddEntry(entriesByVersionDate, namespaceName, memberName, attr.Version, attr.Date,
attr.Description);
}
}
}
}
catch (ReflectionTypeLoadException)
{
// Skip assemblies that can't be fully loaded
}
}
foreach (var versionGroup in entriesByVersionDate.OrderByDescending(x => x.Key.Version))
{
changelog.AppendLine($"## Version {versionGroup.Key.Version}");
if (!string.IsNullOrEmpty(versionGroup.Key.Date))
{
changelog.AppendLine($"### {versionGroup.Key.Date}");
}
changelog.AppendLine();
foreach (var namespaceGroup in versionGroup.Value.OrderBy(x => x.Key))
{
changelog.AppendLine($"**{namespaceGroup.Key}**");
foreach (var entry in namespaceGroup.Value.OrderBy(x => x.ClassName))
{
changelog.AppendLine($@"- **{entry.ClassName}**:
- {entry.Description}");
}
changelog.AppendLine();
}
}
return changelog.ToString();
}
private static void AddEntry(
Dictionary<(string Version, string Date), Dictionary<string, List<(string ClassName, string Description)>>>
entriesByVersionDate,
string namespaceName,
string className,
string version,
string date,
string description)
{
var key = (version, date ?? string.Empty);
if (!entriesByVersionDate.ContainsKey(key))
entriesByVersionDate[key] = new Dictionary<string, List<(string, string)>>();
if (!entriesByVersionDate[key].ContainsKey(namespaceName))
entriesByVersionDate[key][namespaceName] = new List<(string, string)>();
entriesByVersionDate[key][namespaceName].Add((className, description));
}
}
}
View File
View File
+4 -7
View File
@@ -23,17 +23,14 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.3" /> <Reference Include="OmegaLeo.HelperLib.Documentation">
</ItemGroup> <HintPath>..\..\..\..\..\..\home\omegaleo\.nuget\packages\OmegaLeo.HelperLib.Documentation\1.1.2\lib\netstandard2.1\OmegaLeo.HelperLib.Documentation.dll</HintPath>
<ItemGroup>
<Reference Include="NetFlow.DocumentationHelper.Library">
<HintPath>..\..\..\..\..\..\home\omegaleo\.nuget\packages\netflow.documentationhelper.library\1.1.2\lib\netstandard2.1\NetFlow.DocumentationHelper.Library.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.2" /> <ProjectReference Include="..\OmegaLeo.HelperLib.Documentation\OmegaLeo.HelperLib.Documentation.csproj" />
<ProjectReference Include="..\OmegaLeo.HelperLib.Shared\OmegaLeo.HelperLib.Shared.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1 -1
View File
@@ -3,7 +3,7 @@ Package to help with Changelog generation by providing a new Changelog attribute
Example attribute usage: Example attribute usage:
```cs ```cs
[Changelog("v1.0.0", "This is a test")] [Changelog("1.0.0", "This is a test")]
[Changelog("v1.0.1", "This is another test")] [Changelog("v1.0.1", "This is another test")]
public class Test public class Test
{ {
+2 -3
View File
@@ -2,12 +2,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Changelog.Attributes;
namespace OmegaLeo.HelperLib.Changelog.Tools namespace OmegaLeo.HelperLib.Changelog.Tools
{ {
[Changelog("v1.0.0", "Created the class ChangelogTool to extract changelogs via attributes")] [Changelog("1.0.0", "Created the class ChangelogTool to extract changelogs via attributes")]
[Documentation("ChangelogTool", "Provides methods to extract changelog information from assembly attributes.")] [Documentation("ChangelogTool", "Provides methods to extract changelog information from assembly attributes.")]
public class ChangelogTool public class ChangelogTool
{ {
@@ -13,8 +13,4 @@
<ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" /> <ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.3" />
</ItemGroup>
</Project> </Project>
+1 -1
View File
@@ -4,7 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using GameDevLibrary.Helpers; using OmegaLeo.HelperLib.Helpers;
using OmegaLeo.HelperLib.Changelog.Models; using OmegaLeo.HelperLib.Changelog.Models;
using OmegaLeo.HelperLib.Changelog.Tools; using OmegaLeo.HelperLib.Changelog.Tools;
-4
View File
@@ -13,8 +13,4 @@
<ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" /> <ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.3" />
</ItemGroup>
</Project> </Project>
+2 -2
View File
@@ -3,8 +3,8 @@
// /media/omegaleo/Development/Library Dev/HelperLib // /media/omegaleo/Development/Library Dev/HelperLib
using System.Reflection; using System.Reflection;
using GameDevLibrary.Extensions; using OmegaLeo.HelperLib.Extensions;
using GameDevLibrary.Helpers; using OmegaLeo.HelperLib.Helpers;
using LibGit2Sharp; using LibGit2Sharp;
using OmegaLeo.HelperLib.Changelog.Tools; using OmegaLeo.HelperLib.Changelog.Tools;
using OmegaLeo.HelperLib.Git; using OmegaLeo.HelperLib.Git;
@@ -1,10 +0,0 @@
using OmegaLeo.HelperLib.Changelog.Attributes;
namespace OmegaLeo.HelperLib.ConsoleApp;
[Changelog("v1.0.0", "Test")]
[Changelog("v1.0.1", "Test 1")]
public class TestClass
{
}
@@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using Microsoft.Extensions.DependencyModel;
using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Documentation.Models;
namespace OmegaLeo.HelperLib.Documentation.Helpers
{
[Changelog("1.2.0", "Migrated DocumentationHelper library from NetFlow.DocumentationHelper.Library to it's own package in OmegaLeo.HelperLib")]
public static class DocumentationHelperTool
{
[Documentation("GenerateDocumentation (bool generateForPackageAssembly)",
@"Generates a List of objects of type DocumentationStructure that contain the following fields:
**AssemblyName**: Name of the main Assembly, used to identify the root namespace
**ClassName**: Name of the class, used to identify the upper level object
**Title**: Title what we're generating documentation for
**Description**: Description of what we're generating documentation for, this can contain usage examples and can use the args array to pass names(e.g.: This method uses this methodology)
**Args**: Array of strings that describe the parameters of the method or class
**CodeExample**: A code example of how to use the method or class
*Note: If generateForPackageAssembly is set to true, this will generate documentation for the library as well.*",
new []
{
"generateForPackageAssembly - Generate documentation for the DocumentationHelper library as well?"
},
@"```csharp
DocumentationHelperTool.GenerateDocumentation(true); // Generates documentation for all assemblies including the DocumentationHelper.Library package assembly
DocumentationHelperTool.GenerateDocumentation(false); // Generates documentation for all assemblies excluding the DocumentationHelper.Library package assembly
```")]
public static IEnumerable<DocumentationStructure> GenerateDocumentation(bool generateForPackageAssembly = false)
{
EnsureReferencedAssembliesLoaded();
var assemblies = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => !a.IsDynamic)
.Select(a =>
new DocumentationAssembly()
{
AssemblyName = a.GetName(false)?.Name ?? nameof(a),
Types = GetTypesWithDocumentationAttribute(a)
}).Where(x => x.Types.Any()).ToList();
if (!generateForPackageAssembly)
{
assemblies =
assemblies.Where(x => x.AssemblyName != typeof(DocumentationHelperTool).Assembly.GetName().Name)
.ToList();
}
foreach (var assembly in assemblies)
{
foreach (var type in assembly.Types)
{
var doc = GetDocumentation(type, assembly.AssemblyName);
yield return doc;
}
}
}
static void EnsureReferencedAssembliesLoaded()
{
try
{
var loadedNames = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => a.GetName(false) != null)
.Select(a => a.GetName(false).Name)
.ToHashSet(StringComparer.OrdinalIgnoreCase);
var deps = DependencyContext.Default?.RuntimeLibraries;
if (deps == null) return;
foreach (var lib in deps)
{
if (!loadedNames.Contains(lib.Name))
{
try
{
Assembly.Load(new AssemblyName(lib.Name));
}
catch (Exception ex)
{
Console.Error.WriteLine($"warning OMEGA001: Failed to load assembly '{lib.Name}': {ex.Message}");
}
}
}
}
catch (Exception ex)
{
// best-effort only
Console.Error.WriteLine($"warning OMEGA001: EnsureReferencedAssembliesLoaded failed: {ex.Message}");
}
}
static IEnumerable<Type> GetTypesWithDocumentationAttribute(Assembly assembly)
{
Type[] types;
try
{
types = assembly.GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
types = ex.Types.Where(t => t != null).ToArray();
}
foreach (Type type in types)
{
if (type == null) continue;
var classHasDoc = type.GetCustomAttributes(typeof(DocumentationAttribute), true).Any();
var fieldsHaveDoc = type.GetFields()
.Any(f => f.GetCustomAttributes(typeof(DocumentationAttribute), true).Any());
var typesHaveDoc = type.GetProperties()
.Any(p => p.GetCustomAttributes(typeof(DocumentationAttribute), true).Any());
var methodsHaveDoc = type.GetMethods()
.Any(m => m.GetCustomAttributes(typeof(DocumentationAttribute), true).Any());
if (classHasDoc || fieldsHaveDoc || typesHaveDoc || methodsHaveDoc)
{
yield return type;
}
}
}
[Documentation(nameof(GetDocumentation), "Generates a DocumentationStructure object for the given Type and Assembly Name",
new []
{
"type - The Type to generate documentation for",
"assemblyName - The name of the assembly the Type belongs to"
},
@"```csharp
var doc = GetDocumentation(typeof(MyClass), ""MyAssembly"");
```")]
static DocumentationStructure GetDocumentation(Type type, string assemblyName)
{
var classDocs = type.GetCustomAttributes(typeof(DocumentationAttribute), true)
.Select(x => (DocumentationAttribute)x);
var fieldDocs = type.GetFields().SelectMany(f =>
f.GetCustomAttributes(typeof(DocumentationAttribute), true).Select(x => (DocumentationAttribute)x));
var propertyDocs = type.GetProperties().SelectMany(p =>
p.GetCustomAttributes(typeof(DocumentationAttribute), true).Select(x => (DocumentationAttribute)x));
var methodDocs = type.GetMethods().SelectMany(m =>
m.GetCustomAttributes(typeof(DocumentationAttribute), true).Select(x => (DocumentationAttribute)x));
var docStructure = new DocumentationStructure(assemblyName, type.Name);
foreach (var doc in classDocs)
{
docStructure.AddDescription(new DocumentationDescription(doc.Title, doc.Description, doc.Args, doc.CodeExample));
}
foreach (var doc in fieldDocs)
{
docStructure.AddDescription(new DocumentationDescription(doc.Title, doc.Description, doc.Args, doc.CodeExample));
}
foreach (var doc in propertyDocs)
{
docStructure.AddDescription(new DocumentationDescription(doc.Title, doc.Description, doc.Args, doc.CodeExample));
}
foreach (var doc in methodDocs)
{
docStructure.AddDescription(new DocumentationDescription(doc.Title, doc.Description, doc.Args, doc.CodeExample));
}
return docStructure;
}
static Dictionary<string, string> loadedXmlDocumentation =
new Dictionary<string, string>();
public static void LoadXmlDocumentation(string xmlDocumentation)
{
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlDocumentation)))
{
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "member")
{
string raw_name = xmlReader["name"];
loadedXmlDocumentation[raw_name] = xmlReader.ReadInnerXml();
}
}
}
}
}
}
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
namespace OmegaLeo.HelperLib.Documentation.Models
{
public class DocumentationAssembly
{
public string AssemblyName;
public IEnumerable<Type> Types;
}
}
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using OmegaLeo.HelperLib.Shared.Attributes;
namespace OmegaLeo.HelperLib.Documentation.Models
{
public class DocumentationStructure
{
public string AssemblyName;
public string ClassName;
public List<DocumentationDescription> Descriptions;
public DocumentationStructure(string assemblyName, string className)
{
AssemblyName = assemblyName;
ClassName = className;
Descriptions = new List<DocumentationDescription>();
}
public void AddDescription(DocumentationDescription description)
{
Descriptions.Add(description);
}
}
public class DocumentationDescription
{
public string Title;
public string Description;
public string[] Parameters;
public string CodeExample = string.Empty;
[Documentation(nameof(DocumentationDescription), "Description of the current Documented object", new []
{
"title - Name of the object",
"description - Description of what the object does",
"parameters - The parameters for the object (in case of a method with parameters)",
"codeExample - Code example of how to use the object"
})]
public DocumentationDescription(string title, string description, string[] parameters = default, string codeExample = "")
{
Title = title;
Description = description;
Parameters = parameters ?? Array.Empty<string>();
CodeExample = codeExample;
}
}
}
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<RootNamespace>OmegaLeo.HelperLib.Documentation</RootNamespace>
<Version>0.0.2</Version>
<Title>Omega Leo's Helper Library</Title>
<Authors>Nuno "Omega Leo" Diogo</Authors>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://github.com/omegaleo/HelperLib</PackageProjectUrl>
<RepositoryUrl>https://github.com/omegaleo/HelperLib</RepositoryUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageLicenseExpression>AGPL-3.0-only</PackageLicenseExpression>
<PackageTags>csharp;dotnet;utility;helper;documentation;</PackageTags>
<RepositoryType>git</RepositoryType>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="10.0.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Attributes\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OmegaLeo.HelperLib.Shared\OmegaLeo.HelperLib.Shared.csproj" />
</ItemGroup>
</Project>
+1 -1
View File
@@ -1,5 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Game.Models; using OmegaLeo.HelperLib.Game.Models;
namespace OmegaLeo.HelperLib.Game.Extensions namespace OmegaLeo.HelperLib.Game.Extensions
+1 -1
View File
@@ -1,4 +1,4 @@
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Game.Models; using OmegaLeo.HelperLib.Game.Models;
namespace OmegaLeo.HelperLib.Game.Handlers namespace OmegaLeo.HelperLib.Game.Handlers
View File
View File
View File
View File
View File
View File
View File
-1
View File
@@ -19,7 +19,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup> </ItemGroup>
View File
View File
View File
View File
Regular → Executable
View File
+1 -1
View File
@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Game.Models; using OmegaLeo.HelperLib.Game.Models;
namespace OmegaLeo.HelperLib.Game.Services namespace OmegaLeo.HelperLib.Game.Services
+1 -1
View File
@@ -1,6 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Game.Handlers; using OmegaLeo.HelperLib.Game.Handlers;
using OmegaLeo.HelperLib.Game.Models; using OmegaLeo.HelperLib.Game.Models;
+1 -1
View File
@@ -1,6 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using Newtonsoft.Json; using Newtonsoft.Json;
using OmegaLeo.HelperLib.Game.Interfaces; using OmegaLeo.HelperLib.Game.Interfaces;
View File
View File
+1 -1
View File
@@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NetFlow.DocumentationHelper.Library.Attributes; using OmegaLeo.HelperLib.Shared.Attributes;
using OmegaLeo.HelperLib.Game.Models; using OmegaLeo.HelperLib.Game.Models;
namespace OmegaLeo.HelperLib.Game.Utilities namespace OmegaLeo.HelperLib.Game.Utilities
+1 -1
View File
@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using GameDevLibrary.Extensions; using OmegaLeo.HelperLib.Extensions;
using LibGit2Sharp; using LibGit2Sharp;
using OmegaLeo.HelperLib.Git.Models; using OmegaLeo.HelperLib.Git.Models;
View File
+1 -2
View File
@@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<RootNamespace>GameDevLibrary.Git</RootNamespace> <RootNamespace>OmegaLeo.HelperLib.Git</RootNamespace>
<Version>0.0.2</Version> <Version>0.0.2</Version>
<Title>Omega Leo's Helper Library - LibGit2Sharp Implementation</Title> <Title>Omega Leo's Helper Library - LibGit2Sharp Implementation</Title>
<Authors>Nuno "Omega Leo" Diogo</Authors> <Authors>Nuno "Omega Leo" Diogo</Authors>
@@ -13,7 +13,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="LibGit2Sharp" Version="0.30.0"/> <PackageReference Include="LibGit2Sharp" Version="0.30.0"/>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -1,20 +1,22 @@
using System; using System;
using NetFlow.DocumentationHelper.Library.Attributes;
namespace OmegaLeo.HelperLib.Changelog.Attributes namespace OmegaLeo.HelperLib.Shared.Attributes
{ {
[Changelog("v1.0.0", "Created ChangelogAttribute to be used to register changes in the code.")] [Changelog("1.0.0", "Created ChangelogAttribute to be used to register changes in the code.")]
[Documentation(nameof(ChangelogAttribute), "Attribute to annotate classes, methods, or properties with changelog information.")] [Documentation(nameof(ChangelogAttribute), "Attribute to annotate classes, methods, or properties with changelog information.")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public class ChangelogAttribute : Attribute public class ChangelogAttribute : Attribute
{ {
public string Version { get; } public string Version { get; }
public string Description { get; } public string Description { get; }
public string Date { get; set; }
public ChangelogAttribute(string version, string description) public ChangelogAttribute(string version, string description, string date = "")
{ {
Version = version; Version = version;
Description = description; Description = description;
Date = date;
} }
} }
} }
@@ -0,0 +1,21 @@
using System;
namespace OmegaLeo.HelperLib.Shared.Attributes
{
[System.AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class DocumentationAttribute : Attribute
{
public string Title;
public string Description;
public string[] Args;
public string CodeExample = string.Empty;
public DocumentationAttribute(string title, string description, string[] args = null, string codeExample = "")
{
Title = title;
Description = description;
Args = args ?? Array.Empty<string>();
CodeExample = codeExample;
}
}
}
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+21 -12
View File
@@ -3,10 +3,11 @@
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using GameDevLibrary.Helpers; using OmegaLeo.HelperLib.Helpers;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NetFlow.DocumentationHelper.Library.Helpers; using OmegaLeo.HelperLib.Changelog.Helpers;
using NetFlow.DocumentationHelper.Library.Models; using OmegaLeo.HelperLib.Documentation.Helpers;
using OmegaLeo.HelperLib.Documentation.Models;
using OmegaLeo.HelperLib.Changelog.Tools; using OmegaLeo.HelperLib.Changelog.Tools;
using OmegaLeo.HelperLib.Web.Models; using OmegaLeo.HelperLib.Web.Models;
@@ -52,7 +53,15 @@ public class HomeController : Controller
"Game Development Library", "Game Development Library",
"Game development utilities for Unity and Godot", "Game development utilities for Unity and Godot",
"OmegaLeo.HelperLib.Game" "OmegaLeo.HelperLib.Game"
) ),
["documentation"] = GenerateLibraryDocs(
typeof(OmegaLeo.HelperLib.Documentation.Helpers.DocumentationHelperTool).Assembly,
Path.Combine(root, "changelogs", "OmegaLeo.HelperLib.Documentation.CHANGELOG.md"),
"Documentation Library",
"Tools for generating documentation from code attributes",
"OmegaLeo.HelperLib.Documentation",
true
),
}; };
_logger.LogInformation("Initialized {Count} libraries", _libraryCache.Count); _logger.LogInformation("Initialized {Count} libraries", _libraryCache.Count);
@@ -99,11 +108,11 @@ public class HomeController : Controller
{ {
var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var target = assemblies.FirstOrDefault(a => var target = assemblies.FirstOrDefault(a =>
a.GetName().Name.Equals("NetFlow.DocumentationHelper.Library", StringComparison.OrdinalIgnoreCase)); a.GetName().Name.Equals("OmegaLeo.HelperLib.Documentation", StringComparison.OrdinalIgnoreCase));
if (target == null) if (target == null)
{ {
_logger.LogWarning("NetFlow.DocumentationHelper.Library not loaded. Loaded assemblies ({Count}):", _logger.LogWarning("OmegaLeo.HelperLib.Documentation not loaded. Loaded assemblies ({Count}):",
assemblies.Length); assemblies.Length);
foreach (var a in assemblies.OrderBy(a => a.GetName().Name)) foreach (var a in assemblies.OrderBy(a => a.GetName().Name))
{ {
@@ -120,7 +129,7 @@ public class HomeController : Controller
Type attrType = null; Type attrType = null;
try try
{ {
attrType = target.GetType("NetFlow.DocumentationHelper.Library.Attributes.DocumentationAttribute", attrType = target.GetType("OmegaLeo.HelperLib.Documentation.Attributes.DocumentationAttribute",
false, true); false, true);
} }
catch (Exception ex) catch (Exception ex)
@@ -238,7 +247,7 @@ public class HomeController : Controller
} }
private LibraryDocumentationViewModel GenerateLibraryDocs(Assembly assembly, string changelogPath, private LibraryDocumentationViewModel GenerateLibraryDocs(Assembly assembly, string changelogPath,
string displayName, string description, string nugetPackageId) string displayName, string description, string nugetPackageId, bool generateForDocumentationAssembly = false)
{ {
_logger.LogInformation("=== Starting GenerateLibraryDocs for {Assembly} ===", assembly.GetName().Name); _logger.LogInformation("=== Starting GenerateLibraryDocs for {Assembly} ===", assembly.GetName().Name);
_logger.LogInformation("Assembly location: {Location}", assembly.Location ?? "<in-memory>"); _logger.LogInformation("Assembly location: {Location}", assembly.Location ?? "<in-memory>");
@@ -278,7 +287,7 @@ public class HomeController : Controller
try try
{ {
// Pass the specific assembly to only scan that assembly // Pass the specific assembly to only scan that assembly
var result = DocumentationHelperTool.GenerateDocumentation(); var result = DocumentationHelperTool.GenerateDocumentation(generateForDocumentationAssembly);
allDocumentation = result? allDocumentation = result?
.Where(d => d.AssemblyName?.Equals(assembly.GetName().Name ,StringComparison.OrdinalIgnoreCase) == true) .Where(d => d.AssemblyName?.Equals(assembly.GetName().Name ,StringComparison.OrdinalIgnoreCase) == true)
.ToList() ?? Enumerable.Empty<DocumentationStructure>(); .ToList() ?? Enumerable.Empty<DocumentationStructure>();
@@ -307,7 +316,7 @@ public class HomeController : Controller
throw; throw;
} }
var changelogMarkdown = string.Empty; /*var changelogMarkdown = string.Empty;
if (System.IO.File.Exists(changelogPath)) if (System.IO.File.Exists(changelogPath))
{ {
try try
@@ -324,14 +333,14 @@ public class HomeController : Controller
else else
{ {
_logger.LogWarning("Changelog file not found at {Path}", changelogPath); _logger.LogWarning("Changelog file not found at {Path}", changelogPath);
} }*/
var viewModel = new LibraryDocumentationViewModel var viewModel = new LibraryDocumentationViewModel
{ {
LibraryName = displayName, LibraryName = displayName,
Description = description, Description = description,
NuGetPackageId = nugetPackageId, NuGetPackageId = nugetPackageId,
ChangelogMarkdown = changelogMarkdown, ChangelogMarkdown = ChangelogHelper.GetChangelogMarkdown(new []{assembly}),
Documentation = allDocumentation.ToList() Documentation = allDocumentation.ToList()
}; };
View File
+1 -1
View File
@@ -1,5 +1,5 @@
// File: `OmegaLeo.HelperLib.Web/Models/LibraryDocumentationViewModel.cs` // File: `OmegaLeo.HelperLib.Web/Models/LibraryDocumentationViewModel.cs`
using NetFlow.DocumentationHelper.Library.Models; using OmegaLeo.HelperLib.Documentation.Models;
namespace OmegaLeo.HelperLib.Web.Models namespace OmegaLeo.HelperLib.Web.Models
{ {
-1
View File
@@ -16,7 +16,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Markdig" Version="0.40.0" /> <PackageReference Include="Markdig" Version="0.40.0" />
<PackageReference Include="MarkdigExtensions.SyntaxHighlighting" Version="1.0.3" /> <PackageReference Include="MarkdigExtensions.SyntaxHighlighting" Version="1.0.3" />
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.3" />
<PackageReference Include="Serilog.AspNetCore" Version="10.0.0" /> <PackageReference Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
View File
View File
View File
+2 -2
View File
@@ -1,6 +1,6 @@
@* File: `OmegaLeo.HelperLib.Web/Views/Home/Library.cshtml` *@ @* File: `OmegaLeo.HelperLib.Web/Views/Home/Library.cshtml` *@
@using ColorCode.Styling @using ColorCode.Styling
@using GameDevLibrary.Extensions @using OmegaLeo.HelperLib.Extensions
@using Markdig @using Markdig
@model OmegaLeo.HelperLib.Web.Models.LibraryDocumentationViewModel @model OmegaLeo.HelperLib.Web.Models.LibraryDocumentationViewModel
@{ @{
@@ -83,7 +83,7 @@
{ {
<tr> <tr>
<td><code>@desc.Title</code></td> <td><code>@desc.Title</code></td>
<td>@Html.Raw(desc.Description)<br/> <td>@Html.Raw(Markdig.Markdown.ToHtml(desc.Description))<br/>
@if (desc.CodeExample.IsNotNullOrEmpty()) @if (desc.CodeExample.IsNotNullOrEmpty())
{ {
<strong>Example:</strong><br/> <strong>Example:</strong><br/>
View File
View File
+3
View File
@@ -33,6 +33,9 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" asp-area="" asp-controller="Home" asp-action="Library" asp-route-id="game">Game Dev</a> <a class="nav-link" asp-area="" asp-controller="Home" asp-action="Library" asp-route-id="game">Game Dev</a>
</li> </li>
<li class="nav-item">
<a class="nav-link" asp-area="" asp-controller="Home" asp-action="Library" asp-route-id="documentation">Documentation</a>
</li>
</ul> </ul>
<ul class="navbar-nav ms-auto"> <ul class="navbar-nav ms-auto">
View File
View File
View File
View File
View File
View File
View File
View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More