Skip to content

Commit

Permalink
Test Parse mountFile and mountFolder
Browse files Browse the repository at this point in the history
  • Loading branch information
thohng committed May 31, 2024
1 parent e9a59ea commit 5fbcfca
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 12 deletions.
6 changes: 6 additions & 0 deletions exclusion.dic
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
00240000048000009400000006020000002400005253413100040000010001004d00e99319a4318191d83271ebfe50641f7d06bf155b6577bdf3d8cfc4acd1b1c4423dad9ef8f96273fb89f04f9f38f46b8311ced3dcc18d302b860db3b8a12e93bcf5af95a178deb289dab8ce14ef01994a90b3623ddcec9675a8bc1a9c03c3c73da3c103777e1228438b7eacf8a205e092b2a5a480a7b1ff37c8446b4b47b4
ddcec
eacf
ebfe
buildtime
dest
ffff
fffff
ffffff
fffffff
fffzzz
healthz
hsts
json'
subpath
testhost
urls
Expand Down
4 changes: 4 additions & 0 deletions src/Hosting/Hosting.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<InternalsVisibleTo Include="Hosting.Test" Key="00240000048000009400000006020000002400005253413100040000010001004d00e99319a4318191d83271ebfe50641f7d06bf155b6577bdf3d8cfc4acd1b1c4423dad9ef8f96273fb89f04f9f38f46b8311ced3dcc18d302b860db3b8a12e93bcf5af95a178deb289dab8ce14ef01994a90b3623ddcec9675a8bc1a9c03c3c73da3c103777e1228438b7eacf8a205e092b2a5a480a7b1ff37c8446b4b47b4" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="\" />
<None Include="..\..\README.md" Pack="true" PackagePath="\" />
Expand Down
83 changes: 72 additions & 11 deletions src/Hosting/MountFileHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NetLah.Extensions.Logging;
using NetLah.Extensions.SpaServices.Hosting;

namespace Microsoft.AspNetCore.Builder;
namespace NetLah.Extensions.SpaServices.Hosting;

internal static class MountFileHelpers
{
private static readonly Lazy<ILogger?> _loggerLazy = new(() => AppLogReference.GetAppLogLogger(typeof(AppOptions).Namespace + ".MountFile"));
private static readonly StringComparer _stringComparer = OperatingSystem.IsWindows() ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
// private static readonly StringComparison _stringComparison = OperatingSystem.IsWindows() ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal

internal static Func<string, bool> ValidateDirectoryExistsDelegate { get; set; } = Directory.Exists;

private static ILogger GetLogger()
{
return _loggerLazy.Value ?? NullLogger.Instance;
}

public static void Configure(IServiceCollection services, IConfigurationRoot configuration)
{
var logger = GetLogger();
var options = ParserOptions(configuration, GetLogger());

if (options.Files.Count > 0 || options.Folders.Count > 0)
{
services.AddSingleton(options);
services.AddDecoratorAsLifetime<ISpaStaticFileProvider, MountSpaStaticFileProvider>();
}
}

public static MountFileProviderOptions ParserOptions(IConfigurationRoot configuration, ILogger logger)
{
var options = new MountFileProviderOptions
{
Files = new Dictionary<string, string>(_stringComparer),
Expand All @@ -33,13 +43,13 @@ public static void Configure(IServiceCollection services, IConfigurationRoot con
{
if (item.Value is { } keyValue)
{
if (TryParse(keyValue, out var target, out var source) && !string.IsNullOrEmpty(target) && !string.IsNullOrEmpty(source))
if (TryParseKeyValue(keyValue, out var target, out var source) && !string.IsNullOrEmpty(target) && !string.IsNullOrEmpty(source))
{
TryAddFile(target, source);
}
else
{
throw new InvalidOperationException("Invalid MountFile " + keyValue);
throw new InvalidOperationException("Invalid MountFile '" + keyValue + "'");
}
}
else
Expand All @@ -50,13 +60,28 @@ public static void Configure(IServiceCollection services, IConfigurationRoot con
}
}

if (options.Files.Count > 0 || options.Folders.Count > 0)
foreach (var item in configuration.GetSection("MountFolder").GetChildren().Concat(configuration.GetSection("MountFolders").GetChildren()))
{
services.AddSingleton(options);
services.AddDecoratorAsLifetime<ISpaStaticFileProvider, MountSpaStaticFileProvider>();
if (item.Value is { } keyValue)
{
if (TryParseKeyValue(keyValue, out var target, out var source) && !string.IsNullOrEmpty(target) && !string.IsNullOrEmpty(source))
{
TryAddFolder(target, source);
}
else
{
throw new InvalidOperationException("Invalid MountFolder '" + keyValue + "'");
}
}
else
{
var source = item["From"] ?? item["Source"] ?? item["Src"];
var target = item["Target"] ?? item["To"] ?? item["Destination"] ?? item["Dest"] ?? item["Dst"];
TryAddFolder(target, source);
}
}

bool TryParse(string keyValue, out string key, out string? value)
bool TryParseKeyValue(string keyValue, out string key, out string? value)
{
var pos = keyValue.IndexOf('=');
if (pos > 0 && pos < keyValue.Length - 1)
Expand All @@ -75,7 +100,7 @@ void TryAddFile(string? target, string? source)
{
if (string.IsNullOrEmpty(target) || !target.StartsWith('/'))
{
throw new InvalidOperationException("target have to start with /");
throw new InvalidOperationException("target has to start with / '" + target + "'");
}

if (string.IsNullOrEmpty(source))
Expand All @@ -85,7 +110,7 @@ void TryAddFile(string? target, string? source)

if (options.Files.ContainsKey(target))
{
throw new InvalidOperationException("Duplicate target " + target);
throw new InvalidOperationException("Duplicated target '" + target + "'");
}

var sourceFullPath = Path.GetFullPath(source);
Expand All @@ -94,5 +119,41 @@ void TryAddFile(string? target, string? source)

options.Files[target] = sourceFullPath;
}

void TryAddFolder(string? target, string? source)
{
if (string.IsNullOrEmpty(target) || !target.StartsWith('/'))
{
throw new InvalidOperationException("target has to start with / '" + target + "'");
}

if (string.IsNullOrEmpty(source))
{
throw new InvalidOperationException("source is required");
}

if (!target.EndsWith('/'))
{
target += '/';
}

if (options.Folders.ContainsKey(target))
{
throw new InvalidOperationException("Duplicated target '" + target + "'");
}

var sourceFullPath = Path.GetFullPath(source);

if (!ValidateDirectoryExistsDelegate(sourceFullPath))
{
throw new DirectoryNotFoundException(sourceFullPath);
}

logger.LogDebug("MountFolder target={target} source={source} {sourceFullPath}", target, source, sourceFullPath);

options.Folders[target] = sourceFullPath;
}

return options;
}
}
2 changes: 1 addition & 1 deletion src/WebApp/WebApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageReference Include="NetLah.Extensions.Configuration" />
</ItemGroup>

<ItemGroup Condition="'$(NET_6_0)' == true">
<ItemGroup Condition="'$(NET_6_0)' == true">
<PackageReference Include="Azure.Core" />
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" />
Expand Down
1 change: 1 addition & 0 deletions test/Hosting.Test/Hosting.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
<PackageReference Include="NetLah.Extensions.Configuration" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading

0 comments on commit 5fbcfca

Please sign in to comment.