journal/Journal.DevTool/Config/WorkspaceLoader.cs

53 lines
1.8 KiB
C#

using System.Text.Json;
namespace Sdt.Config;
public static class WorkspaceLoader
{
private const string FileName = "sdt-workspace.json";
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
AllowTrailingCommas = true,
ReadCommentHandling = JsonCommentHandling.Skip,
};
/// <summary>
/// Walks up from <paramref name="startDir"/> (or CWD) to find sdt-workspace.json.
/// Returns null if not found.
/// </summary>
public static (WorkspaceConfig Config, string WorkspaceRoot)? FindAndLoad(string? startDir = null)
{
var dir = new DirectoryInfo(startDir ?? Directory.GetCurrentDirectory());
while (dir is not null)
{
var candidate = Path.Combine(dir.FullName, FileName);
if (File.Exists(candidate))
{
try
{
var json = File.ReadAllText(candidate);
var config = JsonSerializer.Deserialize<WorkspaceConfig>(json, JsonOptions)
?? throw new InvalidOperationException($"{FileName} deserialized to null.");
return (config, dir.FullName);
}
catch (Exception ex)
{
throw new InvalidOperationException(
$"Failed to parse {FileName} at {candidate}: {ex.Message}", ex);
}
}
dir = dir.Parent!;
}
return null;
}
/// <summary>
/// Resolves the absolute project root for a workspace project entry.
/// </summary>
public static string ResolveProjectRoot(string workspaceRoot, WorkspaceProject project)
=> Path.GetFullPath(Path.Combine(workspaceRoot, project.Path));
}