feat: Add support for removing deleted source files
Detects files removed from the source directory, deletes the file from destination, removes it from the metadata cache.
This commit is contained in:
parent
264129b1e9
commit
da24073f14
38
Program.cs
38
Program.cs
|
|
@ -16,10 +16,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using Serilog.Events;
|
||||
using Serilog;
|
||||
using System.CommandLine.Builder;
|
||||
using System.CommandLine.Help;
|
||||
using System.CommandLine.Parsing;
|
||||
using System.CommandLine;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -209,7 +207,7 @@ class Program
|
|||
AnsiConsole.MarkupLine("[yellow]See log for more details[/]");
|
||||
}
|
||||
}
|
||||
|
||||
EnforceConsistency(settings);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -253,17 +251,37 @@ class Program
|
|||
|
||||
static void EnforceConsistency(ProjectSettings projectSettings)
|
||||
{
|
||||
AnsiConsole.MarkupLine("[blue]Checking for stale files[/]");
|
||||
// Grab the metadata.
|
||||
|
||||
List<string> staleMetadataFiles = new();
|
||||
var metadata = SiteFile.getMetadata(projectSettings);
|
||||
// Read the metadata.
|
||||
foreach (var entry in metadata)
|
||||
{
|
||||
var file = entry.Key;
|
||||
Log.Information("Checking if {f} has been deleted", file);
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
Log.Information("{f} HAS been deleted", file);
|
||||
|
||||
// Find deleted files.
|
||||
|
||||
// Figure out what the new name for those files would be.
|
||||
|
||||
// Remove those files.
|
||||
|
||||
// what should that files new name be.
|
||||
var newFileName = Conversions.GetNewName(new FileInfo(file),projectSettings);
|
||||
try{
|
||||
// Delete that file and mark the metadata for removal.
|
||||
File.Delete(newFileName);
|
||||
AnsiConsole.MarkupLineInterpolated($"[red]Deleted [blue]{newFileName}[/][/]");
|
||||
Log.Information("Deleted {f}",newFileName);
|
||||
staleMetadataFiles.Add(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e,"Could not delete {f}",newFileName);
|
||||
}
|
||||
}
|
||||
SiteFile.invalidateMetadata(staleMetadataFiles,projectSettings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ProjectSettings GetProjectSettings(DirectoryInfo? ProjectDirectory)
|
||||
{
|
||||
|
|
|
|||
10
Readme.md
10
Readme.md
|
|
@ -57,8 +57,6 @@ It only considers source files for conversion if they are new or have been
|
|||
changed since the last run of the program.
|
||||
Therefore if you change the `BaseUrl` or the template file you will need to
|
||||
clean and convert your entire project.
|
||||
Convert also does not detect deleted source files at the moment, so you
|
||||
will also need to clean for that,
|
||||
|
||||
#### clean
|
||||
This subcommand purges the output directory, You can of course do this
|
||||
|
|
@ -85,11 +83,7 @@ unless you want to structure everything to the point you only need relative
|
|||
links. (I personally found this almost impossible)
|
||||
|
||||
## Future plans
|
||||
- Automatic page generation using pre-process steps and temporary files.
|
||||
E.G Contents pages, index pages etc...(DIFFICULT)
|
||||
- Automatic page generation using pre-process steps and temporary files. E.G Contents pages, index pages etc...(DIFFICULT)
|
||||
- Detection of changes to the `BaseUrl` and any templates. (MEDIUM)
|
||||
- Detection of deleted source files and removal of the destination
|
||||
files.(MEDIUM)
|
||||
- Allow expansion of conversion operations (DIFFICULT)
|
||||
- Allow customisation of filetypes that can have `%BASEURL%` replaced
|
||||
(EASY-MEDIUM)
|
||||
- Allow customisation of filetypes that can have `%BASEURL%` replaced (EASY-MEDIUM)
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ public static class Conversions{
|
|||
/// <summary>
|
||||
/// A Mapping of filetype to ConvertFunc.
|
||||
/// </summary>
|
||||
public static readonly Dictionary<string,ConvertFunc> Mappings = new(){
|
||||
{".md", Pandoc},
|
||||
public static readonly Dictionary<string,(ConvertFunc function,string extension)> Mappings = new(){
|
||||
{".md", (Pandoc, ".html")},
|
||||
};
|
||||
|
||||
private static readonly string[] StringReplaceFiletypes = {
|
||||
|
|
@ -26,7 +26,7 @@ public static class Conversions{
|
|||
/// </summary>
|
||||
public static bool NoOp(FileInfo file, ProjectSettings settings){
|
||||
Log.Information("Performing NoOp Conversion");
|
||||
string newName = GetNewName(file,settings,"NoOp");
|
||||
string newName = GetNewName(file,settings);
|
||||
Log.Debug("{FullName} -> {newName}",file.FullName,newName);
|
||||
Thread.Sleep(1500);
|
||||
return true;
|
||||
|
|
@ -36,7 +36,7 @@ public static class Conversions{
|
|||
/// Copy the file verbatim (doing any baseurl replacements if needed)
|
||||
/// </summary>
|
||||
public static bool RawCpy(FileInfo file, ProjectSettings settings){
|
||||
FileInfo newPath = new FileInfo(GetNewName(file,settings,null));
|
||||
FileInfo newPath = new FileInfo(GetNewName(file,settings));
|
||||
|
||||
Log.Information("RawCpy: Copying {file} to {dest}",file.FullName, newPath.FullName);
|
||||
|
||||
|
|
@ -133,11 +133,11 @@ public static class Conversions{
|
|||
// If we have created a temporary file we need to ensure that we use it.
|
||||
if (!string.IsNullOrEmpty(tmpFile))
|
||||
{
|
||||
pandocArgs = $"{tmpFile} -o {GetNewName(file,settings,".html")}";
|
||||
pandocArgs = $"{tmpFile} -o {GetNewName(file,settings)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
pandocArgs = $"{file.FullName} -o {GetNewName(file,settings,".html")}";
|
||||
pandocArgs = $"{file.FullName} -o {GetNewName(file,settings)}";
|
||||
}
|
||||
|
||||
if (template is not null)
|
||||
|
|
@ -156,9 +156,9 @@ public static class Conversions{
|
|||
// This is used in my template to add the sitename to the title element.
|
||||
pandocArgs += $" --metadata=\"SiteName:{settings.SiteName}\"";
|
||||
}
|
||||
if (!Directory.Exists(Path.GetDirectoryName(GetNewName(file,settings,".html"))))
|
||||
if (!Directory.Exists(Path.GetDirectoryName(GetNewName(file,settings))))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(GetNewName(file,settings,".html"))!);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(GetNewName(file,settings))!);
|
||||
}
|
||||
|
||||
bool pandocReturn = RunExternalProgram(pandoc,pandocArgs);
|
||||
|
|
@ -214,10 +214,11 @@ public static class Conversions{
|
|||
return true;
|
||||
}
|
||||
|
||||
private static string GetNewName(FileInfo file, ProjectSettings settings, string? newExtension){
|
||||
public static string GetNewName(FileInfo file, ProjectSettings settings){
|
||||
var newExtension = Mappings.GetValueOrDefault(file.Extension,(RawCpy,file.Extension)).extension;
|
||||
return file.FullName
|
||||
.Replace(settings.InputDirectory.FullName, settings.OutputDirectory.FullName)
|
||||
.Replace(file.Extension,newExtension ?? file.Extension);
|
||||
.Replace(file.Extension,newExtension);
|
||||
}
|
||||
|
||||
private static string StringReplace(FileInfo file, ProjectSettings settings){
|
||||
|
|
|
|||
|
|
@ -12,6 +12,36 @@ public partial class SiteFile
|
|||
Conversions.ConvertFunc ConverterFunction;
|
||||
static Dictionary<string, DateTime>? Metadata = null;
|
||||
|
||||
/// <summary>
|
||||
/// Get the metadata for the current project, loading it if not already loaded.
|
||||
/// </summary>
|
||||
/// <param name="settings">
|
||||
/// The current <c>ProjectSettings</c>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <c>Dictionary<string,DateTime></c> that represents the metadata stored.
|
||||
/// </returns>
|
||||
public static Dictionary<string,DateTime> getMetadata(ProjectSettings settings) {
|
||||
if (Metadata is null)
|
||||
{
|
||||
LoadMetadata(settings);
|
||||
}
|
||||
return Metadata?? new(); // Metadata is unlikely(if not impossible) to be null here but the compiler isn't convinced
|
||||
}
|
||||
|
||||
public static void invalidateMetadata(List<string> files, ProjectSettings settings)
|
||||
{
|
||||
if (Metadata is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
files.ForEach( file => {
|
||||
Metadata.Remove(file);
|
||||
});
|
||||
|
||||
SaveMetadata(settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the file, Not Guaranteed to be unique.
|
||||
/// Use only for output and logging, never file operations,
|
||||
|
|
@ -32,7 +62,7 @@ public partial class SiteFile
|
|||
Log.Debug("{file} extension is {ext}",fileInfo.FullName, fileInfo.Extension);
|
||||
// Using this Ensures that the ConverterFunction is Always set.
|
||||
// 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,info.Extension)).function;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -88,7 +118,7 @@ public partial class SiteFile
|
|||
* But that ensures that if you remove the output directory the site will be
|
||||
* Fully recreated.
|
||||
*/
|
||||
private void LoadMetadata(ProjectSettings settings)
|
||||
private static void LoadMetadata(ProjectSettings settings)
|
||||
{
|
||||
string metaFile = $"{settings.OutputDirectory}/.files";
|
||||
Log.Information("Loading Metadata from {file}",metaFile);
|
||||
|
|
@ -114,7 +144,7 @@ public partial class SiteFile
|
|||
}
|
||||
}
|
||||
|
||||
private void SaveMetadata(ProjectSettings settings)
|
||||
private static void SaveMetadata(ProjectSettings settings)
|
||||
{
|
||||
if (Metadata is null)
|
||||
{
|
||||
|
|
|
|||
3
TODO
3
TODO
|
|
@ -1,5 +1,2 @@
|
|||
- Make the code such that the metadata file knows what source file an output file came from, this will allow us to delete files from source
|
||||
and force consistency by removing them from the dst directory too.
|
||||
|
||||
- Add a pre-commit or other type of hook to ensure that the Testing directory is properly cleaned and reset before commit.
|
||||
- Ensure that the .gitkeep file is placed into Testing/dst
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
|
||||
<Version Condition="'$(RELEASE_VERSION)' != ''">$(RELEASE_VERSION)</Version>
|
||||
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.2</VersionPrefix>
|
||||
<VersionPrefix Condition="'$(RELEASE_VERSION)' == ''">0.0.3</VersionPrefix>
|
||||
<VersionSuffix Condition="'$(RELEASE_VERSION)' == ''">$([System.DateTime]::UtcNow.ToString(`yyyyMMdd-HHmm`))</VersionSuffix>
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user