// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. using AutomationTool; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using Tools.DotNETCommon; using UnrealBuildTool; namespace BuildGraph.Tasks { /// /// Parameters for a move task /// public class MoveTaskParameters { /// /// Filter to be applied to the list of input files. Optional. /// [TaskParameter(Optional = true, ValidationType = TaskParameterValidationType.FileSpec)] public string Files; /// /// The pattern(s) to copy from (eg. Engine/*.txt) /// [TaskParameter(ValidationType = TaskParameterValidationType.FileSpec)] public string From; /// /// The directory or to copy to /// [TaskParameter(ValidationType = TaskParameterValidationType.FileSpec)] public string To; /// /// Tag to be applied to build products of this task /// [TaskParameter(Optional = true, ValidationType = TaskParameterValidationType.TagList)] public string Tag; } /// /// Moves files from one directory to another. /// [TaskElement("Move", typeof(MoveTaskParameters))] public class MoveTask : CustomTask { /// /// Parameters for this task /// MoveTaskParameters Parameters; /// /// Constructor /// /// Parameters for this task public MoveTask(MoveTaskParameters 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) { // Parse all the source patterns FilePattern SourcePattern = new FilePattern(CommandUtils.RootDirectory, Parameters.From); // Parse the target pattern FilePattern TargetPattern = new FilePattern(CommandUtils.RootDirectory, Parameters.To); // Apply the filter to the source files HashSet Files = null; if(!String.IsNullOrEmpty(Parameters.Files)) { SourcePattern = SourcePattern.AsDirectoryPattern(); Files = ResolveFilespec(SourcePattern.BaseDirectory, Parameters.Files, TagNameToFileSet); } // Build the file mapping Dictionary TargetFileToSourceFile = FilePattern.CreateMapping(Files, ref SourcePattern, ref TargetPattern); // Check we got some files if(TargetFileToSourceFile.Count == 0) { CommandUtils.LogInformation("No files found matching '{0}'", SourcePattern); return; } // Copy them all CommandUtils.LogInformation("Moving {0} file{1} from {2} to {3}...", TargetFileToSourceFile.Count, (TargetFileToSourceFile.Count == 1)? "" : "s", SourcePattern.BaseDirectory, TargetPattern.BaseDirectory); CommandUtils.ParallelMoveFiles(TargetFileToSourceFile.Select(x => new KeyValuePair(x.Value, x.Key))); // Update the list of build products BuildProducts.UnionWith(TargetFileToSourceFile.Keys); // Apply the optional output tag to them foreach(string TagName in FindTagNamesFromList(Parameters.Tag)) { FindOrAddTagSet(TagNameToFileSet, TagName).UnionWith(TargetFileToSourceFile.Keys); } } /// /// 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() { foreach(string TagName in FindTagNamesFromFilespec(Parameters.Files)) { yield return TagName; } } /// /// Find all the tags which are modified by this task /// /// The tag names which are modified by this task public override IEnumerable FindProducedTagNames() { return FindTagNamesFromList(Parameters.Tag); } } }