SDT/src/DevTool.Engine/Core/RequirementResolver.cs
2026-03-04 16:40:57 -06:00

86 lines
3.2 KiB
C#

using Sdt.Config;
namespace Sdt.Core;
public sealed class RequirementResolver : IRequirementResolver
{
public List<ToolRequirement> 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<ToolRequirement> Resolve(BuildTarget target)
{
if (string.IsNullOrWhiteSpace(target.Command))
return [];
return InferCommandRequirements(target.Command, target.Args);
}
private static List<ToolRequirement> 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<ToolRequirement> InferCommandRequirements(string command, IReadOnlyList<string> 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<ToolRequirement> InferPythonRequirements(IReadOnlyList<string> args)
{
var result = new List<ToolRequirement> { 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,
};
}