using Sdt.Core; namespace Sdt.Config; public enum LegacyMode { Strict, Compat, } public sealed record WorkflowNormalizationResult( IReadOnlyList Workflows, IReadOnlyList Warnings); public static class WorkflowModelBuilder { public static WorkflowNormalizationResult Normalize( DevToolConfig config, LegacyMode legacyMode = LegacyMode.Strict, IRequirementResolver? requirementResolver = null) { requirementResolver ??= new RequirementResolver(); var warnings = new List(); if (config.Workflows.Count > 0) { if (config.Targets.Count > 0) { warnings.Add("Both 'workflows' and legacy 'targets' are present. SDT will use 'workflows'."); } return new WorkflowNormalizationResult(config.Workflows, warnings); } if (config.Targets.Count == 0) { warnings.Add("No 'workflows' or legacy 'targets' were found."); return new WorkflowNormalizationResult([], warnings); } if (legacyMode == LegacyMode.Strict) { throw new InvalidOperationException( "Legacy 'targets' are not allowed in strict mode. Migrate to 'workflows' or set SDT_LEGACY_MODE=compat temporarily."); } warnings.Add("Using legacy 'targets' schema. Migrate to 'workflows' for v1+ features."); return new WorkflowNormalizationResult(ConvertLegacyTargets(config.Targets, requirementResolver), warnings); } public static DevToolConfig BuildMigrationPreviewConfig(DevToolConfig config, IRequirementResolver? requirementResolver = null) { requirementResolver ??= new RequirementResolver(); return new DevToolConfig { Name = config.Name, Version = config.Version, Targets = [], Workflows = ConvertLegacyTargets(config.Targets, requirementResolver), Env = config.Env, Toolchains = config.Toolchains, Tooling = config.Tooling, Project = config.Project, Debug = config.Debug, }; } private static List ConvertLegacyTargets( IReadOnlyList targets, IRequirementResolver requirementResolver) { var workflows = new List(targets.Count); foreach (var target in targets) { var step = target.Command is null ? null : new WorkflowStep { Id = $"{target.Id}:run", Label = string.IsNullOrWhiteSpace(target.Label) ? target.Id : target.Label, Command = target.Command, Args = target.Args, WorkingDir = target.WorkingDir, Requires = requirementResolver.Resolve(target), }; workflows.Add(new WorkflowDefinition { Id = target.Id, Label = target.Label, Description = target.Description, Group = target.Group, DependsOn = target.DependsOn, Steps = step is null ? [] : [step], }); } return workflows; } }