Files
UnrealEngineUWP/Engine/Source/Programs/AutomationTool/Program.cs
Ben Marsh 273dfca9b8 Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 2972140)
==========================
MAJOR FEATURES + CHANGES
==========================

Change 2959679 on 2016/04/28 by Ben.Marsh

	UGS: Show the original author for changes with a #ROBOMERGE-AUTHOR tag.

Change 2959695 on 2016/04/28 by Ben.Marsh

	UGS: Only filter out changes from by buildmachine that contain the string "CIS Counter".

Change 2960798 on 2016/04/29 by Ben.Marsh

	Remove C++ version of ParallelExecutor. Now implemented in C# as part of UAT.

Change 2960928 on 2016/04/29 by Ben.Marsh

	UGS: Change filter for buildmachine changes to only include rebuilt lightmaps.

Change 2963214 on 2016/05/02 by Ben.Marsh

	BuildGraph: Allow specifying optional dependencies for a node, indicating that the build products from an upstream node are desired, but should not block the node from running.

Change 2964454 on 2016/05/03 by Ben.Marsh

	Change PostBuildInfoTool to PostBadgeStatus, and add position-independent argument parsing.

Change 2964533 on 2016/05/03 by Ben.Marsh

	BuildGraph: Add the ability to generate summary badges from BuildGraph scripts, which can be pushed into a separate database for consumption by UGS.

Change 2964852 on 2016/05/03 by Ben.Marsh

	BuildGraph: Add a task which can submit a set of files to Perforce, optionally creating and using a different workspace to do so.

Change 2966856 on 2016/05/04 by Ben.Marsh

	EC: Allow specifying a filter for the changes considered when looking for the most recent change. Allows filtering out content changes for UGS builds, code-only builds, etc...

Change 2966867 on 2016/05/04 by Ben.Marsh

	EC: Restore code to always set time in CIS state; we never want large builds to trigger off their defined interval.

Change 2967504 on 2016/05/05 by Ben.Marsh

	UAT: Make sure the intermediate directory exists before writing out the list of changes in StreamCopyDescription.

Change 2967778 on 2016/05/05 by Ben.Marsh

	UAT: Detect the P4 environment by querying Perforce for the setting of P4PORT, rather than assuming it's set in an environment variable. Windows stores this setting in the registry rather than the environment, but it's also valid to be set via P4CONFIG.

Change 2967815 on 2016/05/05 by Ben.Marsh

	EC: Copy the initial resource pool setting from the stream settings into an EC property

Change 2967873 on 2016/05/05 by Ben.Marsh

	EC: Allow stream settings to be stored directly in /GUBP_V5/Streams/ rather than having to be in a child property sheet.

Change 2969294 on 2016/05/06 by Ben.Marsh

	EC: Extend ConformResources command to allow updating the pools that resources are assigned to, and to limit the number of machines which are syncing at once. Also added new EC procedure to allow specifying these arguments.

Change 2969371 on 2016/05/06 by Ben.Marsh

	EC: Allow overriding the stream and workspace identifier synced by the builders. Overriding the stream allows syncing a narrower view of files (eg. Dev-Main vs Main), and overriding the workspace identifier allows sharing a workspace between two streams.

Change 2970623 on 2016/05/09 by Ben.Marsh

	UAT: Prevent Ctrl-C handler delegate from being garbage collected and failing to be triggered.

Change 2970627 on 2016/05/09 by Ben.Marsh

	UAT: Don't limit the list of valid target platforms specified on the command line to just those that we have initialized. Ignoring the platform if the SDK is not installed is never what the user wants.

Change 2972140 on 2016/05/10 by Ben.Marsh

	Change 'Engine, Tools and Monolithics' to include QAGame and Template editors, but exclude everything downstream of a trigger.

#lockdown Nick.Penwarden

[CL 2972146 by Ben Marsh in Main branch]
2016-05-10 08:49:41 -04:00

144 lines
5.3 KiB
C#

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
// This software is provided "as-is," without any express or implied warranty.
// In no event shall the author, nor Epic Games, Inc. be held liable for any damages arising from the use of this software.
// This software will not be supported.
// Use at your own risk.
using System;
using System.Threading;
using System.Diagnostics;
using UnrealBuildTool;
using System.Reflection;
using Tools.DotNETCommon;
using System.IO;
namespace AutomationTool
{
public class Program
{
/// <summary>
/// Keep a persistent reference to the delegate for handling Ctrl-C events. Since it's passed to non-managed code, we have to prevent it from being garbage collected.
/// </summary>
static ProcessManager.CtrlHandlerDelegate CtrlHandlerDelegateInstance = CtrlHandler;
[STAThread]
public static int Main()
{
var CommandLine = SharedUtils.ParseCommandLine();
LogUtils.InitLogging(CommandLine);
ExitCode ReturnCode = ExitCode.Success;
try
{
// ensure we can resolve any external assemblies as necessary.
AssemblyUtils.InstallAssemblyResolver(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()));
HostPlatform.Initialize();
Log.TraceVerbose("{2}: Running on {0} as a {1}-bit process.", HostPlatform.Current.GetType().Name, Environment.Is64BitProcess ? 64 : 32, DateTime.UtcNow.ToString("o"));
XmlConfigLoader.Init();
// Log if we're running from the launcher
var ExecutingAssemblyLocation = Assembly.GetExecutingAssembly().Location;
if (string.Compare(ExecutingAssemblyLocation, Assembly.GetEntryAssembly().GetOriginalLocation(), StringComparison.OrdinalIgnoreCase) != 0)
{
Log.TraceVerbose("Executed from AutomationToolLauncher ({0})", ExecutingAssemblyLocation);
}
Log.TraceVerbose("CWD={0}", Environment.CurrentDirectory);
// Hook up exit callbacks
var Domain = AppDomain.CurrentDomain;
Domain.ProcessExit += Domain_ProcessExit;
Domain.DomainUnload += Domain_ProcessExit;
HostPlatform.Current.SetConsoleCtrlHandler(CtrlHandlerDelegateInstance);
var Version = AssemblyUtils.ExecutableVersion;
Log.TraceVerbose("{0} ver. {1}", Version.ProductName, Version.ProductVersion);
// Don't allow simultaneous execution of AT (in the same branch)
ReturnCode = InternalUtils.RunSingleInstance(MainProc, CommandLine);
}
catch (AutomationException Ex)
{
Log.TraceError("AutomationTool terminated with exception: {0}", Ex);
ReturnCode = Ex.ErrorCode;
}
catch (Exception Ex)
{
// Catch all exceptions and propagate the ErrorCode if we are given one.
Log.TraceError("AutomationTool terminated with exception: {0}", Ex);
ReturnCode = ExitCode.Error_Unknown;
}
finally
{
// In all cases, do necessary shut down stuff, but don't let any additional exceptions leak out while trying to shut down.
// Make sure there's no directories on the stack.
NoThrow(() => CommandUtils.ClearDirStack(), "Clear Dir Stack");
// Try to kill process before app domain exits to leave the other KillAll call to extreme edge cases
NoThrow(() => { if (ShouldKillProcesses && !Utils.IsRunningOnMono) ProcessManager.KillAll(); }, "Kill All Processes");
Log.TraceInformation("AutomationTool exiting with ExitCode={0} ({1})", (int)ReturnCode, ReturnCode);
// Can't use NoThrow here because the code logs exceptions. We're shutting down logging!
LogUtils.ShutdownLogging();
}
// STOP: No code beyond the return statement should go beyond this point!
// Nothing should happen after the finally block above is finished.
return (int)ReturnCode;
}
/// <summary>
/// Wraps an action in an exception block.
/// Ensures individual actions can be performed and exceptions won't prevent further actions from being executed.
/// Useful for shutdown code where shutdown may be in several stages and it's important that all stages get a chance to run.
/// </summary>
/// <param name="Action"></param>
private static void NoThrow(System.Action Action, string ActionDesc)
{
try
{
Action();
}
catch (Exception Ex)
{
Log.TraceError("Exception performing nothrow action \"{0}\": {1}", ActionDesc, LogUtils.FormatException(Ex));
}
}
static bool CtrlHandler(CtrlTypes EventType)
{
Domain_ProcessExit(null, null);
if (EventType == CtrlTypes.CTRL_C_EVENT)
{
// Force exit
Environment.Exit(3);
}
return true;
}
static void Domain_ProcessExit(object sender, EventArgs e)
{
// Kill all spawned processes (Console instead of Log because logging is closed at this time anyway)
Console.WriteLine("Domain_ProcessExit");
if (ShouldKillProcesses && !Utils.IsRunningOnMono)
{
ProcessManager.KillAll();
}
Trace.Close();
}
static ExitCode MainProc(object Param)
{
ExitCode Result = Automation.Process((string[])Param);
ShouldKillProcesses = Automation.ShouldKillProcesses;
return Result;
}
static bool ShouldKillProcesses = true;
}
}