using System; using System.Collections.Generic; using System.IO; namespace StellaOps.Interop; internal sealed class ToolPathResolver : IToolPathResolver { private readonly IReadOnlyDictionary _toolPaths; public ToolPathResolver(IReadOnlyDictionary toolPaths) { _toolPaths = toolPaths ?? throw new ArgumentNullException(nameof(toolPaths)); } public string? ResolveToolPath(string tool) { if (_toolPaths.TryGetValue(tool, out var configured) && File.Exists(configured)) { return configured; } return FindOnPath(tool); } public static string? FindOnPath(string tool) { if (File.Exists(tool)) { return Path.GetFullPath(tool); } var path = Environment.GetEnvironmentVariable("PATH"); if (string.IsNullOrWhiteSpace(path)) { return null; } foreach (var dir in path.Split(Path.PathSeparator)) { if (string.IsNullOrWhiteSpace(dir)) { continue; } var candidate = Path.Combine(dir, tool); if (File.Exists(candidate)) { return candidate; } if (OperatingSystem.IsWindows()) { var exeCandidate = candidate + ".exe"; if (File.Exists(exeCandidate)) { return exeCandidate; } } } return null; } }