cssitegen/Utils/Utils.PathSearch.cs
Robert Morrison 53344de6ea
build: Enable AOT
Add the JSON code generation needed to make my code fully trimmable, and
therefore able to be published with full native AOT compilation.

NOTE: This may not guarantee stable builds as the logging library
serilog is still not fully trimmable, I have made changes to my logging
statements to avoid destructuring, but there is a chance that a
published build could randomly crash.
The only solution is to either wait for serilog to become fully
trimmable, or to remove the logging from AOT builds
2024-06-03 04:04:16 +01:00

55 lines
1.5 KiB
C#

using Serilog;
namespace csSiteGen;
public static partial class Utils {
// As the PathSearch utility will be called for every convertible file
// It has been memoized which mean subsequent calls for the same argument just return the result
static Dictionary<string,string> PathSearchMemo = new();
///<summary>
/// Find executable in path
///</summary>
public static string PathSearch(string Program){
if (PathSearchMemo.TryGetValue(Program, out string? result))
{
Log.Debug("Memo Hit for {program}", Program);
return result;
}
var path = System.Environment.GetEnvironmentVariable("PATH")?.Split(':');
if (path is null)
{
Log.Error("Failed to read PATH environment variable.");
return string.Empty;
}
List<string> candidateExecutables = new();
foreach (var dir in path)
{
// Directories do not need to exist for them to be in path
// This check avoids attempting to look in directories that
// Do not exist.
if (Directory.Exists(dir))
{
Log.Information("Searching for {Program} in {dir}", Program, dir);
candidateExecutables.AddRange(Directory.GetFiles(dir,$"{Program}"));
}
}
if (candidateExecutables.Count == 0)
{
Log.Warning("Dependency {Program} not found",Program);
return string.Empty;
}
result = candidateExecutables.First();
PathSearchMemo.Add(Program,result);
Log.Information("Found {program} at {path}",Program, result);
Log.Debug("Adding to PathSearchMemo", PathSearchMemo.Last().Value);
return result;
}
}