Files
zousar shaker 6a6743fcfd Relocate the TmpPackaging directory so that it is not under Project\Saved\TmpPackaging (regardless of presence of DLC), but is instead in the cook Metadata folder. This ensures that:
1. DLC cooks don't overwrite the TmpPackaging contents of a base game
2. TmpPackaging contents are picked up by zen filesystem and snapshot logic as other metadata

#rb Matt.Peters

[CL 34938925 by zousar shaker in ue5-main branch]
2024-07-19 14:14:45 -04:00

174 lines
5.7 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using EpicGames.Core;
using OpenTracing;
using OpenTracing.Util;
namespace AutomationTool.Tasks
{
/// <summary>
/// Parameters for a task that runs the cooker
/// </summary>
public class CookTaskParameters
{
/// <summary>
/// Project file to be cooked.
/// </summary>
[TaskParameter]
public string Project { get; set; }
/// <summary>
/// The cook platform to target (for example, Windows).
/// </summary>
[TaskParameter]
public string Platform { get; set; }
/// <summary>
/// List of maps to be cooked, separated by '+' characters.
/// </summary>
[TaskParameter(Optional = true)]
public string Maps { get; set; }
/// <summary>
/// Additional arguments to be passed to the cooker.
/// </summary>
[TaskParameter(Optional = true)]
public bool Versioned { get; set; } = false;
/// <summary>
/// Additional arguments to be passed to the cooker.
/// </summary>
[TaskParameter(Optional = true)]
public string Arguments { get; set; } = "";
/// <summary>
/// Optional path to what editor executable to run for cooking.
/// </summary>
[TaskParameter(Optional = true)]
public string EditorExe { get; set; } = "";
/// <summary>
/// Whether to tag the output from the cook. Since cooks produce a lot of files, it can be detrimental to spend time tagging them if we don't need them in a dependent node.
/// </summary>
[TaskParameter(Optional = true)]
public bool TagOutput { get; set; } = true;
/// <summary>
/// Tag to be applied to build products of this task.
/// </summary>
[TaskParameter(Optional = true, ValidationType = TaskParameterValidationType.TagList)]
public string Tag { get; set; }
}
/// <summary>
/// Cook a selection of maps for a certain platform
/// </summary>
[TaskElement("Cook", typeof(CookTaskParameters))]
public class CookTask : BgTaskImpl
{
/// <summary>
/// Parameters for the task
/// </summary>
readonly CookTaskParameters _parameters;
/// <summary>
/// Constructor.
/// </summary>
/// <param name="parameters">Parameters for this task</param>
public CookTask(CookTaskParameters parameters)
{
_parameters = parameters;
}
/// <summary>
/// ExecuteAsync the task.
/// </summary>
/// <param name="job">Information about the current job</param>
/// <param name="buildProducts">Set of build products produced by this node.</param>
/// <param name="tagNameToFileSet">Mapping from tag names to the set of files they include</param>
public override Task ExecuteAsync(JobContext job, HashSet<FileReference> buildProducts, Dictionary<string, HashSet<FileReference>> tagNameToFileSet)
{
// Figure out the project that this target belongs to
FileReference projectFile = null;
if (_parameters.Project != null)
{
projectFile = new FileReference(_parameters.Project);
if (!FileReference.Exists(projectFile))
{
throw new AutomationException("Missing project file - {0}", projectFile.FullName);
}
}
// ExecuteAsync the cooker
using (IScope scope = GlobalTracer.Instance.BuildSpan("Cook").StartActive())
{
scope.Span.SetTag("project", projectFile == null ? "UE4" : projectFile.GetFileNameWithoutExtension());
scope.Span.SetTag("platform", _parameters.Platform);
string[] maps = (_parameters.Maps == null) ? null : _parameters.Maps.Split(new char[] { '+' });
string arguments = (_parameters.Versioned ? "" : "-Unversioned ") + _parameters.Arguments;
string editorExe = (string.IsNullOrWhiteSpace(_parameters.EditorExe) ? ProjectUtils.GetEditorForProject(projectFile).FullName : _parameters.EditorExe);
CommandUtils.CookCommandlet(projectFile, editorExe, maps, null, null, null, _parameters.Platform, arguments);
}
// Find all the cooked files
List<FileReference> cookedFiles = new List<FileReference>();
if (_parameters.TagOutput)
{
foreach (string platform in _parameters.Platform.Split('+'))
{
DirectoryReference platformCookedDirectory = DirectoryReference.Combine(projectFile.Directory, "Saved", "Cooked", platform);
if (!DirectoryReference.Exists(platformCookedDirectory))
{
throw new AutomationException("Cook output directory not found ({0})", platformCookedDirectory.FullName);
}
List<FileReference> platformCookedFiles = DirectoryReference.EnumerateFiles(platformCookedDirectory, "*", System.IO.SearchOption.AllDirectories).ToList();
if (platformCookedFiles.Count == 0)
{
throw new AutomationException("Cooking did not produce any files in {0}", platformCookedDirectory.FullName);
}
cookedFiles.AddRange(platformCookedFiles);
}
}
// Apply the optional tag to the build products
foreach (string tagName in FindTagNamesFromList(_parameters.Tag))
{
FindOrAddTagSet(tagNameToFileSet, tagName).UnionWith(cookedFiles);
}
// Add them to the set of build products
buildProducts.UnionWith(cookedFiles);
return Task.CompletedTask;
}
/// <summary>
/// Output this task out to an XML writer.
/// </summary>
public override void Write(XmlWriter writer)
{
Write(writer, _parameters);
}
/// <summary>
/// Find all the tags which are used as inputs to this task
/// </summary>
/// <returns>The tag names which are read by this task</returns>
public override IEnumerable<string> FindConsumedTagNames()
{
yield break;
}
/// <summary>
/// Find all the tags which are modified by this task
/// </summary>
/// <returns>The tag names which are modified by this task</returns>
public override IEnumerable<string> FindProducedTagNames()
{
return FindTagNamesFromList(_parameters.Tag);
}
}
}