// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; 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 the Tag Receipt task. /// public class SanitizeReceiptTaskParameters { /// /// Set of receipt files (*.target) to read, including wildcards and tag names, separated by semicolons. /// [TaskParameter(ValidationType = TaskParameterValidationType.FileSpec)] public string Files; /// /// Path to the Engine folder, used to expand $(EngineDir) properties in receipt files. Defaults to the Engine directory for the current workspace. /// [TaskParameter(Optional = true)] public DirectoryReference EngineDir; } /// /// Task that tags build products and/or runtime dependencies by reading from *.target files. /// [TaskElement("SanitizeReceipt", typeof(SanitizeReceiptTaskParameters))] class SanitizeReceiptTask : CustomTask { /// /// Parameters to this task /// SanitizeReceiptTaskParameters Parameters; /// /// Constructor /// /// Parameters to select which files to search public SanitizeReceiptTask(SanitizeReceiptTaskParameters 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 void Execute(JobContext Job, HashSet BuildProducts, Dictionary> TagNameToFileSet) { // Set the Engine directory DirectoryReference EngineDir = Parameters.EngineDir ?? Unreal.EngineDirectory; // Resolve the input list IEnumerable TargetFiles = ResolveFilespec(Unreal.RootDirectory, Parameters.Files, TagNameToFileSet); foreach(FileReference TargetFile in TargetFiles) { // check all files are .target files if (TargetFile.GetExtension() != ".target") { throw new AutomationException("Invalid file passed to TagReceipt task ({0})", TargetFile.FullName); } // Print the name of the file being scanned Log.TraceInformation("Sanitizing {0}", TargetFile); using(new LogIndentScope(" ")) { // Read the receipt TargetReceipt Receipt; if (!TargetReceipt.TryRead(TargetFile, EngineDir, out Receipt)) { CommandUtils.LogWarning("Unable to load file using TagReceipt task ({0})", TargetFile.FullName); continue; } // Remove any build products that don't exist List NewBuildProducts = new List(Receipt.BuildProducts.Count); foreach(BuildProduct BuildProduct in Receipt.BuildProducts) { if(FileReference.Exists(BuildProduct.Path)) { NewBuildProducts.Add(BuildProduct); } else { Log.TraceInformation("Removing build product: {0}", BuildProduct.Path); } } Receipt.BuildProducts = NewBuildProducts; // Remove any runtime dependencies that don't exist RuntimeDependencyList NewRuntimeDependencies = new RuntimeDependencyList(); foreach(RuntimeDependency RuntimeDependency in Receipt.RuntimeDependencies) { if(FileReference.Exists(RuntimeDependency.Path)) { NewRuntimeDependencies.Add(RuntimeDependency); } else { Log.TraceInformation("Removing runtime dependency: {0}", RuntimeDependency.Path); } } Receipt.RuntimeDependencies = NewRuntimeDependencies; // Save the new receipt Receipt.Write(TargetFile, EngineDir); } } } /// /// Output this task out to an XML writer. /// public override void Write(XmlWriter Writer) { Write(Writer, Parameters); } /// /// Find all the tags which are required by this task /// /// The tag names which are required by this task public override IEnumerable FindConsumedTagNames() { return FindTagNamesFromFilespec(Parameters.Files); } /// /// Find all the referenced tags from tasks in this task /// /// The tag names which are produced/modified by this task public override IEnumerable FindProducedTagNames() { return new string[0]; } } }