Remove StartAt

Handle directoryInfo.LinkTarget
This commit is contained in:
Mike Phares 2024-07-10 17:58:50 -07:00
parent 1cd20fa08b
commit e047304438
5 changed files with 126 additions and 121 deletions

8
.vscode/launch.json vendored
View File

@ -12,9 +12,11 @@
"program": "${workspaceFolder}/bin/Debug/net8.0/win-x64/File-Folder-Helper.dll",
"args": [
"s",
"K",
".kanbn"
],
"M",
"L:/Git/Notes-Infineon/.Infineon",
"-d",
"L:/Git/Notes-Infineon/.Infineon/.vscode/helper"
],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"stopAtEntry": false

View File

@ -31,6 +31,7 @@
"onenote",
"pged",
"Phares",
"Reparse",
"Rijndael",
"Serilog",
"SUBM",

View File

@ -43,22 +43,39 @@ internal static class HelperGit
return result.Output;
}
private static List<string> GetOthersModifiedAndDeletedExcludingStandardFilesAsList(string repositoryDirectory, bool usePathCombine, CancellationToken cancellationToken)
{
List<string> results = [];
Task<string> task = RunAsync($"ls-files --others --modified --deleted --exclude-standard", repositoryDirectory, cancellationToken);
task.Wait(cancellationToken);
string[] files = task.Result.Split("\r\n");
foreach (string file in files)
{
if (!usePathCombine)
results.Add(file);
else
results.Add(Path.GetFullPath(Path.Combine(repositoryDirectory, file)));
}
return results;
}
internal static ReadOnlyCollection<string> GetOthersModifiedAndDeletedExcludingStandardFiles(string repositoryDirectory, bool usePathCombine, CancellationToken cancellationToken)
{
List<string> results = [];
DirectoryInfo directoryInfo;
string checkDirectory = Path.Combine(repositoryDirectory, ".git");
if (Directory.Exists(checkDirectory))
results.AddRange(GetOthersModifiedAndDeletedExcludingStandardFilesAsList(repositoryDirectory, usePathCombine, cancellationToken));
string[] subdirectories = Directory.GetDirectories(repositoryDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string subdirectory in subdirectories)
{
Task<string> task = RunAsync($"ls-files --others --modified --deleted --exclude-standard", repositoryDirectory, cancellationToken);
task.Wait(cancellationToken);
string[] files = task.Result.Split("\r\n");
foreach (string file in files)
{
if (!usePathCombine)
results.Add(file);
else
results.Add(Path.GetFullPath(Path.Combine(repositoryDirectory, file)));
}
directoryInfo = new(subdirectory);
if (directoryInfo.LinkTarget is null)
continue;
checkDirectory = Path.Combine(directoryInfo.LinkTarget, ".git");
if (!Directory.Exists(checkDirectory))
continue;
results.AddRange(GetOthersModifiedAndDeletedExcludingStandardFilesAsList(directoryInfo.LinkTarget, usePathCombine, cancellationToken));
}
return new(results);
}

View File

@ -160,7 +160,7 @@ internal static partial class HelperKanbanMetadata
results.Add(lines[i]);
}
}
results.Add($"status: \"{record.GroupCount}-{record.Group}\"");
results.Add($"status: {record.GroupCount}-{record.Group}");
results.Add("```");
results.Add(string.Empty);
}
@ -201,7 +201,7 @@ internal static partial class HelperKanbanMetadata
(lines, lineNumber) = HelperMarkdown.GetStatusAndFrontMatterYamlEndLineNumbers(record.FileInfo);
if (lines.Count == 0)
continue;
statusLine = $"status: \"{record.GroupCount}-{record.Group}\"";
statusLine = $"status: {record.GroupCount}-{record.Group}";
paramCase = lineNumber.H1 is null ? null : GetParamCase(lines[lineNumber.H1.Value]);
match = lineNumber.H1 is null || paramCase is null ? null : Path.GetFileNameWithoutExtension(record.FileInfo.Name) == paramCase;
if (lineNumber.FrontMatterYamlEnd is null)

View File

@ -14,8 +14,7 @@ internal static partial class HelperMarkdown
{
private record Input(string? Destination,
string Source,
string? StartAt);
string Source);
private record Record(string Directory,
string File,
@ -98,7 +97,7 @@ internal static partial class HelperMarkdown
if (markdownFileH1AndRelativePath.MarkdownFile is null || markdownFileH1AndRelativePath.H1 is null || markdownFileH1AndRelativePath.RelativePath is null)
{
recursiveLines.Add($"???{indentation}{lines[i]}");
logger.LogInformation("Didn't find {line} in <{file}>", lines[i], markdownFile.FileNameWithoutExtension);
logger.LogInformation("Didn't find '{line}' in <{file}>", lines[i], markdownFile.FileName);
continue;
}
if (markdownFileH1AndRelativePath.Lines is null)
@ -516,13 +515,38 @@ internal static partial class HelperMarkdown
return result;
}
private static string[] GetFiles(AppSettings appSettings, string directory)
private static string[] GetFiles(AppSettings appSettings, string directory, SearchOption searchOption)
{
string[] results = Directory.GetFiles(directory, "*.md", SearchOption.AllDirectories).
string[] results = Directory.GetFiles(directory, "*.md", searchOption).
Where(l => !appSettings.ExcludeDirectoryNames.Any(m => l.Contains(m))).ToArray();
return results;
}
private static ReadOnlyCollection<string> GetFiles(AppSettings appSettings, Input input)
{
List<string> results = [];
FileInfo fileInfo;
List<string> files = [];
DirectoryInfo directoryInfo;
string[] directories = Directory.GetDirectories(input.Source, "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
files.Clear();
directoryInfo = new(directory);
files.AddRange(GetFiles(appSettings, directory, SearchOption.TopDirectoryOnly));
if (directoryInfo.LinkTarget is not null)
files.AddRange(GetFiles(appSettings, directoryInfo.LinkTarget, SearchOption.AllDirectories));
foreach (string file in files)
{
results.Add(file);
fileInfo = new(file);
if (fileInfo.LinkTarget is not null)
results.Add(fileInfo.LinkTarget);
}
}
return new(results);
}
private static ReadOnlyCollection<string> GetFromMatterYamlLines(List<string> lines, LineNumber lineNumber)
{
List<string> results = [];
@ -549,65 +573,6 @@ internal static partial class HelperMarkdown
return new(results);
}
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, string[] files, ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles, bool force)
{
Dictionary<string, MarkdownFileAndLines> results = [];
string h1;
string key;
string type;
bool gitCheck;
FileInfo fileInfo;
bool isKanbanIndex;
List<string> lines;
bool isKanbanMarkdown;
LineNumber lineNumber;
MarkdownFile markdownFile;
string fileNameWithoutExtension;
ReadOnlyDictionary<string, object> frontMatterYaml;
foreach (string file in files)
{ // cSpell:disable
fileInfo = new(file);
if (fileInfo.DirectoryName is null)
continue;
key = Path.GetRelativePath(input.Source, file);
(lines, lineNumber) = GetStatusAndFrontMatterYamlEndLineNumbers(fileInfo);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
h1 = fileNameWithoutExtension.ToLower().Replace("%20", "-").Replace(' ', '-');
frontMatterYaml = GetFromMatterYaml(lines, lineNumber);
if (lines.Count > 0)
(type, h1) = GetTypeAndH1(appSettings, h1, lines, lineNumber);
else
{
gitCheck = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(file);
if (!gitCheck)
continue;
type = appSettings.DefaultNoteType;
File.WriteAllLines(file, ["---", $"type: \"{type}\"", "---", string.Empty, $"# {h1}"]);
lines = File.ReadAllLines(file).ToList();
}
isKanbanMarkdown = fileInfo.Name.EndsWith(".knb.md");
isKanbanIndex = fileNameWithoutExtension == "index" && type.StartsWith("kanb", StringComparison.OrdinalIgnoreCase);
markdownFile = new(fileInfo.CreationTime,
fileInfo.DirectoryName,
fileInfo.Extension,
file,
fileInfo.Name,
fileNameWithoutExtension,
frontMatterYaml,
h1,
isKanbanIndex,
isKanbanMarkdown,
fileInfo.LastWriteTime,
lineNumber,
type);
if (force || input.StartAt is null || file.StartsWith(input.StartAt))
results.Add(key, new(markdownFile, lines.ToArray()));
else
results.Add(key, new(markdownFile, []));
} // cSpell:restore
return new(results);
}
private static List<string> GetKeys(ReadOnlyDictionary<string, MarkdownFileAndLines> relativeToCollection)
{
List<string> results = [];
@ -772,24 +737,17 @@ internal static partial class HelperMarkdown
private static Input GetInput(List<string> args)
{
Input result;
string? startAt = null;
string? destination = null;
string source = Path.GetFullPath(args[0]);
for (int i = 1; i < args.Count; i++)
{
if (args[i].Length == 2 && i + 1 < args.Count)
{
if (args[i][1] == 's')
startAt = Path.GetFullPath(args[i + 1]);
else if (args[i][1] == 'd')
if (args[i][1] == 'd')
destination = Path.GetFullPath(args[i + 1]);
i++;
}
}
if (startAt is not null && !Directory.Exists(startAt))
throw new Exception($"Start at directory <{startAt}> doesn't exist!");
if (startAt is not null && startAt.Length < source.Length)
throw new Exception($"Start at directory <{startAt}> must be a subdirectory!");
if (destination is not null)
{
string? root = Path.GetPathRoot(destination);
@ -798,7 +756,7 @@ internal static partial class HelperMarkdown
if (!Directory.Exists(destination))
_ = Directory.CreateDirectory(destination);
}
result = new(destination, source, startAt);
result = new(destination, source);
return result;
}
@ -949,7 +907,7 @@ internal static partial class HelperMarkdown
markdownFileH1AndRelativePath = GetRelativePath(keyValuePairs, markdownFile, segmentsC[0]);
if (markdownFileH1AndRelativePath.MarkdownFile is null || markdownFileH1AndRelativePath.H1 is null || markdownFileH1AndRelativePath.RelativePath is null)
{
logger.LogInformation("Didn't find {line} in <{file}>", lines[i], markdownFile.FileNameWithoutExtension);
logger.LogInformation("Didn't find '{line}' in <{file}>", lines[i], markdownFile.FileName);
continue;
}
line = $"{segmentsB[0]}[{markdownFileH1AndRelativePath.H1}]({markdownFileH1AndRelativePath.RelativePath.Replace('\\', '/')}){segmentsA[^1]}";
@ -1024,7 +982,7 @@ internal static partial class HelperMarkdown
markdownFileH1AndRelativePath = GetRelativePath(keyValuePairs, markdownFile, file);
if (markdownFileH1AndRelativePath.MarkdownFile is null || markdownFileH1AndRelativePath.H1 is null || markdownFileH1AndRelativePath.RelativePath is null)
{
logger.LogInformation("Didn't find {line} in <{file}>", lines[i], markdownFile.FileNameWithoutExtension);
logger.LogInformation("Didn't find '{line}' in <{file}>", lines[i], markdownFile.FileName);
continue;
}
line = $"{string.Join('[', segmentsC, 0, segmentsC.Length - 1)}[{markdownFileH1AndRelativePath.H1}]({markdownFileH1AndRelativePath.RelativePath.Replace('\\', '/')}){segmentsB[^1]}";
@ -1070,11 +1028,60 @@ internal static partial class HelperMarkdown
return result;
}
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles, bool force = false)
private static ReadOnlyDictionary<string, MarkdownFileAndLines> GetRelativeToCollection(AppSettings appSettings, Input input, ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles)
{
ReadOnlyDictionary<string, MarkdownFileAndLines> results;
string[] files = GetFiles(appSettings, input.Source);
results = GetRelativeToCollection(appSettings, input, files, gitOthersModifiedAndDeletedExcludingStandardFiles, force);
Dictionary<string, MarkdownFileAndLines> results = [];
string h1;
string key;
string type;
bool gitCheck;
FileInfo fileInfo;
bool isKanbanIndex;
List<string> lines;
bool isKanbanMarkdown;
LineNumber lineNumber;
MarkdownFile markdownFile;
string fileNameWithoutExtension;
ReadOnlyDictionary<string, object> frontMatterYaml;
ReadOnlyCollection<string> files = GetFiles(appSettings, input);
foreach (string file in files)
{ // cSpell:disable
fileInfo = new(file);
if (fileInfo.DirectoryName is null)
continue;
key = !file.Contains(input.Source) ? file : Path.GetRelativePath(input.Source, file);
(lines, lineNumber) = GetStatusAndFrontMatterYamlEndLineNumbers(fileInfo);
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
h1 = fileNameWithoutExtension.ToLower().Replace("%20", "-").Replace(' ', '-');
frontMatterYaml = GetFromMatterYaml(lines, lineNumber);
if (lines.Count > 0)
(type, h1) = GetTypeAndH1(appSettings, h1, lines, lineNumber);
else
{
gitCheck = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(file);
if (!gitCheck)
continue;
type = appSettings.DefaultNoteType;
File.WriteAllLines(file, ["---", $"type: {type}\"", "---", string.Empty, $"# {h1}"]);
lines = File.ReadAllLines(file).ToList();
}
isKanbanMarkdown = fileInfo.Name.EndsWith(".knb.md");
isKanbanIndex = fileNameWithoutExtension == "index" && type.StartsWith("kanb", StringComparison.OrdinalIgnoreCase);
markdownFile = new(fileInfo.CreationTime,
fileInfo.DirectoryName,
fileInfo.Extension,
file,
fileInfo.Name,
fileNameWithoutExtension,
frontMatterYaml,
h1,
isKanbanIndex,
isKanbanMarkdown,
fileInfo.LastWriteTime,
lineNumber,
type);
results.Add(key, new(markdownFile, lines.ToArray()));
} // cSpell:restore
return new(results);
}
@ -1090,8 +1097,6 @@ internal static partial class HelperMarkdown
{
if (relativeTo.Value.Lines.Length == 0)
continue;
if (input.StartAt is null || !relativeTo.Value.MarkdownFile.File.StartsWith(input.StartAt) || Path.GetFileName(relativeTo.Value.MarkdownFile.Directory) != Path.GetFileName(input.StartAt))
continue;
indentations = [];
recursiveLines = [];
lines = relativeTo.Value.Lines;
@ -1102,23 +1107,9 @@ internal static partial class HelperMarkdown
return results;
}
private static void Write(Input input, List<MarkdownFileAndLines> markdownFileAndLinesCollection, ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles)
{
bool gitCheck;
foreach (MarkdownFileAndLines markdownFileAndLines in markdownFileAndLinesCollection)
{
if (input.Destination is null)
continue;
gitCheck = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(markdownFileAndLines.MarkdownFile.File);
if (!gitCheck)
continue;
File.WriteAllLines(Path.Combine(input.Destination, markdownFileAndLines.MarkdownFile.FileName), markdownFileAndLines.Lines);
}
}
private static void SaveColumnToCards(Input input, ReadOnlyDictionary<string, MarkdownFileAndLines> relativeToCollection)
{
if (string.IsNullOrEmpty(input.StartAt) || string.IsNullOrEmpty(input.Destination))
if (string.IsNullOrEmpty(input.Destination))
throw new NotSupportedException();
MarkdownFileAndLines? markdownFileAndLines = GetKanbanIndexMarkdownFileAndLines(relativeToCollection);
if (markdownFileAndLines is not null && File.Exists(markdownFileAndLines.MarkdownFile.File))
@ -1171,12 +1162,12 @@ internal static partial class HelperMarkdown
if (markdownFile.IsKanbanMarkdown)
continue;
results.AddRange(lines);
typeLine = $"type: \"{appSettings.DefaultNoteType}\"";
typeLine = $"type: {appSettings.DefaultNoteType}";
h1Line = $"# {markdownFile.FileNameWithoutExtension}";
creationDateTime = markdownFile.CreationDateTime > markdownFile.LastWriteDateTime ? markdownFile.LastWriteDateTime : markdownFile.CreationDateTime;
gitCheck = gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(markdownFile.File);
createdLine = $"created: \"{creationDateTime.ToUniversalTime():yyyy-MM-ddTHH:mm:ss.fffZ}\"";
updatedLine = $"updated: \"{markdownFile.LastWriteDateTime.ToUniversalTime():yyyy-MM-ddTHH:mm:ss.fffZ}\"";
createdLine = $"created: {creationDateTime.ToUniversalTime():yyyy-MM-ddTHH:mm:ss.fffZ}";
updatedLine = $"updated: {markdownFile.LastWriteDateTime.ToUniversalTime():yyyy-MM-ddTHH:mm:ss.fffZ}";
if (markdownFile.IsKanbanIndex)
HelperKanbanMetadata.SetMetadata(markdownFile.Directory, new(lines), markdownFile.LineNumber, gitOthersModifiedAndDeletedExcludingStandardFiles);
if (markdownFile.LineNumber.FrontMatterYamlEnd is null)
@ -1341,13 +1332,7 @@ internal static partial class HelperMarkdown
relativeToCollection = GetRelativeToCollection(appSettings, input, gitOthersModifiedAndDeletedExcludingStandardFiles);
logger.LogInformation("{updated} Markdown file(s) were updated", updated);
}
if (!string.IsNullOrEmpty(input.StartAt) && !string.IsNullOrEmpty(input.Destination))
{
relativeToCollection = GetRelativeToCollection(appSettings, input, gitOthersModifiedAndDeletedExcludingStandardFiles, force: true);
List<MarkdownFileAndLines> markdownFileAndLinesCollection = GetRecursiveLines(appSettings, input, logger, relativeToCollection);
Write(input, markdownFileAndLinesCollection, gitOthersModifiedAndDeletedExcludingStandardFiles);
}
if (!string.IsNullOrEmpty(input.StartAt) && !string.IsNullOrEmpty(input.Destination))
if (!string.IsNullOrEmpty(input.Destination))
SaveColumnToCards(input, relativeToCollection);
}