165 lines
No EOL
5.1 KiB
C#
165 lines
No EOL
5.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.ExceptionServices;
|
|
using JD.Core.ProjectManaging;
|
|
using Packager.BuildConfigurations;
|
|
using Packager.Parameters;
|
|
using Packager.Tasks;
|
|
using LogCategory = JD.LogService.LogCategory;
|
|
|
|
namespace Packager
|
|
{
|
|
/// <summary>
|
|
/// Builder takes in the build configuration's tasklist and executes each task in the list sequentially.
|
|
/// </summary>
|
|
public class Builder : IDisposable
|
|
{
|
|
private readonly TaskList _buildTasks;
|
|
private readonly BuildConfiguration _buildProfile;
|
|
private engineWrapper _engine;
|
|
private cookerWrapper _cooker;
|
|
private readonly bool _stopOnErrors;
|
|
private bool _exit;
|
|
|
|
public MessageLogger Logger { get; } = new MessageLogger(nameof(Builder));
|
|
|
|
public Builder(BuildConfiguration profile, bool stopOnErrors)
|
|
{
|
|
_buildProfile = profile;
|
|
_buildTasks = _buildProfile.Tasks;
|
|
_stopOnErrors = stopOnErrors;
|
|
}
|
|
|
|
public void BuildTaskList(int startTask = 0)
|
|
{
|
|
var taskNameString = string.Join(";", _buildTasks.Select(task => task.InstanceName));
|
|
Logger.LogInfo("[Tasklist]" + taskNameString);
|
|
|
|
foreach (var task in _buildTasks.Skip(startTask))
|
|
{
|
|
if (_exit)
|
|
{
|
|
Logger.LogTaskMessage(task, "Aborting the build as StopOnError is on", LogCategory.Error);
|
|
break;
|
|
}
|
|
|
|
Logger.LogInfo($"{task.InstanceName} task was created, its log file can be found at \"{task.Logger.LogFilePath}\".");
|
|
|
|
ExecuteCurrentTask(task);
|
|
CheckTaskErrors(task);
|
|
TaskFinishCleanUp(task);
|
|
}
|
|
}
|
|
|
|
[HandleProcessCorruptedStateExceptions]
|
|
private void ExecuteCurrentTask(Task task)
|
|
{
|
|
try
|
|
{
|
|
string outputPath = task.TaskOutputFolder;
|
|
|
|
if (!Directory.Exists(outputPath))
|
|
{
|
|
Directory.CreateDirectory(outputPath);
|
|
}
|
|
|
|
Logger.LogStartedTask(task);
|
|
|
|
TaskUtility.ValidateTaskInput(task);
|
|
|
|
if (task.NeedCooker)
|
|
{
|
|
_engine = new engineWrapper("Packager");
|
|
_cooker = new cookerWrapper();
|
|
_cooker.init(DataPath.Value);
|
|
|
|
Logger.AttachCookerWrapper(_cooker);
|
|
}
|
|
|
|
task.Start(_buildProfile, _cooker);
|
|
}
|
|
catch (AccessViolationException ex)
|
|
{
|
|
HandleAccessViolationError(task, ex);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
HandleLaunchError(task, ex);
|
|
}
|
|
}
|
|
|
|
private void CheckTaskErrors(Task task)
|
|
{
|
|
if (task.ErrorCode == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Logger.LogTaskMessage(task, $"Returns error {task.ErrorCode}", LogCategory.Error);
|
|
CheckToStopExecution();
|
|
}
|
|
|
|
private void HandleLaunchError(Task task, Exception ex)
|
|
{
|
|
var message = $"When launching the task \"{task.InstanceName}\": {ex.Message}. Details: {ex}";
|
|
Logger.LogTaskMessage(task, message, ex is EmptyInputException ? LogCategory.Warning : LogCategory.Error);
|
|
|
|
CheckToStopExecution();
|
|
}
|
|
|
|
private void HandleAccessViolationError(Task task, Exception ex)
|
|
{
|
|
var message = $"Access Violation Exception when launching the task \"{task.InstanceName}\". If this error occurs in ITF.EngineSignature.computeEngineSignature(), please check with the engine and ggp teams if changes were made in serializable classes. Please check {Logger.LogFilePath} for the stacktrace. Details: {ex}";
|
|
Logger.LogTaskMessage(task, message, LogCategory.Error);
|
|
//Force stop execution because an access violation error is not recoverable
|
|
_exit = true;
|
|
}
|
|
|
|
private void CheckToStopExecution()
|
|
{
|
|
if (_stopOnErrors)
|
|
{
|
|
_exit = true;
|
|
}
|
|
}
|
|
|
|
public void TaskFinishCleanUp(Task task)
|
|
{
|
|
if (_cooker != null)
|
|
{
|
|
Logger.DetachCookerWrapper(_cooker);
|
|
|
|
_cooker.destroy();
|
|
_cooker = null;
|
|
}
|
|
|
|
if (_engine != null)
|
|
{
|
|
_engine.destroy();
|
|
_engine = null;
|
|
}
|
|
|
|
SaveTaskOutput(task);
|
|
|
|
Logger.LogEndedTask(task);
|
|
}
|
|
|
|
private void SaveTaskOutput(Task task)
|
|
{
|
|
try
|
|
{
|
|
task.SaveOutputs(task.TaskOutputFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogTaskMessage(task, $"Error while saving the task outputs: {ex.Message}", LogCategory.Error);
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_cooker?.Dispose();
|
|
}
|
|
}
|
|
} |