206 lines
9.0 KiB
C#
206 lines
9.0 KiB
C#
using Microsoft.Extensions.Logging;
|
|
using System.Collections.ObjectModel;
|
|
|
|
namespace File_Folder_Helper.ADO2024.PI2;
|
|
|
|
internal static partial class Helper20240623
|
|
{
|
|
|
|
private record SubTaskLine(string Text, bool Done, long? Ticks, int? Line);
|
|
private record Record(int? CodeInsidersLine, string File, string[] Lines, int? StopLine, int? SubTasksLine);
|
|
|
|
private static List<Record> GetRecords(string sourceDirectory, string searchPattern, string codeInsiders, string subTasks)
|
|
{
|
|
List<Record> results = [];
|
|
int? stopLine;
|
|
string[] lines;
|
|
int? subTasksLine;
|
|
int? codeInsidersLine;
|
|
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
|
|
foreach (string file in files)
|
|
{
|
|
stopLine = null;
|
|
subTasksLine = null;
|
|
codeInsidersLine = null;
|
|
lines = File.ReadAllLines(file);
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
if (lines[i].StartsWith(codeInsiders) && lines[i][^1] == '"')
|
|
{
|
|
if (lines.Length > i + 1 && lines[i + 1] == "```")
|
|
codeInsidersLine = i;
|
|
}
|
|
if (lines[i] != subTasks)
|
|
continue;
|
|
subTasksLine = i;
|
|
if (codeInsidersLine is null)
|
|
break;
|
|
if (lines.Length > i)
|
|
{
|
|
for (int j = i + 1; j < lines.Length; j++)
|
|
{
|
|
if (lines[j].Length > 0 && lines[j][0] == '#')
|
|
{
|
|
stopLine = j;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
stopLine ??= lines.Length;
|
|
break;
|
|
}
|
|
results.Add(new(codeInsidersLine, file, lines, stopLine, subTasksLine));
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static ReadOnlyCollection<SubTaskLine> GetSubTasks(string subTasks, string[] tasks, bool? foundDone, string fallbackLine, FileInfo fileInfo)
|
|
{
|
|
List<SubTaskLine> results = [];
|
|
string line;
|
|
bool doneValue;
|
|
string? h1 = null;
|
|
bool foundSubTasks = false;
|
|
int tasksZeroLength = tasks[0].Length;
|
|
string[] lines = File.ReadAllLines(fileInfo.FullName);
|
|
for (int i = 0; i < lines.Length; i++)
|
|
{
|
|
line = lines[i];
|
|
if (line.StartsWith("# "))
|
|
h1 = line[2..];
|
|
if (!foundSubTasks && line == subTasks)
|
|
foundSubTasks = true;
|
|
if (!foundSubTasks)
|
|
continue;
|
|
if (line.Length <= tasksZeroLength || !line.StartsWith(tasks[0]) || line[tasksZeroLength] is not ' ' and not 'x' || line[tasksZeroLength + 1] != ']')
|
|
continue;
|
|
doneValue = foundDone is not null && foundDone.Value;
|
|
results.Add(new($" {line}", doneValue, fileInfo.LastWriteTime.Ticks, i));
|
|
}
|
|
doneValue = foundDone is not null && foundDone.Value;
|
|
if (h1 is null)
|
|
results.Add(new(fallbackLine, doneValue, fileInfo.LastWriteTime.Ticks, Line: null));
|
|
else
|
|
results.Add(new(foundDone is null || !foundDone.Value ? $"- [ ] {fileInfo.LastWriteTime.Ticks} ~~~ {h1}" : $"- [x] {fileInfo.LastWriteTime.Ticks} ~~~ {h1}", doneValue, fileInfo.LastWriteTime.Ticks, Line: 0));
|
|
return new(results);
|
|
}
|
|
|
|
internal static void UpdateSubTasksInMarkdownFiles(ILogger<Worker> logger, List<string> args)
|
|
{
|
|
int lineCheck;
|
|
bool doneValue;
|
|
bool? foundDone;
|
|
FileInfo fileInfo;
|
|
string[] newLines;
|
|
string[] segments;
|
|
List<string> lines;
|
|
string fallbackLine;
|
|
string[] indexLines;
|
|
string checkDirectory;
|
|
string done = args[7];
|
|
List<string> indexFiles;
|
|
string subTasks = args[3];
|
|
List<string> oldLines = [];
|
|
string indexFile = args[5];
|
|
string searchPattern = args[2];
|
|
string directoryFilter = args[8];
|
|
string[] tasks = args[6].Split(',');
|
|
string codeInsiders = $"{args[4]} \"";
|
|
List<SubTaskLine> allSubTaskLines = [];
|
|
ReadOnlyCollection<SubTaskLine> subTaskLines;
|
|
string sourceDirectory = Path.GetFullPath(args[0]);
|
|
List<Record> records = GetRecords(sourceDirectory, searchPattern, codeInsiders, subTasks);
|
|
foreach (Record record in from l in records orderby l.SubTasksLine is null, l.CodeInsidersLine is null select l)
|
|
{
|
|
if (record.SubTasksLine is null)
|
|
continue;
|
|
if (record.CodeInsidersLine is not null)
|
|
logger.LogInformation("<{file}> has [{subTasks}]", Path.GetFileNameWithoutExtension(record.File), subTasks);
|
|
else
|
|
{
|
|
logger.LogWarning("<{file}> has [{subTasks}] but doesn't have [{codeInsiders}]!", Path.GetFileNameWithoutExtension(record.File), subTasks, codeInsiders);
|
|
continue;
|
|
}
|
|
if (record.StopLine is null)
|
|
continue;
|
|
checkDirectory = record.Lines[record.CodeInsidersLine.Value][codeInsiders.Length..^1];
|
|
if (!Directory.Exists(checkDirectory))
|
|
{
|
|
logger.LogError("<{checkDirectory}> doesn't exist", Path.GetFileName(checkDirectory));
|
|
continue;
|
|
}
|
|
indexFiles = Directory.GetFiles(checkDirectory, indexFile, SearchOption.AllDirectories).ToList();
|
|
if (indexFiles.Count != 1)
|
|
{
|
|
for (int i = indexFiles.Count - 1; i > -1; i--)
|
|
{
|
|
if (!indexFiles[i].Contains(directoryFilter, StringComparison.CurrentCultureIgnoreCase))
|
|
indexFiles.RemoveAt(i);
|
|
}
|
|
if (indexFiles.Count != 1)
|
|
{
|
|
logger.LogError("<{checkDirectory}> doesn't have a [{indexFile}]", Path.GetFileName(checkDirectory), indexFile);
|
|
continue;
|
|
}
|
|
}
|
|
foundDone = null;
|
|
oldLines.Clear();
|
|
allSubTaskLines.Clear();
|
|
indexLines = File.ReadAllLines(indexFiles[0]);
|
|
checkDirectory = Path.GetDirectoryName(indexFiles[0]) ?? throw new Exception();
|
|
for (int i = 0; i < indexLines.Length; i++)
|
|
{
|
|
if (indexLines[i] == done)
|
|
foundDone = true;
|
|
segments = indexLines[i].Split(tasks[1]);
|
|
doneValue = foundDone is not null && foundDone.Value;
|
|
if (segments.Length > 2 || !segments[0].StartsWith(tasks[0]))
|
|
continue;
|
|
fallbackLine = foundDone is null || !foundDone.Value ? $"- [ ] {segments[0][tasks[0].Length..]}" : $"- [x] {segments[0][tasks[0].Length..]}";
|
|
fileInfo = new(Path.GetFullPath(Path.Combine(checkDirectory, segments[1][..^1])));
|
|
if (!fileInfo.Exists)
|
|
{
|
|
allSubTaskLines.Add(new(fallbackLine, doneValue, Ticks: null, Line: null));
|
|
continue;
|
|
}
|
|
subTaskLines = GetSubTasks(subTasks, tasks, doneValue, fallbackLine, fileInfo);
|
|
for (int j = subTaskLines.Count - 1; j >= 0; j--)
|
|
allSubTaskLines.Add(subTaskLines[j]);
|
|
}
|
|
if (allSubTaskLines.Count == 0)
|
|
continue;
|
|
lineCheck = 0;
|
|
for (int i = record.SubTasksLine.Value + 1; i < record.StopLine.Value - 1; i++)
|
|
oldLines.Add(record.Lines[i]);
|
|
if (allSubTaskLines.Any(l => l.Ticks is null))
|
|
newLines = (from l in allSubTaskLines select l.Text).ToArray();
|
|
else
|
|
newLines = (from l in allSubTaskLines orderby l.Done descending, l.Ticks, l.Line select l.Text).ToArray();
|
|
if (newLines.Length == oldLines.Count)
|
|
{
|
|
for (int i = 0; i < newLines.Length; i++)
|
|
{
|
|
if (newLines[i] != record.Lines[record.SubTasksLine.Value + 1 + i])
|
|
continue;
|
|
lineCheck++;
|
|
}
|
|
if (lineCheck == newLines.Length)
|
|
continue;
|
|
}
|
|
checkDirectory = Path.Combine(checkDirectory, DateTime.Now.Ticks.ToString());
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
Thread.Sleep(500);
|
|
Directory.Delete(checkDirectory);
|
|
lines = record.Lines.ToList();
|
|
for (int i = record.StopLine.Value - 1; i > record.SubTasksLine.Value + 1; i--)
|
|
lines.RemoveAt(i);
|
|
if (record.StopLine.Value == record.Lines.Length && lines[^1].Length == 0)
|
|
lines.RemoveAt(lines.Count - 1);
|
|
for (int i = 0; i < newLines.Length; i++)
|
|
lines.Insert(record.SubTasksLine.Value + 1 + i, newLines[i]);
|
|
lines.Insert(record.SubTasksLine.Value + 1, string.Empty);
|
|
File.WriteAllLines(record.File, lines);
|
|
}
|
|
}
|
|
|
|
} |