using Sdt.Config; namespace Sdt.Core; public sealed class RequirementResolver : IRequirementResolver { public List Resolve(WorkflowStep step) { if (step.Requires.Count > 0) return step.Requires.ToList(); if (!string.IsNullOrWhiteSpace(step.Action)) return InferActionRequirements(step.Action); if (string.IsNullOrWhiteSpace(step.Command)) return []; return InferCommandRequirements(step.Command, step.Args); } public List Resolve(BuildTarget target) { if (string.IsNullOrWhiteSpace(target.Command)) return []; return InferCommandRequirements(target.Command, target.Args); } private static List InferActionRequirements(string action) { return action.ToLowerInvariant() switch { "dotnet-restore" or "dotnet-build" or "dotnet-test" or "dotnet-publish" => [Req("dotnet")], "npm-install" or "npm-ci" or "npm-build" or "npm-test" or "npm-audit" => [Req("node"), Req("npm")], "python-venv-create" or "python-pip-install" or "python-pip-sync" or "python-pytest" => [Req("python")], "cargo-build" or "cargo-test" => [Req("cargo")], "tauri-build" => [Req("cargo"), Req("node"), Req("npm")], "git-status" or "git-fetch" or "git-pull" or "git-clean" => [Req("git")], "docker-build" or "docker-compose-up" or "docker-compose-down" => [Req("docker")], "go-build" or "go-test" => [Req("go")], "maven-build" or "maven-test" => [Req("maven")], "gradle-build" or "gradle-test" => [Req("gradle")], _ => [], }; } private static List InferCommandRequirements(string command, IReadOnlyList args) { return command.ToLowerInvariant() switch { "dotnet" => [Req("dotnet")], "npm" => [Req("node"), Req("npm")], "pnpm" => [Req("node"), Req("pnpm")], "yarn" => [Req("node"), Req("yarn")], "python" or "py" => InferPythonRequirements(args), "cargo" => [Req("cargo")], "tauri" => [Req("cargo"), Req("node"), Req("npm")], "git" => [Req("git")], "docker" => [Req("docker")], "go" => [Req("go")], "mvn" => [Req("maven")], "gradle" => [Req("gradle")], "pwsh" or "powershell" => LegacyScriptRequirementResolver.InferForPowerShellArgs(args), _ => [], }; } private static List InferPythonRequirements(IReadOnlyList args) { var result = new List { Req("python") }; if (args.Any(a => string.Equals(a, "PyInstaller", StringComparison.OrdinalIgnoreCase) || a.EndsWith("pyinstaller", StringComparison.OrdinalIgnoreCase) || a.EndsWith("pyinstaller.exe", StringComparison.OrdinalIgnoreCase))) { result.Add(Req("pyinstaller")); } return result; } private static ToolRequirement Req(string tool) => new() { Tool = tool, InstallPolicy = InstallPolicy.Prompt, }; }