Skip to content

Commit

Permalink
Merge pull request #77 from guitarrapc/feature/logfile
Browse files Browse the repository at this point in the history
fix:  treat `-logFile -` as invalid and replace to default log filename
  • Loading branch information
guitarrapc committed Jun 28, 2023
2 parents 9180373 + d3c7797 commit 2cd9736
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 19 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ await builder.BuildAsync(cts.Token);
Console.WriteLine(builder.ExitCode);
```

# TODO
## FAQ

- [x] dotnet global command
- [x] core logic as nuget
**What happen when passing `-logFile -` argument?**

Unity.exe not generate log file when passing `-` as log file name. Therefore UnityBuildRunner replace `-` to temporary log file `unitybuild.log` instead.
2 changes: 2 additions & 0 deletions src/UnityBuildRunner.Core/BuildErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ internal enum BuildErrorCode
ProcessTimeout,
[ErrorExitCode(9904)]
OperationCancelled,
[ErrorExitCode(9905)]
LogFileNotFound,
[ErrorExitCode(9999)]
OtherError,
}
Expand Down
17 changes: 17 additions & 0 deletions src/UnityBuildRunner.Core/BuildErrorFoundException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,20 @@ public BuildErrorFoundException(string message, string stdout, string matchPatte
MatchPattern = matchPattern;
}
}


internal class BuildLogNotFoundException : Exception
{
public override string Message => message;
private string message;

public string LogFilePath { get; }
public string FullPath { get; }

public BuildLogNotFoundException(string message, string logFilePath, string fullPath)
{
this.message = message;
LogFilePath = logFilePath;
FullPath = fullPath;
}
}
45 changes: 31 additions & 14 deletions src/UnityBuildRunner.Core/DefaultBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,34 +70,34 @@ public async Task BuildAsync(CancellationToken ct = default)

if (process is null)
{
sw.Stop();
buildErrorCode = BuildErrorCode.ProcessNull;
throw new OperationCanceledException("Could not start Unity. Somthing blocked creating process.");
}

var unityProcessExitCode = 0;
var logFileFound = false;
try
{
// wait for log file generated.
while (!File.Exists(settings.LogFilePath) && !process.HasExited)
while (!process.HasExited)
{
// retry in 10 seconds.
if (sw.Elapsed.TotalSeconds < 10 * 1000)
logFileFound = File.Exists(settings.LogFilePath);
if (logFileFound) break;

// retry for 10 seconds.
if (sw.Elapsed.TotalSeconds < 10)
{
await Task.Delay(TimeSpan.FromMilliseconds(10), ct).ConfigureAwait(false);
}
else
{
buildErrorCode = BuildErrorCode.ProcessTimeout;
throw new TimeoutException($"Unity Process has been aborted. Waited 10 seconds but could't create logFilePath '{settings.LogFilePath}'.");
throw new BuildLogNotFoundException($"Unity Process not created logfile.", settings.LogFilePath, Path.Combine(settings.WorkingDirectory, settings.LogFilePath));
}
}

// log file generated but process immediately exited.
if (process.HasExited)
{
buildErrorCode = BuildErrorCode.ProcessImmediatelyExit;
throw new OperationCanceledException($"Unity process started but build unexpectedly finished before began.");
throw new OperationCanceledException($"Unity process started but build unexpectedly finished.");
}

using (var file = File.Open(settings.LogFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
Expand All @@ -122,26 +122,43 @@ public async Task BuildAsync(CancellationToken ct = default)
buildErrorCode = BuildErrorCode.UnityProcessError;
}
}
catch (OperationCanceledException ex) when (process is null)
{
// process could not create
logger.LogInformation($"Stopping build. {ex.Message}");
buildErrorCode = BuildErrorCode.ProcessNull;
}
catch (OperationCanceledException ex) when (process.HasExited)
{
// process immediately finished
logger.LogInformation($"Stopping build. {ex.Message}");
buildErrorCode = BuildErrorCode.ProcessImmediatelyExit;
}
catch (OperationCanceledException) when (sw.Elapsed.TotalMilliseconds > settings.TimeOut.TotalMilliseconds)
{
// Timeout
logger.LogInformation($"Timeout exceeded, {settings.TimeOut.TotalMinutes}min has been passed. Stopping build.");
logger.LogInformation($"Stopping build. Timeout exceeded, {settings.TimeOut.TotalMinutes}min has been passed.");
buildErrorCode = BuildErrorCode.ProcessTimeout;
}
catch (OperationCanceledException)
{
// User cancel or any cancellation detected
logger.LogInformation("Operation canceled. Stopping build.");
logger.LogInformation("Stopping build. Operation canceled.");
buildErrorCode = BuildErrorCode.OperationCancelled;
}
catch (BuildErrorFoundException bex)
catch (BuildErrorFoundException ex)
{
logger.LogInformation($"Error filter caught message '{bex.StdOut}'. Stopping build.");
logger.LogInformation($"Stopping build. {ex.Message} stdout: '{ex.StdOut}'");
buildErrorCode = BuildErrorCode.BuildErrorMessageFound;
}
catch (BuildLogNotFoundException ex)
{
logger.LogCritical(ex, $"Stopping build. {ex.Message} logFile: '{ex.LogFilePath}', FullPath: '{ex.FullPath}'.");
buildErrorCode = BuildErrorCode.LogFileNotFound;
}
catch (Exception ex)
{
logger.LogCritical(ex, $"Error happen while building Unity. Error message: {ex.Message}");
logger.LogCritical(ex, $"Stopping build. Error happen while building Unity. {ex.Message}");
buildErrorCode = BuildErrorCode.OtherError;
}
finally
Expand Down
19 changes: 17 additions & 2 deletions src/UnityBuildRunner.Core/DefaultSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,15 @@ public static DefaultSettings Parse(IReadOnlyList<string> args, string unityPath

// parse and fallback logfilePath
var logFilePath = ParseLogFile(args);
if (string.IsNullOrWhiteSpace(logFilePath))
if (!IsValidLogFileName(logFilePath))
{
var inputLogFilePath = logFilePath;
logFilePath = "unitybuild.log";
args = args.Concat(new[] { "-logFile", logFilePath }).ToArray();
// remove current `-logFile "-"` and replace to `-logFile unitybuild.log`
var tmpArgs = string.IsNullOrEmpty(logFilePath)
? args.Except(new[] { "-logFile" }, StringComparer.OrdinalIgnoreCase).Concat(new[] { "-logFile", logFilePath })
: args.Except(new[] { "-logFile" }, StringComparer.OrdinalIgnoreCase).Except(new[] { inputLogFilePath } ).Concat(new[] { "-logFile", logFilePath });
args = tmpArgs.ToArray();
}

var arguments = args.Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
Expand Down Expand Up @@ -155,4 +160,14 @@ internal static string ParseLogFile(IReadOnlyList<string> args)
}
return logFile;
}

internal static bool IsValidLogFileName(string? fileName)
{
// missing filename is not valid
if (fileName is null) return false;
if (fileName is "") return false;
// Unity not create logfile when "-" passed. It's unexpected for UnityBuildRunner.
if (fileName == "-") return false;
return true;
}
}
4 changes: 4 additions & 0 deletions src/UnityBuildRunner/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"environmentVariables": {
"UnityPath": "C:\\Program Files\\Unity\\Hub\\Editor\\2021.3.17f1\\Editor\\Unity.exe"
}
},
"UnityBuildRunner (-logFile -)": {
"commandName": "Project",
"commandLineArgs": "--unity-path \"C:/Program Files/Unity/Hub/Editor/2021.3.17f1/Editor/Unity.exe\" -quit -batchmode -nographics -silent-crashes -logfile - -buildTarget StandaloneWindows64 -projectPath ../../../../../sandbox/Sandbox.Unity -executeMethod BuildUnity.BuildGame"
}
}
}
11 changes: 11 additions & 0 deletions tests/UnityBuildRunner.Core.Tests/SettingsUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,15 @@ public void ArgsumentStringShouldFormated(string[] actual, string expected)
ISettings settings = DefaultSettings.Parse(actual, _unityPath, _timeout);
settings.ArgumentString.Should().Be(expected);
}

[Theory]
[InlineData(null, false)]
[InlineData("", false)]
[InlineData("-", false)]
[InlineData("foo", true)]
[InlineData("log.log", true)]
public void IsValidLogFilePath(string? logFilePath, bool expected)
{
DefaultSettings.IsValidLogFileName(logFilePath).Should().Be(expected);
}
}

0 comments on commit 2cd9736

Please sign in to comment.