// Copyright Epic Games, Inc. All Rights Reserved.
using AutomationTool;
using System;
using System.IO;
using UnrealBuildTool;
namespace Gauntlet
{
///
/// Manages the overlaying of a development executable over an existing build.
/// These are useful for testing code changes without needing to re-cook or re-package builds.
/// To use overlay executables, simply specify -dev on the UAT commandline.
/// The overlay executable will automatically be applied as long as the following conditions are met
/// - The build being used supports Overlay executables. See BuildFlags.CanReplaceExecutable
/// - The development executable's write time is newer than that of the supplied builds write time
///
public class OverlayExecutable
{
private string ProjectName;
private string Flavor;
private UnrealTargetPlatform Platform;
private UnrealTargetConfiguration Configuration;
private UnrealTargetRole Role;
public OverlayExecutable(UnrealSessionRole SessionRole, string ProjectName)
{
this.ProjectName = ProjectName;
this.Configuration = SessionRole.Configuration;
this.Role = SessionRole.RoleType;
this.Platform = SessionRole.Platform.Value;
this.Flavor = SessionRole.RequiredFlavor;
}
///
/// Attempts to get the path to a local executable if it is newer than the base executable
///
/// The base executable to use if an overlay does not exist
///
/// What extension the overlay file should have
/// True if a local, newer executable that matches the role's requirements exists
///
public bool GetOverlay(string BaseExecutable, out string OverlayExecutable, string ExtensionOverride = null)
{
OverlayExecutable = null;
// If no base executable is specified we'll skip the "newer" check and just return a local binary that matches the role
if (string.IsNullOrEmpty(BaseExecutable))
{
throw new AutomationException("Overlay Error: No base executable was specified.");
}
if (!File.Exists(BaseExecutable) && !Directory.Exists(BaseExecutable)) // mac/ios apps can be directories
{
throw new AutomationException("Overlay Error: Could not find base executable {0}.", BaseExecutable);
}
// Ex. /UnrealGame/Binaries/Win64/UnrealClient.exe
string PlatformBinariesDirectory = Path.Combine(Environment.CurrentDirectory, ProjectName, "Binaries", Platform.ToString());
string ExecutableName = UnrealHelpers.GetExecutableName(ProjectName, Platform, Configuration, Role, Flavor, string.Empty);
string ExecutableExtension = string.IsNullOrEmpty(ExtensionOverride) ? Path.GetExtension(BaseExecutable) : ExtensionOverride;
string LocalExecutable = Path.Combine(PlatformBinariesDirectory, ExecutableName + ExecutableExtension);
if (!File.Exists(LocalExecutable) && !Directory.Exists(LocalExecutable))
{
Log.Verbose("No local executable for {Platform} exists. Skipping overlay for this role", Platform);
return false;
}
if (File.GetLastWriteTime(BaseExecutable) > File.GetLastWriteTime(LocalExecutable))
{
Log.Verbose("Local executable for {Platform} is not newer than base executable. Skipping overlay for this role", Platform);
return false;
}
Log.Info("Applying newer local executable as overlay {LocalExecutable}", LocalExecutable);
OverlayExecutable = LocalExecutable;
return true;
}
}
}