- Journal.DevTool: C# TUI dev tool (SDT) using Spectre.Console - Phosphor green (#00FF41) terminal aesthetic with amber/red accents - Grouped build target menu driven by devtool.json config - Topological dependency resolver for DependsOn chains - Live stdout/stderr streaming per target step - Interactive environment variable editor (dropdown + free-text) - Toolchain management screen: Python venv create/install/upgrade, Node npm install - Workspace switcher: reads sdt-workspace.json, hot-switches between projects - Outputs as 'sdt' executable (net10.0) - devtool.json: project config for SDT - All build targets: sidecar, web, webgateway, tauri, tauri-nsis, all (virtual) - Dev targets: run-gateway - Test targets: test (smoke), gate (migration) - Cache targets: nuget-export, nuget-import - Toolchains: Python 3.14 (cpu/gpu/nlp profiles) + Node/npm (Journal.App) - Env vars: AI provider, log level, NLP backend, path overrides - justfile: just command runner recipes wrapping existing scripts - Correct dependency ordering (sidecar before tauri, web before webgateway) - OS-aware runtime detection (win-x64 / linux-x64) - Recipes: sidecar, web, webgateway, tauri, tauri-nsis, all, run, dev-app, test, gate, build, nuget-export/import, sdt - Journal.slnx: added Journal.DevTool project
42 lines
1.3 KiB
C#
42 lines
1.3 KiB
C#
using Sdt.Config;
|
|
|
|
namespace Sdt.Runner;
|
|
|
|
public static class TargetRunner
|
|
{
|
|
/// <summary>
|
|
/// Returns the ordered list of real (non-virtual) steps needed to execute <paramref name="target"/>,
|
|
/// respecting DependsOn chains. Each step appears at most once.
|
|
/// </summary>
|
|
public static List<BuildTarget> ResolvePlan(
|
|
BuildTarget target,
|
|
IReadOnlyDictionary<string, BuildTarget> allTargets)
|
|
{
|
|
var visited = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
var plan = new List<BuildTarget>();
|
|
Visit(target, allTargets, visited, plan);
|
|
return plan;
|
|
}
|
|
|
|
private static void Visit(
|
|
BuildTarget target,
|
|
IReadOnlyDictionary<string, BuildTarget> allTargets,
|
|
HashSet<string> visited,
|
|
List<BuildTarget> plan)
|
|
{
|
|
if (!visited.Add(target.Id))
|
|
return;
|
|
|
|
// Recurse into dependencies first (topological order)
|
|
foreach (var depId in target.DependsOn)
|
|
{
|
|
if (allTargets.TryGetValue(depId, out var dep))
|
|
Visit(dep, allTargets, visited, plan);
|
|
}
|
|
|
|
// Virtual aggregator targets (null Command) are just dependency collectors
|
|
if (target.Command is not null)
|
|
plan.Add(target);
|
|
}
|
|
}
|