diff --git a/src/ThisAssembly.Constants/CSharp.sbntxt b/src/ThisAssembly.Constants/CSharp.sbntxt
index a92ce7c2..77711f19 100644
--- a/src/ThisAssembly.Constants/CSharp.sbntxt
+++ b/src/ThisAssembly.Constants/CSharp.sbntxt
@@ -34,6 +34,9 @@
{{~ end ~}}
{{ end }}
{{ func render }}
+ ///
+ /// {{ $0.Comment }}
+ ///
public static partial class {{ $0.Name | string.replace "-" "_" | string.replace " " "_" }}
{
{{~ for value in $0.Values ~}}
@@ -73,8 +76,5 @@ namespace {{ Namespace }};
///
{{ Visibility }}partial class ThisAssembly
{
- ///
- /// {{ RootArea.Comment }}
- ///
{{ render RootArea }}
}
\ No newline at end of file
diff --git a/src/ThisAssembly.Constants/Model.cs b/src/ThisAssembly.Constants/Model.cs
index 8ca8e2b7..10f9ee13 100644
--- a/src/ThisAssembly.Constants/Model.cs
+++ b/src/ThisAssembly.Constants/Model.cs
@@ -4,6 +4,7 @@
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
+using System.Xml.Linq;
using Microsoft.CodeAnalysis.CSharp;
namespace ThisAssembly;
@@ -22,10 +23,21 @@ record Model(Area RootArea, string? Namespace, bool IsPublic)
}
[DebuggerDisplay("Name = {Name}, NestedAreas = {NestedAreas.Count}, Values = {Values.Count}")]
-record Area(string Name, string Prefix, string Comment)
+record Area(string Name, string Prefix)
{
- public List NestedAreas { get; init; } = new();
- public List Values { get; init; } = new();
+ string? comment = null;
+ Area? parent = null;
+
+ public string Comment
+ {
+ get => comment ?? $"Provides access to constants under {Path}";
+ set => comment = value;
+ }
+
+ public string Path => parent == null ? Name : $"{parent.Path}/{Name}";
+
+ public List NestedAreas { get; init; } = [];
+ public List Values { get; init; } = [];
static string EscapeIdentifier(string identifier)
{
@@ -50,7 +62,7 @@ static string EscapeIdentifier(string identifier)
public static Area Load(List constants, string rootArea = "Constants", string comment = "Provides access project-defined constants.")
{
- var root = new Area(rootArea, "", comment);
+ var root = new Area(rootArea, "") { Comment = comment };
foreach (var constant in constants)
{
@@ -96,7 +108,10 @@ static Area GetArea(Area area, IEnumerable areaPath)
"Area name '{0}' is already in use as a value name under area '{1}'.",
areaName, currentArea.Name));
- existing = new Area(areaName, currentArea.Prefix + areaName + ".", "");
+ existing = new Area(areaName, currentArea.Prefix + areaName + ".")
+ {
+ parent = currentArea
+ };
currentArea.NestedAreas.Add(existing);
}
diff --git a/src/ThisAssembly.Resources/CSharp.sbntxt b/src/ThisAssembly.Resources/CSharp.sbntxt
index 9b0520c0..dae7ce5a 100644
--- a/src/ThisAssembly.Resources/CSharp.sbntxt
+++ b/src/ThisAssembly.Resources/CSharp.sbntxt
@@ -31,17 +31,31 @@
{
{{~ if $0.IsText ~}}
private static string text;
+
+ ///
+ /// Gets the resource as plain text.
+ ///
public static string Text =>
text ??= EmbeddedResource.GetContent(@"{{ $0.Path }}");
{{~ end ~}}
+ ///
+ /// Gets the resource as a byte array.
+ ///
public static byte[] GetBytes() =>
EmbeddedResource.GetBytes(@"{{ $0.Path }}");
+
+ ///
+ /// Gets the resource as a stream.
+ ///
public static Stream GetStream() =>
EmbeddedResource.GetStream(@"{{ $0.Path }}");
}
{{ end }}
{{ func render }}
+ ///
+ /// {{ $0.Comment }}
+ ///
public static partial class {{ $0.Name | string.replace "-" "_" | string.replace " " "_" }}
{
{{~ if $0.Resources ~}}
@@ -65,8 +79,5 @@ namespace {{ Namespace }};
///
{{ Visibility }}partial class ThisAssembly
{
- ///
- /// Provides access to assembly embedded resources.
- ///
{{ render RootArea }}
}
diff --git a/src/ThisAssembly.Resources/Model.cs b/src/ThisAssembly.Resources/Model.cs
index 4652e2af..9d7f2d55 100644
--- a/src/ThisAssembly.Resources/Model.cs
+++ b/src/ThisAssembly.Resources/Model.cs
@@ -19,12 +19,34 @@ record Model(Area RootArea, string? Namespace, bool IsPublic)
[DebuggerDisplay("Name = {Name}")]
record Area(string Name)
{
- public Area? NestedArea { get; private set; }
+ Area? nestedArea = null;
+ Area? parent = null;
+ string? comment = null;
+
+ public string? Comment
+ {
+ get => comment ?? $"Provides access to embedded resources under {Path}";
+ set => comment = value;
+ }
+
+ public Area? NestedArea
+ {
+ get => nestedArea;
+ set
+ {
+ nestedArea = value;
+ if (nestedArea != null)
+ nestedArea.parent = this;
+ }
+ }
+
+ public string Path => parent == null ? Name : $"{parent.Path}/{Name}";
+
public IEnumerable? Resources { get; private set; }
- public static Area Load(string basePath, List resources, string rootArea = "Resources")
+ public static Area Load(string basePath, List resources, string rootArea = "Resources", string comment = "Provides access to embedded resources.")
{
- var root = new Area(rootArea);
+ var root = new Area(rootArea) { Comment = comment };
// Splits: ([area].)*[name]
var area = root;
@@ -36,9 +58,7 @@ public static Area Load(string basePath, List resources, string rootAr
{
var partStr = PathSanitizer.Sanitize(part, parent);
parent = partStr;
-
- area.NestedArea = new Area(partStr);
- area = area.NestedArea;
+ area = area.NestedArea = new Area(partStr);
}
area.Resources = resources
diff --git a/src/ThisAssembly.Resources/ResourcesGenerator.cs b/src/ThisAssembly.Resources/ResourcesGenerator.cs
index 80326fd5..fa170a92 100644
--- a/src/ThisAssembly.Resources/ResourcesGenerator.cs
+++ b/src/ThisAssembly.Resources/ResourcesGenerator.cs
@@ -42,7 +42,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
{
if (!p.GlobalOptions.TryGetValue("build_property.EmbeddedResourceStringExtensions", out var extensions) ||
extensions == null)
- return Array.Empty();
+ return [];
return extensions.Split('|');
})
diff --git a/src/ThisAssembly.Strings/CSharp.sbntxt b/src/ThisAssembly.Strings/CSharp.sbntxt
index 105ab253..966983bb 100644
--- a/src/ThisAssembly.Strings/CSharp.sbntxt
+++ b/src/ThisAssembly.Strings/CSharp.sbntxt
@@ -29,6 +29,7 @@
{{~ end ~}}
{{ end }}
{{ func render }}
+ ///
public static partial class {{ $0.Id }}
{
{{~ for value in $0.Values }}
diff --git a/src/ThisAssembly.Tests/Extensions.cs b/src/ThisAssembly.Tests/Extensions.cs
index 6385bccc..fed45d71 100644
--- a/src/ThisAssembly.Tests/Extensions.cs
+++ b/src/ThisAssembly.Tests/Extensions.cs
@@ -1,9 +1,12 @@
using System;
+///
public static class Extensions
{
+ ///
public static string ReplaceLineEndings(this string input) => ReplaceLineEndings(input, Environment.NewLine);
+ ///
public static string ReplaceLineEndings(this string input, string replacementText)
{
#if NET6_0_OR_GREATER
diff --git a/src/ThisAssembly.Tests/ScribanTests.cs b/src/ThisAssembly.Tests/ScribanTests.cs
index c0831e46..1a764321 100644
--- a/src/ThisAssembly.Tests/ScribanTests.cs
+++ b/src/ThisAssembly.Tests/ScribanTests.cs
@@ -9,8 +9,10 @@
namespace ThisAssemblyTests;
+///
public class ScribanTests(ITestOutputHelper Console)
{
+ ///
[Fact]
public void CanRenderModel()
{
diff --git a/src/ThisAssembly.Tests/Tests.cs b/src/ThisAssembly.Tests/Tests.cs
index 21bd1698..a9daf305 100644
--- a/src/ThisAssembly.Tests/Tests.cs
+++ b/src/ThisAssembly.Tests/Tests.cs
@@ -9,16 +9,20 @@
namespace ThisAssemblyTests;
+///
public record class Tests(ITestOutputHelper Output)
{
+ ///
[Fact]
public void CanReadResourceFile()
=> Assert.NotNull(ResourceFile.Load("Resources.resx", "Strings"));
+ ///
[Fact]
public void CanUseInfo()
=> Assert.Equal("ThisAssembly.Tests", ThisAssembly.Info.Title);
+ ///
[Fact]
public void CanUseInfoDescription()
=> Assert.Equal(
@@ -29,6 +33,7 @@ with a newline and
// Some comments too.
""".ReplaceLineEndings(), ThisAssembly.Info.Description.ReplaceLineEndings());
+ ///
[Fact]
public void CanUseMultilineProjectProperty()
=> Assert.Equal(
@@ -39,6 +44,7 @@ with a newline and
// Some comments too.
""".ReplaceLineEndings(), ThisAssembly.Project.Multiline.ReplaceLineEndings());
+ ///
[Fact]
public void CanUseProjectFullFileContents()
{
@@ -46,98 +52,122 @@ public void CanUseProjectFullFileContents()
Assert.False(ThisAssembly.Project.ProjectFile.StartsWith("|"));
}
+ ///
[Fact]
public void CanUseConstants()
=> Assert.Equal("Baz", ThisAssembly.Constants.Foo.Bar);
+ ///
[Fact]
public void CanUseTypedIntConstant()
=> Assert.Equal(123, ThisAssembly.Constants.TypedInt);
+ ///
[Fact]
public void CanUseTypedInt64Constant()
=> Assert.Equal(123, ThisAssembly.Constants.TypedInt64);
+ ///
[Fact]
public void CanUseTypedLongConstant()
=> Assert.Equal(123, ThisAssembly.Constants.TypedLong);
+ ///
[Fact]
public void CanUseTypedBoolConstant()
=> Assert.True(ThisAssembly.Constants.TypedBoolean);
+ ///
[Fact]
public void CanUseTypedDoubleConstant()
=> Assert.Equal(1.23, ThisAssembly.Constants.TypedDouble);
+ ///
[Fact]
public void CanUseTypedTimeSpanStaticProp()
=> Assert.Equal(TimeSpan.FromSeconds(5), ThisAssembly.Constants.TypedTimeSpan);
+ ///
[Fact]
public void CanUseFileConstants()
=> Assert.Equal(ThisAssembly.Constants.Content.Docs.License, Path.Combine("Content", "Docs", "License.md"));
+ ///
[Fact]
public void CanUseFileConstantInvalidIdentifier()
=> Assert.Equal(ThisAssembly.Constants.Content.Docs._12._Readme_copy_, Path.Combine("Content", "Docs", "12. Readme (copy).txt"));
+ ///
[Fact]
public void CanUseFileConstantLinkedFile()
=> Assert.Equal(ThisAssembly.Constants.Included.Readme, Path.Combine("Included", "Readme.txt"));
+ ///
[Fact]
public void CanUseMetadata()
=> Assert.Equal("Bar", ThisAssembly.Metadata.Foo);
+ ///
[Fact]
public void CanUseHierarchicalMetadata()
=> Assert.Equal("Baz", ThisAssembly.Metadata.Root.Foo.Bar);
+ ///
[Fact]
public void CanUseProjectProperty()
=> Assert.Equal("Bar", ThisAssembly.Project.Foo);
+ ///
[Fact]
public void CanUseStringsNamedArguments()
=> Assert.NotNull(ThisAssembly.Strings.Named("hello", "world"));
+ ///
[Fact]
public void CanUseStringsIndexedArguments()
=> Assert.NotNull(ThisAssembly.Strings.Indexed("hello", "world"));
+ ///
[Fact]
public void CanUseStringsNamedFormattedArguments()
=> Assert.Equal("Year 2020, Month 03", ThisAssembly.Strings.WithNamedFormat(new DateTime(2020, 3, 20)));
+ ///
[Fact]
public void CanUseStringsIndexedFormattedArguments()
=> Assert.Equal("Year 2020, Month 03", ThisAssembly.Strings.WithIndexedFormat(new DateTime(2020, 3, 20)));
+ ///
[Fact]
public void CanUseStringResource()
=> Assert.Equal("Value", ThisAssembly.Strings.Foo.Bar.Baz);
+ ///
[Fact]
public void CanUseTextResource()
=> Assert.NotNull(ThisAssembly.Resources.Content.Styles.Custom.Text);
+ ///
[Fact]
public void CanUseByteResource()
=> Assert.NotNull(ThisAssembly.Resources.Content.Styles.Main.GetBytes());
+ ///
[Fact]
public void CanUseSameNameDifferentExtensions()
=> Assert.NotNull(ThisAssembly.Resources.Content.Swagger.swagger_ui.css.GetBytes());
+ ///
[Fact]
public void CanUseFileInvalidCharacters()
=> Assert.NotNull(ThisAssembly.Resources.webhook_data.Text);
+ ///
[Fact]
public void CanUseGitConstants()
=> Assert.NotEmpty(ThisAssembly.Git.Commit);
+ ///
[Fact]
public void CanUseGitBranchConstants()
{
@@ -145,6 +175,7 @@ public void CanUseGitBranchConstants()
Output.WriteLine(ThisAssembly.Git.Branch);
}
+ ///
[Fact]
public void CanUseSemicolonsInConstant()
=> Assert.Equal("A;B;C", ThisAssembly.Constants.WithSemiColon);
diff --git a/src/ThisAssembly.Tests/ThisAssembly.Tests.csproj b/src/ThisAssembly.Tests/ThisAssembly.Tests.csproj
index e0eb23f8..c430c5fe 100644
--- a/src/ThisAssembly.Tests/ThisAssembly.Tests.csproj
+++ b/src/ThisAssembly.Tests/ThisAssembly.Tests.csproj
@@ -19,10 +19,12 @@
// Some comments too.
net472
ThisAssemblyTests
-
+ true
CS0618;CS8981;TA100;$(NoWarn)
false
$([System.IO.File]::ReadAllText($(MSBuildProjectFullPath)))
+ true
+ true
@@ -69,7 +71,7 @@
-
+