refactor: Merge Project/Runtime Settings

Merge the RuntimeSettings class into ProjectSettings,
Minimising the duplication of stored data
This commit is contained in:
Robert Morrison 2024-06-03 02:54:38 +01:00
parent 0db8101662
commit 34bf088c78
Signed by: robert
GPG Key ID: 73E012EB3F4EC696
5 changed files with 42 additions and 83 deletions

View File

@ -149,21 +149,14 @@ class Program
AnsiConsole.Console.Profile.Capabilities.Ansi = true; AnsiConsole.Console.Profile.Capabilities.Ansi = true;
// NOTE: Future refactors may merge ProjectSettings and RuntimeSettings ProjectSettings settings = GetProjectSettings(ProjectDirectory);
ProjectSettings projectSettings = GetProjectSettings(ProjectDirectory);
DirectoryInfo inputDir = new(projectSettings.Source);
DirectoryInfo outputDir = new(projectSettings.Destination);
RuntimeSettings settings = new(inputDir,outputDir);
settings.setBaseUrl(projectSettings.BaseUrl);
List<SiteFile> siteFiles = new(); List<SiteFile> siteFiles = new();
Utils.GetFiles(inputDir).ForEach(x => siteFiles.Add(new SiteFile(x))); Utils.GetFiles(settings.InputDirectory).ForEach(x => siteFiles.Add(new SiteFile(x)));
Log.Information("SiteFiles: {@sf} {count}", siteFiles, siteFiles.Count); Log.Information("SiteFiles: {@sf} {count}", siteFiles, siteFiles.Count);
Console.WriteLine($"Converting {siteFiles.Count} files from {inputDir.FullName} to {outputDir.FullName}"); Console.WriteLine($"Converting {siteFiles.Count} files from {settings.InputDirectory.FullName} to {settings.OutputDirectory.FullName}");
Dictionary<string,bool> fileStatus = new(); Dictionary<string,bool> fileStatus = new();
@ -224,40 +217,36 @@ class Program
{ {
Log.Information("Clean command was called, Beginning cleaning"); Log.Information("Clean command was called, Beginning cleaning");
// NOTE: Future refactors may merge ProjectSettings and RuntimeSettings ProjectSettings settings = GetProjectSettings(ProjectDirectory);
ProjectSettings projectSettings = GetProjectSettings(ProjectDirectory);
DirectoryInfo inputDir = new(projectSettings.Source); if (!settings.OutputDirectory.Exists)
DirectoryInfo outputDir = new(projectSettings.Destination);
if (!outputDir.Exists)
{ {
Log.Warning("Not deleting {dir} as it doesn't exist",outputDir.FullName); Log.Warning("Not deleting {dir} as it doesn't exist",settings.OutputDirectory.FullName);
AnsiConsole.MarkupLineInterpolated($"[bold][[[yellow]Warning[/]]][/] Not cleaning [blue]\"{outputDir}\"[/] as it does not exist."); AnsiConsole.MarkupLineInterpolated($"[bold][[[yellow]Warning[/]]][/] Not cleaning [blue]\"{settings.OutputDirectory.FullName}\"[/] as it does not exist.");
return 0; // success because it doesn't exist. return 0; // success because it doesn't exist.
} }
try try
{ {
Log.Information("Cleaning {dir}",outputDir.FullName); Log.Information("Cleaning {dir}",settings.OutputDirectory.FullName);
AnsiConsole.MarkupInterpolated($"Cleaning [blue]\"{outputDir.FullName}\"[/]"); AnsiConsole.MarkupInterpolated($"Cleaning [blue]\"{settings.OutputDirectory.FullName}\"[/]");
outputDir.Delete(recursive: true); settings.OutputDirectory.Delete(recursive: true);
outputDir.Create(); settings.OutputDirectory.Create();
AnsiConsole.MarkupLine(" [bold][[[green]OK[/]]][/]"); AnsiConsole.MarkupLine(" [bold][[[green]OK[/]]][/]");
AnsiConsole.MarkupLineInterpolated($"\t[grey]>>[/] [green]All files in {outputDir.FullName} purged successfully[/]"); AnsiConsole.MarkupLineInterpolated($"\t[grey]>>[/] [green]All files in {settings.OutputDirectory.FullName} purged successfully[/]");
return 0; return 0;
} }
catch (System.Security.SecurityException e) catch (System.Security.SecurityException e)
{ {
AnsiConsole.MarkupLine(" [bold][[[red]Fail[/]]][/]"); AnsiConsole.MarkupLine(" [bold][[[red]Fail[/]]][/]");
AnsiConsole.MarkupLine("[orangered1]See log for more details about what went wrong.[/]"); AnsiConsole.MarkupLine("[orangered1]See log for more details about what went wrong.[/]");
Log.Error(e, "Failed to delete directory {dir} due to permission error.", outputDir.FullName); Log.Error(e, "Failed to delete directory {dir} due to permission error.", settings.OutputDirectory.FullName);
return 1; return 1;
} }
catch (Exception e) catch (Exception e)
{ {
AnsiConsole.MarkupLine(" [red][[[bold]Fail[/]]][/]"); AnsiConsole.MarkupLine(" [red][[[bold]Fail[/]]][/]");
AnsiConsole.MarkupLine("[orangered1]See log for more details about what went wrong.[/]"); AnsiConsole.MarkupLine("[orangered1]See log for more details about what went wrong.[/]");
Log.Error(e, "Failed to delete/create directory {dir}", outputDir.FullName); Log.Error(e, "Failed to delete/create directory {dir}", settings.OutputDirectory.FullName);
return 1; return 1;
} }
} }

View File

@ -2,32 +2,33 @@ using System.Text.Json.Serialization;
// project settings is a user accessible config to set the Source and destination of a site // project settings is a user accessible config to set the Source and destination of a site
// This may include more scope in the future such as holding the site base address etc.. // This may include more scope in the future such as holding the site base address etc..
class ProjectSettings public class ProjectSettings
{ {
private string _Source; // The Source and Destination need to be public for the json constructor to work properly.
private string _Destination; public string Source {get; private set;}
public string Destination {get; private set;}
private DirectoryInfo? _ProjectRoot; private DirectoryInfo? _ProjectRoot;
public string? BaseUrl {get; private set;} public string? BaseUrl {get; private set;}
public string Source {get { public DirectoryInfo InputDirectory {get {
if (_ProjectRoot is null) if (_ProjectRoot is null)
{ {
return _Source; return new(Source);
} }
return Path.Combine(_ProjectRoot.FullName,_Source); return new(Path.Combine(_ProjectRoot.FullName,Source));
}} }}
public string Destination {get { public DirectoryInfo OutputDirectory {get {
if (_ProjectRoot is null) if (_ProjectRoot is null)
{ {
return _Destination; return new(Destination);
} }
return Path.Combine(_ProjectRoot.FullName,_Destination); return new(Path.Combine(_ProjectRoot.FullName,Destination));
}} }}
[JsonConstructor] [JsonConstructor]
public ProjectSettings(String source, String destination, string baseUrl) { public ProjectSettings(String source, String destination, string baseUrl) {
_Source = source; Source = source;
_Destination = destination; Destination = destination;
BaseUrl = baseUrl; BaseUrl = baseUrl;
} }
@ -38,7 +39,9 @@ class ProjectSettings
_ProjectRoot = projectRoot; _ProjectRoot = projectRoot;
} }
public void setBaseUrl(string baseUrl) { /*
BaseUrl = baseUrl; * public void setBaseUrl(string baseUrl) {
} * BaseUrl = baseUrl;
* }
*/
} }

View File

@ -1,33 +0,0 @@
namespace csSiteGen;
/// <summary>
/// Class <c>RuntimeSettings</c> Contains all the settings that could be loaded from the commandline.
/// </summary>
public class RuntimeSettings {
public DirectoryInfo InputDirectory {get; private set;}
public DirectoryInfo OutputDirectory {get; private set;}
public string? BaseUrl {get; private set;}
public RuntimeSettings(string inputDirectory, string outputDirectory){
InputDirectory = new DirectoryInfo(inputDirectory);
OutputDirectory = new DirectoryInfo(outputDirectory);
/* NOTE: it is the responisbility of the UI code to check the values passed are good.
*/
}
public RuntimeSettings(DirectoryInfo inputDirectory, DirectoryInfo outputDirectory){
InputDirectory = inputDirectory;
OutputDirectory = outputDirectory;
/* NOTE: it is the responisbility of the UI code to check the values passed are good.
*/
}
public void setBaseUrl(string? baseurl) {
BaseUrl = baseurl;
}
}

View File

@ -6,7 +6,7 @@ namespace csSiteGen;
public static class Conversions{ public static class Conversions{
public delegate bool ConvertFunc(FileInfo file, RuntimeSettings settings); public delegate bool ConvertFunc(FileInfo file, ProjectSettings settings);
/// <summary> /// <summary>
/// A Mapping of filetype to ConvertFunc. /// A Mapping of filetype to ConvertFunc.
@ -24,7 +24,7 @@ public static class Conversions{
/// <summary> /// <summary>
/// TEST FUNCTION. /// TEST FUNCTION.
/// </summary> /// </summary>
public static bool NoOp(FileInfo file, RuntimeSettings settings){ public static bool NoOp(FileInfo file, ProjectSettings settings){
Log.Information("Performing NoOp Conversion"); Log.Information("Performing NoOp Conversion");
string newName = GetNewName(file,settings,"NoOp"); string newName = GetNewName(file,settings,"NoOp");
Log.Debug("{FullName} -> {newName}",file.FullName,newName); Log.Debug("{FullName} -> {newName}",file.FullName,newName);
@ -35,7 +35,7 @@ public static class Conversions{
/// <summary> /// <summary>
/// Copy the file verbatim (doing any baseurl replacements if needed) /// Copy the file verbatim (doing any baseurl replacements if needed)
/// </summary> /// </summary>
public static bool RawCpy(FileInfo file, RuntimeSettings settings){ public static bool RawCpy(FileInfo file, ProjectSettings settings){
FileInfo newPath = new FileInfo(GetNewName(file,settings,null)); FileInfo newPath = new FileInfo(GetNewName(file,settings,null));
Log.Information("RawCpy: Copying {file} to {dest}",file.FullName, newPath.FullName); Log.Information("RawCpy: Copying {file} to {dest}",file.FullName, newPath.FullName);
@ -65,7 +65,7 @@ public static class Conversions{
/// <summary> /// <summary>
/// Execute pandoc on the file, automatically detecting the template to use. /// Execute pandoc on the file, automatically detecting the template to use.
/// </summary> /// </summary>
public static bool Pandoc(FileInfo file, RuntimeSettings settings){ public static bool Pandoc(FileInfo file, ProjectSettings settings){
// NOTE: Some of the code later where the tmpfile is created for baseurl replacement may be too safe. // NOTE: Some of the code later where the tmpfile is created for baseurl replacement may be too safe.
// the extension checks may be unnecessary, but this depends on if this function will be retooled to run pandoc for different conversions. // the extension checks may be unnecessary, but this depends on if this function will be retooled to run pandoc for different conversions.
// for now I have take the safer approach, but the leaner approach may be used in the future when the project is more mature // for now I have take the safer approach, but the leaner approach may be used in the future when the project is more mature
@ -208,13 +208,13 @@ public static class Conversions{
return true; return true;
} }
private static string GetNewName(FileInfo file, RuntimeSettings settings, string? newExtension){ private static string GetNewName(FileInfo file, ProjectSettings settings, string? newExtension){
return file.FullName return file.FullName
.Replace(settings.InputDirectory.FullName, settings.OutputDirectory.FullName) .Replace(settings.InputDirectory.FullName, settings.OutputDirectory.FullName)
.Replace(file.Extension,newExtension ?? file.Extension); .Replace(file.Extension,newExtension ?? file.Extension);
} }
private static string? BaseUrlReplace(FileInfo file, RuntimeSettings settings){ private static string? BaseUrlReplace(FileInfo file, ProjectSettings settings){
Log.Information("Doing BaseUrlReplace for {f}", file.FullName); Log.Information("Doing BaseUrlReplace for {f}", file.FullName);
// Read the file // Read the file
using (StreamReader FileReader = file.OpenText()) using (StreamReader FileReader = file.OpenText())

View File

@ -30,7 +30,7 @@ public partial class SiteFile
Log.Information("{file} extension is {ext}",fileInfo.FullName, fileInfo.Extension); Log.Information("{file} extension is {ext}",fileInfo.FullName, fileInfo.Extension);
// Using this Ensures that the ConverterFunction is Always set. // Using this Ensures that the ConverterFunction is Always set.
// ConverterFunctions ALWAYS accept just the FileInfo, and RuntimeSettings passed at convert time. // ConverterFunctions ALWAYS accept just the FileInfo, and ProjectSettings passed at convert time.
ConverterFunction = Conversions.Mappings.GetValueOrDefault(info.Extension, Conversions.RawCpy); ConverterFunction = Conversions.Mappings.GetValueOrDefault(info.Extension, Conversions.RawCpy);
} }
@ -38,7 +38,7 @@ public partial class SiteFile
/// Convert the file, placing it in the correct place in the output directory. /// Convert the file, placing it in the correct place in the output directory.
/// If a filetype conversion is not needed, or specified, then the file is simply copied. /// If a filetype conversion is not needed, or specified, then the file is simply copied.
/// </summary> /// </summary>
public bool Convert(RuntimeSettings settings) public bool Convert(ProjectSettings settings)
{ {
if (!NeedsUpdating(settings)) if (!NeedsUpdating(settings))
{ {
@ -65,7 +65,7 @@ public partial class SiteFile
return res; return res;
} }
private bool NeedsUpdating(RuntimeSettings settings) private bool NeedsUpdating(ProjectSettings settings)
{ {
if (Metadata is null) if (Metadata is null)
{ {
@ -87,7 +87,7 @@ public partial class SiteFile
* But that ensures that if you remove the output directory the site will be * But that ensures that if you remove the output directory the site will be
* Fully recreated. * Fully recreated.
*/ */
private void LoadMetadata(RuntimeSettings settings) private void LoadMetadata(ProjectSettings settings)
{ {
string metaFile = $"{settings.OutputDirectory}/.files"; string metaFile = $"{settings.OutputDirectory}/.files";
Log.Information("Loading Metadata from {file}",metaFile); Log.Information("Loading Metadata from {file}",metaFile);
@ -113,7 +113,7 @@ public partial class SiteFile
} }
} }
private void SaveMetadata(RuntimeSettings settings) private void SaveMetadata(ProjectSettings settings)
{ {
if (Metadata is null) if (Metadata is null)
{ {