Files
UnrealEngine/Engine/Source/Programs/BuildPatchTool/Private/ToolModes/MergeManifestMode.cpp
2025-05-18 13:04:45 +08:00

105 lines
3.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "ToolModes/MergeManifestMode.h"
#include "Interfaces/IBuildPatchServicesModule.h"
#include "BuildPatchTool.h"
#include "Misc/CommandLine.h"
#include "Misc/Paths.h"
using namespace BuildPatchTool;
class FMergeManifestToolMode : public IToolMode
{
public:
FMergeManifestToolMode(IBuildPatchServicesModule& InBpsInterface)
: BpsInterface(InBpsInterface)
{}
virtual ~FMergeManifestToolMode()
{}
virtual EReturnCode Execute() override
{
// Parse commandline
if (ProcessCommandline() == false)
{
return EReturnCode::ArgumentProcessingError;
}
// Print help if requested
if (bHelp)
{
UE_LOG(LogBuildPatchTool, Display, TEXT("MERGE MANIFEST MODE"));
UE_LOG(LogBuildPatchTool, Display, TEXT("This tool supports generating a hotfix manifest from two existing manifest files."));
UE_LOG(LogBuildPatchTool, Display, TEXT(""));
UE_LOG(LogBuildPatchTool, Display, TEXT("Required arguments:"));
UE_LOG(LogBuildPatchTool, Display, TEXT(" -mode=MergeManifests Must be specified to launch the tool in merge manifests mode."));
UE_LOG(LogBuildPatchTool, Display, TEXT(" -ManifestA=\"\" Specifies in quotes the file path to the base manifest."));
UE_LOG(LogBuildPatchTool, Display, TEXT(" -ManifestB=\"\" Specifies in quotes the file path to the update manifest."));
UE_LOG(LogBuildPatchTool, Display, TEXT(" -ManifestC=\"\" Specifies in quotes the file path to the output manifest."));
UE_LOG(LogBuildPatchTool, Display, TEXT(" -BuildVersion=\"\" Specifies in quotes the new version string for the build being produced."));
UE_LOG(LogBuildPatchTool, Display, TEXT(""));
UE_LOG(LogBuildPatchTool, Display, TEXT("Optional arguments:"));
UE_LOG(LogBuildPatchTool, Display, TEXT(" -MergeFileList=\"\" Specifies in quotes, the path to a text file containing complete list of desired build root relative files followed by \\t character, followed by A or B to select the manifest to pull from. These should be seperated by \\r\\n line endings."));
UE_LOG(LogBuildPatchTool, Display, TEXT(""));
UE_LOG(LogBuildPatchTool, Display, TEXT("NB: If -MergeFileList is not specified, then union of all files will be selected, preferring ManifestB's version."));
UE_LOG(LogBuildPatchTool, Display, TEXT("NB: With the exception of the new version string for the build, all meta will be copied from only ManifestB."));
UE_LOG(LogBuildPatchTool, Display, TEXT(""));
return EReturnCode::OK;
}
// Run the merge manifest routine
bool bSuccess = BpsInterface.MergeManifests(ManifestA, ManifestB, ManifestC, BuildVersion, MergeFileList);
return bSuccess ? EReturnCode::OK : EReturnCode::ToolFailure;
}
private:
bool ProcessCommandline()
{
#define PARSE_SWITCH(Switch) ParseSwitch(TEXT(#Switch "="), Switch, Switches)
TArray<FString> Tokens, Switches;
FCommandLine::Parse(FCommandLine::Get(), Tokens, Switches);
bHelp = ParseOption(TEXT("help"), Switches);
if (bHelp)
{
return true;
}
// Get all required parameters
if (!(PARSE_SWITCH(ManifestA)
&& PARSE_SWITCH(ManifestB)
&& PARSE_SWITCH(ManifestC)
&& PARSE_SWITCH(BuildVersion)))
{
UE_LOG(LogBuildPatchTool, Error, TEXT("ManifestA, ManifestB, ManifestC, and BuildVersion are required parameters"));
return false;
}
NormalizeUriFile(ManifestA);
NormalizeUriFile(ManifestB);
NormalizeUriFile(ManifestC);
// Optional list to pick specific files, otherwise it is A stomped by B
PARSE_SWITCH(MergeFileList);
NormalizeUriFile(MergeFileList);
return true;
#undef PARSE_SWITCH
}
private:
IBuildPatchServicesModule& BpsInterface;
bool bHelp;
FString ManifestA;
FString ManifestB;
FString ManifestC;
FString BuildVersion;
FString MergeFileList;
};
BuildPatchTool::IToolModeRef BuildPatchTool::FMergeManifestToolModeFactory::Create(IBuildPatchServicesModule& BpsInterface)
{
return MakeShareable(new FMergeManifestToolMode(BpsInterface));
}