Skip to content

Commit f173beb

Browse files
authored
refactor: build up real cli application (#67)
changes: - quite a lot closes #58 closes #28 closes #26 closes #25
2 parents 9a91340 + b63b7c6 commit f173beb

File tree

92 files changed

+1995
-1208
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+1995
-1208
lines changed

DDS.Tools.sln

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7673C6BF-414
77
EndProject
88
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C321AFEB-A037-43BE-BD6F-6DCF9AD96186}"
99
EndProject
10-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared.Library", "src\Shared.Library\Shared.Library.csproj", "{BF2700B8-1A02-4609-92B5-1933D3C0F18E}"
11-
EndProject
12-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PNG2DDS", "src\PNG2DDS\PNG2DDS.csproj", "{4EB04834-21E6-49A1-AAD0-91378B3B48CC}"
13-
EndProject
14-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DDS2PNG", "src\DDS2PNG\DDS2PNG.csproj", "{5D030B57-9BA1-458A-8D3C-065A185DBC09}"
15-
EndProject
16-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared.LibraryTests", "tests\Shared.LibraryTests\Shared.LibraryTests.csproj", "{D7407680-5DF3-4C48-BCD5-9DE910F10A15}"
17-
EndProject
1810
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4CEEF330-70B3-4088-9487-A72D2ACA703C}"
1911
ProjectSection(SolutionItems) = preProject
2012
.editorconfig = .editorconfig
@@ -29,37 +21,31 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
2921
README.md = README.md
3022
EndProjectSection
3123
EndProject
24+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DDS.Tools", "src\DDS.Tools\DDS.Tools.csproj", "{7411B603-3D63-4540-9162-CE460B25FF4F}"
25+
EndProject
26+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DDS.ToolsTests", "tests\DDS.ToolsTests\DDS.ToolsTests.csproj", "{C1ADCA2E-CB4B-4A80-829D-EAFC4479D9EE}"
27+
EndProject
3228
Global
3329
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3430
Debug|Any CPU = Debug|Any CPU
3531
Release|Any CPU = Release|Any CPU
3632
EndGlobalSection
3733
GlobalSection(ProjectConfigurationPlatforms) = postSolution
38-
{BF2700B8-1A02-4609-92B5-1933D3C0F18E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39-
{BF2700B8-1A02-4609-92B5-1933D3C0F18E}.Debug|Any CPU.Build.0 = Debug|Any CPU
40-
{BF2700B8-1A02-4609-92B5-1933D3C0F18E}.Release|Any CPU.ActiveCfg = Release|Any CPU
41-
{BF2700B8-1A02-4609-92B5-1933D3C0F18E}.Release|Any CPU.Build.0 = Release|Any CPU
42-
{4EB04834-21E6-49A1-AAD0-91378B3B48CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43-
{4EB04834-21E6-49A1-AAD0-91378B3B48CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
44-
{4EB04834-21E6-49A1-AAD0-91378B3B48CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
45-
{4EB04834-21E6-49A1-AAD0-91378B3B48CC}.Release|Any CPU.Build.0 = Release|Any CPU
46-
{5D030B57-9BA1-458A-8D3C-065A185DBC09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47-
{5D030B57-9BA1-458A-8D3C-065A185DBC09}.Debug|Any CPU.Build.0 = Debug|Any CPU
48-
{5D030B57-9BA1-458A-8D3C-065A185DBC09}.Release|Any CPU.ActiveCfg = Release|Any CPU
49-
{5D030B57-9BA1-458A-8D3C-065A185DBC09}.Release|Any CPU.Build.0 = Release|Any CPU
50-
{D7407680-5DF3-4C48-BCD5-9DE910F10A15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51-
{D7407680-5DF3-4C48-BCD5-9DE910F10A15}.Debug|Any CPU.Build.0 = Debug|Any CPU
52-
{D7407680-5DF3-4C48-BCD5-9DE910F10A15}.Release|Any CPU.ActiveCfg = Release|Any CPU
53-
{D7407680-5DF3-4C48-BCD5-9DE910F10A15}.Release|Any CPU.Build.0 = Release|Any CPU
34+
{7411B603-3D63-4540-9162-CE460B25FF4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{7411B603-3D63-4540-9162-CE460B25FF4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{7411B603-3D63-4540-9162-CE460B25FF4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{7411B603-3D63-4540-9162-CE460B25FF4F}.Release|Any CPU.Build.0 = Release|Any CPU
38+
{C1ADCA2E-CB4B-4A80-829D-EAFC4479D9EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39+
{C1ADCA2E-CB4B-4A80-829D-EAFC4479D9EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
40+
{C1ADCA2E-CB4B-4A80-829D-EAFC4479D9EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
41+
{C1ADCA2E-CB4B-4A80-829D-EAFC4479D9EE}.Release|Any CPU.Build.0 = Release|Any CPU
5442
EndGlobalSection
5543
GlobalSection(SolutionProperties) = preSolution
5644
HideSolutionNode = FALSE
5745
EndGlobalSection
5846
GlobalSection(NestedProjects) = preSolution
59-
{BF2700B8-1A02-4609-92B5-1933D3C0F18E} = {7673C6BF-414E-4F80-8F88-C4F1F5F379E7}
60-
{4EB04834-21E6-49A1-AAD0-91378B3B48CC} = {7673C6BF-414E-4F80-8F88-C4F1F5F379E7}
61-
{5D030B57-9BA1-458A-8D3C-065A185DBC09} = {7673C6BF-414E-4F80-8F88-C4F1F5F379E7}
62-
{D7407680-5DF3-4C48-BCD5-9DE910F10A15} = {C321AFEB-A037-43BE-BD6F-6DCF9AD96186}
47+
{7411B603-3D63-4540-9162-CE460B25FF4F} = {7673C6BF-414E-4F80-8F88-C4F1F5F379E7}
48+
{C1ADCA2E-CB4B-4A80-829D-EAFC4479D9EE} = {C321AFEB-A037-43BE-BD6F-6DCF9AD96186}
6349
EndGlobalSection
6450
GlobalSection(ExtensibilityGlobals) = postSolution
6551
SolutionGuid = {265C5FBE-91B4-42C2-9B45-E0E3E39D57AB}

Directory.Build.props

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@
3636
<Authors>$(Author)</Authors>
3737
<Company>https://github.com/$(Author)</Company>
3838
<Copyright>Copyright © $(VersionMajor) $(Author)</Copyright>
39-
<Description>This is a simple DDS and PNG tool set.</Description>
39+
<Description>
40+
This is a simple DDS and PNG tool set that converts DDS images to PNG images and vice versa on a large scale.
41+
Has options for duplicate detection and sorting.
42+
</Description>
4043
<NeutralLanguage>en-US</NeutralLanguage>
4144
<PackageLicenseFile>LICENSE</PackageLicenseFile>
4245
<PackageProjectUrl>https://github.com/$(Author)/$(Product)</PackageProjectUrl>
@@ -64,10 +67,13 @@
6467
</ItemGroup>
6568

6669
<ItemGroup Condition="$(MSBuildProjectName.EndsWith('Tests'))">
70+
<PackageReference Include="coverlet.collector">
71+
<PrivateAssets>all</PrivateAssets>
72+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
73+
</PackageReference>
6774
<PackageReference Include="Microsoft.NET.Test.Sdk" />
6875
<PackageReference Include="MSTest.TestAdapter" />
6976
<PackageReference Include="MSTest.TestFramework" />
70-
<PackageReference Include="coverlet.collector" />
7177
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
7278
<Using Include="System.Diagnostics" />
7379
<Using Include="System.Diagnostics.CodeAnalysis" />

Directory.Packages.props

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<Project>
2-
32
<PropertyGroup>
43
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
54
</PropertyGroup>
6-
75
<ItemGroup>
86
<PackageVersion Include="BB84.Extensions" Version="2.2.0" />
97
<PackageVersion Include="BCnEncoder.Net" Version="2.1.0" />
108
<PackageVersion Include="BCnEncoder.Net.ImageSharp" Version="1.1.1" />
11-
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.3" />
12-
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
13-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
149
<PackageVersion Include="MSTest.TestAdapter" Version="3.2.2" />
1510
<PackageVersion Include="MSTest.TestFramework" Version="3.2.2" />
11+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
12+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
13+
<PackageVersion Include="SixLabors.ImageSharp" Version="3.1.3" />
14+
<PackageVersion Include="Spectre.Console" Version="0.48.0" />
15+
<PackageVersion Include="Spectre.Console.Cli" Version="0.48.0" />
16+
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
1617
<PackageVersion Include="coverlet.collector" Version="6.0.1" />
1718
</ItemGroup>
18-
1919
</Project>

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"sdk": {
3-
"version": "8.0.100",
3+
"version": "8.0.200",
44
"allowPrerelease": false,
55
"rollForward": "major"
66
},
77
"tools": {
8-
"dotnet": "8.0.100"
8+
"dotnet": "8.0.200"
99
}
1010
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using DDS.Tools.Common;
2+
using DDS.Tools.Enumerators;
3+
using DDS.Tools.Exceptions;
4+
using DDS.Tools.Interfaces.Services;
5+
using DDS.Tools.Models;
6+
using DDS.Tools.Settings.Base;
7+
8+
using Spectre.Console;
9+
using Spectre.Console.Cli;
10+
11+
namespace DDS.Tools.Commands.Base;
12+
13+
/// <summary>
14+
/// The convert command base class.
15+
/// </summary>
16+
/// <inheritdoc/>
17+
internal abstract class ConvertCommandBase<TSettings>(ITodoService todoService) : Command<TSettings> where TSettings : CommandSettings
18+
{
19+
protected int Action(ConvertSettingsBase settings, ImageType imageType)
20+
{
21+
TodoCollection todos;
22+
23+
if (!Directory.Exists(settings.SourceFolder))
24+
throw new CommandException($"Directory '{settings.SourceFolder}' not found.");
25+
26+
string jsonFilePath = Path.Combine(settings.SourceFolder, Constants.ResultFileName);
27+
bool jsonExists = ResultJsonExists(jsonFilePath);
28+
29+
if (!jsonExists)
30+
{
31+
todos = todoService.GetTodos(settings, imageType);
32+
return GetItDone(todoService, todos, settings, imageType, jsonExists);
33+
}
34+
else
35+
{
36+
string jsonFileContent = File.ReadAllText(jsonFilePath);
37+
todos = todoService.GetTodos(settings, imageType, jsonFileContent);
38+
return GetItDone(todoService, todos, settings, imageType, jsonExists);
39+
}
40+
}
41+
42+
private static bool ResultJsonExists(string jsonFilePath) => File.Exists(jsonFilePath);
43+
44+
private static int GetItDone(ITodoService todoService, TodoCollection todos, ConvertSettingsBase settings, ImageType imageType, bool jsonExists)
45+
{
46+
if (todos.Count.Equals(0))
47+
{
48+
AnsiConsole.MarkupLine($"[yellow]There is nothing todo![/]");
49+
return 1;
50+
}
51+
52+
todoService.GetTodosDone(todos, settings, imageType, jsonExists);
53+
return 0;
54+
}
55+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
using DDS.Tools.Commands.Base;
4+
using DDS.Tools.Enumerators;
5+
using DDS.Tools.Interfaces.Services;
6+
using DDS.Tools.Settings;
7+
8+
using Microsoft.Extensions.Logging;
9+
10+
using Spectre.Console;
11+
using Spectre.Console.Cli;
12+
13+
namespace DDS.Tools.Commands;
14+
15+
/// <summary>
16+
/// The dds convert command class.
17+
/// </summary>
18+
/// <param name="loggerService">The logger service instance to use.</param>
19+
/// <param name="todoService">The todo service instance to use.</param>
20+
internal sealed class DdsConvertCommand(ILoggerService<DdsConvertCommand> loggerService, ITodoService todoService) : ConvertCommandBase<DdsConvertSettings>(todoService)
21+
{
22+
private const ImageType Type = ImageType.DDS;
23+
private readonly ILoggerService<DdsConvertCommand> _loggerService = loggerService;
24+
25+
private static readonly Action<ILogger, Exception?> LogException =
26+
LoggerMessage.Define(LogLevel.Error, 0, "Exception occured.");
27+
28+
/// <inheritdoc/>
29+
public override int Execute([NotNull] CommandContext context, [NotNull] DdsConvertSettings settings)
30+
{
31+
try
32+
{
33+
return AnsiConsole.Status()
34+
.Spinner(Spinner.Known.Line)
35+
.Start("Processing..", action => Action(settings, Type));
36+
}
37+
catch (Exception ex)
38+
{
39+
_loggerService.Log(LogException, ex);
40+
AnsiConsole.MarkupLine($"[maroon]{ex.Message}[/]");
41+
return 1;
42+
}
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
using DDS.Tools.Commands.Base;
4+
using DDS.Tools.Enumerators;
5+
using DDS.Tools.Interfaces.Services;
6+
using DDS.Tools.Settings;
7+
8+
using Microsoft.Extensions.Logging;
9+
10+
using Spectre.Console;
11+
using Spectre.Console.Cli;
12+
13+
namespace DDS.Tools.Commands;
14+
15+
/// <summary>
16+
/// The png convert command class.
17+
/// </summary>
18+
/// <param name="loggerService">The logger service instance to use.</param>
19+
/// <param name="todoService">The todo service instance to use.</param>
20+
internal sealed class PngConvertCommand(ILoggerService<DdsConvertCommand> loggerService, ITodoService todoService) : ConvertCommandBase<PngConvertSettings>(todoService)
21+
{
22+
private const ImageType Type = ImageType.PNG;
23+
private readonly ILoggerService<DdsConvertCommand> _loggerService = loggerService;
24+
25+
private static readonly Action<ILogger, Exception?> LogException =
26+
LoggerMessage.Define(LogLevel.Error, 0, "Exception occured.");
27+
28+
/// <inheritdoc/>
29+
public override int Execute([NotNull] CommandContext context, [NotNull] PngConvertSettings settings)
30+
{
31+
try
32+
{
33+
return AnsiConsole.Status()
34+
.Spinner(Spinner.Known.Line)
35+
.Start("Processing..", action => Action(settings, Type));
36+
}
37+
catch (Exception ex)
38+
{
39+
_loggerService.Log(LogException, ex);
40+
AnsiConsole.MarkupLine($"[maroon]{ex.Message}[/]");
41+
return 1;
42+
}
43+
}
44+
}

src/DDS.Tools/Common/Constants.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace DDS.Tools.Common;
2+
3+
/// <summary>
4+
/// The constants class.
5+
/// </summary>
6+
internal static class Constants
7+
{
8+
/// <summary>
9+
/// The result json file name.
10+
/// </summary>
11+
internal const string ResultFileName = "Result.json";
12+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Hosting;
5+
6+
using Spectre.Console.Cli;
7+
8+
namespace DDS.Tools.Common;
9+
10+
/// <summary>
11+
/// The type registrar class.
12+
/// </summary>
13+
/// <param name="builder">The host builder instance to use.</param>
14+
[ExcludeFromCodeCoverage]
15+
internal sealed class TypeRegistrar(IHostBuilder builder) : ITypeRegistrar
16+
{
17+
private readonly IHostBuilder _builder = builder;
18+
19+
public ITypeResolver Build()
20+
=> new TypeResolver(_builder.Build());
21+
22+
public void Register(Type service, Type implementation)
23+
=> _builder.ConfigureServices((_, services) => services.AddSingleton(service, implementation));
24+
25+
public void RegisterInstance(Type service, object implementation)
26+
=> _builder.ConfigureServices((_, services) => services.AddSingleton(service, implementation));
27+
28+
public void RegisterLazy(Type service, Func<object> func)
29+
{
30+
ArgumentNullException.ThrowIfNull(func);
31+
32+
_ = _builder.ConfigureServices((_, services) => services.AddSingleton(service, _ => func()));
33+
}
34+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Diagnostics.CodeAnalysis;
2+
3+
using Microsoft.Extensions.Hosting;
4+
5+
using Spectre.Console.Cli;
6+
7+
namespace DDS.Tools.Common;
8+
9+
/// <summary>
10+
/// The type resolver class.
11+
/// </summary>
12+
/// <param name="provider">The host provider instance to use.</param>
13+
[ExcludeFromCodeCoverage]
14+
internal sealed class TypeResolver(IHost provider) : ITypeResolver, IDisposable
15+
{
16+
private readonly IHost _host = provider ?? throw new ArgumentNullException(nameof(provider));
17+
18+
public object? Resolve(Type? type)
19+
=> type is not null ? _host.Services.GetService(type) : null;
20+
21+
public void Dispose()
22+
=> _host.Dispose();
23+
}

0 commit comments

Comments
 (0)