// Copyright Epic Games, Inc. All Rights Reserved. using EpicGames.BuildGraph; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using EpicGames.Core; using UnrealBuildBase; using UnrealBuildTool; namespace AutomationTool.Tasks { /// /// Parameters for a task which runs a UE commandlet /// public class CommandletTaskParameters { /// /// The commandlet name to execute. /// [TaskParameter] public string Name; /// /// The project to run the editor with. /// [TaskParameter(Optional = true, ValidationType = TaskParameterValidationType.FileSpec)] public string Project; /// /// Arguments to be passed to the commandlet. /// [TaskParameter(Optional = true)] public string Arguments; /// /// The editor executable to use. Defaults to the development UnrealEditor executable for the current platform. /// [TaskParameter(Optional = true)] public FileReference EditorExe; /// /// The minimum exit code, which is treated as an error. /// [TaskParameter(Optional = true)] public int ErrorLevel = 1; } /// /// Spawns the editor to run a commandlet. /// [TaskElement("Commandlet", typeof(CommandletTaskParameters))] public class CommandletTask : BgTaskImpl { /// /// Parameters for this task /// CommandletTaskParameters Parameters; /// /// Construct a new CommandletTask. /// /// Parameters for this task public CommandletTask(CommandletTaskParameters InParameters) { Parameters = InParameters; } /// /// Execute the task. /// /// Information about the current job /// Set of build products produced by this node. /// Mapping from tag names to the set of files they include public override Task ExecuteAsync(JobContext Job, HashSet BuildProducts, Dictionary> TagNameToFileSet) { // Get the full path to the project file FileReference ProjectFile = null; if(!String.IsNullOrEmpty(Parameters.Project)) { if(Parameters.Project.EndsWith(".uproject", StringComparison.OrdinalIgnoreCase)) { ProjectFile = ResolveFile(Parameters.Project); } else { ProjectFile = NativeProjects.EnumerateProjectFiles(Log.Logger).FirstOrDefault(x => x.GetFileNameWithoutExtension().Equals(Parameters.Project, StringComparison.OrdinalIgnoreCase)); } if(ProjectFile == null || !FileReference.Exists(ProjectFile)) { throw new BuildException("Unable to resolve project '{0}'", Parameters.Project); } } // Get the path to the editor, and check it exists FileSystemReference EditorExe; if(Parameters.EditorExe == null) { EditorExe = ProjectUtils.GetProjectTarget(ProjectFile, UnrealBuildTool.TargetType.Editor, BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development, true); if (EditorExe == null) { EditorExe = new FileReference(HostPlatform.Current.GetUnrealExePath("UnrealEditor-Cmd.exe")); } } else { EditorExe = Parameters.EditorExe; } // Run the commandlet CommandUtils.RunCommandlet(ProjectFile, EditorExe.FullName, Parameters.Name, Parameters.Arguments, Parameters.ErrorLevel); return Task.CompletedTask; } /// /// Output this task out to an XML writer. /// public override void Write(XmlWriter Writer) { Write(Writer, Parameters); } /// /// Find all the tags which are used as inputs to this task /// /// The tag names which are read by this task public override IEnumerable FindConsumedTagNames() { yield break; } /// /// Find all the tags which are modified by this task /// /// The tag names which are modified by this task public override IEnumerable FindProducedTagNames() { yield break; } } /// /// Task wrapper methods /// public static partial class StandardTasks { /// /// Task which runs a UE commandlet /// /// /// The commandlet name to execute. /// The project to run the editor with. /// Arguments to be passed to the commandlet. /// The editor executable to use. Defaults to the development UnrealEditor executable for the current platform. /// The minimum exit code, which is treated as an error. public static async Task CommandletAsync(this BgContext State, string Name, FileReference Project = null, string Arguments = null, FileReference EditorExe = null, int ErrorLevel = 1) { CommandletTaskParameters Parameters = new CommandletTaskParameters(); Parameters.Name = Name; Parameters.Project = Project?.FullName; Parameters.Arguments = Arguments; Parameters.EditorExe = EditorExe; Parameters.ErrorLevel = ErrorLevel; await ExecuteAsync(new CommandletTask(Parameters)); } } }