Skip to content

Commit

Permalink
Reparent absolute path in .target files prior to packaging in Project…
Browse files Browse the repository at this point in the history
…Package tests
  • Loading branch information
hach-que committed Apr 4, 2024
1 parent 236b24b commit ae8dd56
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,19 @@ await writer.WriteAgentNodeAsync(
},
async writer =>
{
await writer.WriteSpawnAsync(
new SpawnElementProperties
{
Exe = "$(UETPath)",
Arguments =
[
"$(UETGlobalArgs)",
"internal",
"reparent-additional-properties-in-targets",
"--project-directory-path",
$"\"$(TempPath)/{assembledProjectName}\"",
]
}).ConfigureAwait(false);
await writer.WriteCommandAsync(
new CommandElementProperties
{
Expand Down
2 changes: 2 additions & 0 deletions UET/uet/Commands/Internal/InternalCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using UET.Commands.Internal.OpenGE;
using UET.Commands.Internal.OpenGEPreprocessorCache;
using UET.Commands.Internal.RemoveStalePrecompiledHeaders;
using UET.Commands.Internal.ReparentAdditionalPropertiesInTargets;
using UET.Commands.Internal.RunDownstreamTest;
using UET.Commands.Internal.RunDriveMappedProcess;
using UET.Commands.Internal.RunGauntletTestFromBuildGraph;
Expand Down Expand Up @@ -58,6 +59,7 @@ public static Command CreateInternalCommand(HashSet<Command> globalCommands)
RunRemoteHostCommand.CreateRunRemoteHostCommand(),
RunRemoteCommand.CreateRunRemoteCommand(),
InspectSnmpCommand.CreateInspectSnmpCommand(),
ReparentAdditionalPropertiesInTargetsCommand.CreateReparentAdditionalPropertiesInTargetsCommand(),
};

var command = new Command("internal", "Internal commands used by UET when it needs to call back into itself.");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace UET.Commands.Internal.ReparentAdditionalPropertiesInTargets
{
using System.Text.Json.Serialization;

internal class MinimalUnrealTargetFile
{
[JsonPropertyName("AdditionalProperties")]
public List<MinimalUnrealTargetFileAdditionalProperty>? AdditionalProperties { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace UET.Commands.Internal.ReparentAdditionalPropertiesInTargets
{
using System.Text.Json.Serialization;

internal class MinimalUnrealTargetFileAdditionalProperty
{
[JsonPropertyName("Name")]
public string? Name { get; set; }

[JsonPropertyName("Value")]
public string? Value { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace UET.Commands.Internal.ReparentAdditionalPropertiesInTargets
{
using System.Text.Json.Serialization;

[JsonSerializable(typeof(MinimalUnrealTargetFile))]
internal partial class MinimalUnrealTargetFileJsonSerializerContext : JsonSerializerContext
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
namespace UET.Commands.Internal.ReparentAdditionalPropertiesInTargets
{
using Microsoft.Extensions.Logging;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Text.Json;
using System.Threading.Tasks;

internal sealed class ReparentAdditionalPropertiesInTargetsCommand
{
public sealed class Options
{
public Option<DirectoryInfo> ProjectDirectoryPath = new Option<DirectoryInfo>("--project-directory-path") { IsRequired = true };
}

public static Command CreateReparentAdditionalPropertiesInTargetsCommand()
{
var options = new Options();
var command = new Command("reparent-additional-properties-in-targets");
command.AddAllOptions(options);
command.AddCommonHandler<ReparentAdditionalPropertiesInTargetsCommandInstance>(options);
return command;
}

private sealed class ReparentAdditionalPropertiesInTargetsCommandInstance : ICommandInstance
{
private readonly ILogger<ReparentAdditionalPropertiesInTargetsCommandInstance> _logger;
private readonly Options _options;

public ReparentAdditionalPropertiesInTargetsCommandInstance(
ILogger<ReparentAdditionalPropertiesInTargetsCommandInstance> logger,
Options options)
{
_logger = logger;
_options = options;
}

public async Task<int> ExecuteAsync(InvocationContext context)
{
var projectDirectoryPath = context.ParseResult.GetValueForOption(_options.ProjectDirectoryPath)!;

foreach (var targetFile in Directory.GetFiles(
Path.Combine(projectDirectoryPath.FullName, "Binaries"),
"*.target",
new EnumerationOptions { RecurseSubdirectories = true }))
{
_logger.LogInformation($"Discovered .target file: {targetFile}");

// Deserialize just enough that we can read the RedpointUETOriginalProjectDirectory property.
var targetText = await File.ReadAllTextAsync(targetFile).ConfigureAwait(false);
var json = JsonSerializer.Deserialize(targetText, MinimalUnrealTargetFileJsonSerializerContext.Default.MinimalUnrealTargetFile);
var originalProjectDirectoryProperty = (json?.AdditionalProperties ?? new List<MinimalUnrealTargetFileAdditionalProperty>())
.FirstOrDefault(x => x.Name == "RedpointUETOriginalProjectDirectory");

// If we have it, just do a really simple find-and-replace on the file. We don't serialize
// via JSON since then UET would need to be updated whenever Unreal changes the schema
// of target files.
if (originalProjectDirectoryProperty?.Value != null)
{
var originalValue = originalProjectDirectoryProperty.Value.Replace("\\", "\\\\", StringComparison.OrdinalIgnoreCase).TrimEnd('\\');
var replacedValue = projectDirectoryPath.FullName.Replace("\\", "\\\\", StringComparison.OrdinalIgnoreCase).TrimEnd('\\');

_logger.LogInformation($"Reparenting absolute paths in .target file: {targetFile} (Replacing '{originalValue}' with '{replacedValue}')");
targetText = targetText.Replace(originalValue, replacedValue, StringComparison.OrdinalIgnoreCase);
await File.WriteAllTextAsync(targetFile, targetText).ConfigureAwait(false);
}
}

return 0;
}
}
}
}

0 comments on commit ae8dd56

Please sign in to comment.