├── .gitignore ├── Resources └── Icon128.png ├── Source └── ProjectVersionFromGit │ ├── Public │ ├── ProjectVersionFromGit.h │ ├── ProjectVersionGitSettings.h │ └── ProjectVersionFromGitBPLibrary.h │ ├── ProjectVersionFromGit.Build.cs │ └── Private │ ├── ProjectVersionFromGit.cpp │ ├── ProjectVersionGitSettings.cpp │ └── ProjectVersionFromGitBPLibrary.cpp ├── ProjectVersionFromGit.uplugin ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.sln 2 | .vs 3 | Binaries 4 | Intermediate 5 | Saved 6 | Build 7 | .DS_Store -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrbindraw/ProjectVersionFromGit/HEAD/Resources/Icon128.png -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/Public/ProjectVersionFromGit.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "Modules/ModuleManager.h" 6 | 7 | #if WITH_EDITOR 8 | #include "ISettingsModule.h" 9 | #include "ProjectVersionGitSettings.h" 10 | #endif 11 | 12 | class FProjectVersionFromGitModule : public IModuleInterface 13 | { 14 | public: 15 | 16 | /** IModuleInterface implementation */ 17 | virtual void StartupModule() override; 18 | virtual void ShutdownModule() override; 19 | }; 20 | -------------------------------------------------------------------------------- /ProjectVersionFromGit.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 7, 4 | "VersionName": "2.5.3", 5 | "FriendlyName": "ProjectVersionFromGit", 6 | "Description": "Set version for project from git tag format MAJOR.MINOR.PATCH also set branch name, commit hash and datetime build", 7 | "Category": "Source Control", 8 | "CreatedBy": "Andrew Bindraw", 9 | "CreatedByURL": "https://github.com/mrbindraw", 10 | "DocsURL": "https://github.com/mrbindraw/ProjectVersionFromGit/blob/master/README.md", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/59246af04cae4760be3934baebaef588", 12 | "SupportURL": "mailto:mrbindraw@gmail.com", 13 | "CanContainContent": false, 14 | "IsBetaVersion": false, 15 | "IsExperimentalVersion": false, 16 | "Installed": false, 17 | "Modules": [ 18 | { 19 | "Name": "ProjectVersionFromGit", 20 | "Type": "Runtime", 21 | "LoadingPhase": "Default", 22 | "PlatformAllowList": [ 23 | "Win64", 24 | "Android", 25 | "Mac", 26 | "IOS", 27 | "Linux" 28 | ] 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Andrew Bindraw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/Public/ProjectVersionGitSettings.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Misc/ConfigCacheIni.h" 7 | #include "ProjectVersionGitSettings.generated.h" 8 | 9 | DECLARE_LOG_CATEGORY_EXTERN(LogProjectVersionGitSettings, Log, All); 10 | 11 | DECLARE_MULTICAST_DELEGATE(FPostInitPropertiesDelegate); 12 | 13 | #if WITH_EDITOR 14 | DECLARE_MULTICAST_DELEGATE(FPostEditChangePropertyDelegate); 15 | #endif 16 | 17 | UCLASS(Config = ProjectVersionGitSettings, DefaultConfig) 18 | class PROJECTVERSIONFROMGIT_API UProjectVersionGitSettings : public UObject 19 | { 20 | GENERATED_BODY() 21 | 22 | public: 23 | UProjectVersionGitSettings(const FObjectInitializer& ObjectInitializer); 24 | 25 | virtual void PostInitProperties() override; 26 | static FPostInitPropertiesDelegate OnPostInitPropertiesCompleted; 27 | 28 | #if WITH_EDITOR 29 | virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; 30 | static FPostEditChangePropertyDelegate OnPostEditChangePropertyCompleted; 31 | #endif 32 | 33 | UPROPERTY(Config, EditAnywhere, Category = "Settings", DisplayName = "Path to git binary file") 34 | FString GitBinPath; 35 | }; 36 | -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/ProjectVersionFromGit.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class ProjectVersionFromGit : ModuleRules 6 | { 7 | public ProjectVersionFromGit(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "CoreUObject", 38 | "Engine", 39 | "Slate", 40 | "SlateCore", 41 | // ... add private dependencies that you statically link with here ... 42 | } 43 | ); 44 | 45 | 46 | DynamicallyLoadedModuleNames.AddRange( 47 | new string[] 48 | { 49 | // ... add any modules that your module loads dynamically here ... 50 | } 51 | ); 52 | 53 | if (Target.Type == TargetType.Editor) 54 | { 55 | DynamicallyLoadedModuleNames.Add("Settings"); 56 | PrivateIncludePathModuleNames.Add("Settings"); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/Private/ProjectVersionFromGit.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | #include "ProjectVersionFromGit.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FProjectVersionFromGitModule" 6 | 7 | void FProjectVersionFromGitModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | 11 | #if WITH_EDITOR 12 | ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); 13 | 14 | if (SettingsModule != nullptr) 15 | { 16 | SettingsModule->RegisterSettings("Project", "Plugins", "ProjectVersionGit", 17 | LOCTEXT("ProjectVersionGitSettingsName", "Project Version Git"), 18 | LOCTEXT("ProjectVersionGitSettingsDescription", "Configure the ProjectVersionFromGit plugin"), 19 | GetMutableDefault() 20 | ); 21 | } 22 | #endif //WITH_EDITOR 23 | } 24 | 25 | void FProjectVersionFromGitModule::ShutdownModule() 26 | { 27 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 28 | // we call this function before unloading the module. 29 | 30 | #if WITH_EDITOR 31 | ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"); 32 | if (SettingsModule != nullptr) 33 | { 34 | SettingsModule->UnregisterSettings("Project", "Plugins", "ProjectVersionGit"); 35 | } 36 | #endif //WITH_EDITOR 37 | 38 | } 39 | 40 | #undef LOCTEXT_NAMESPACE 41 | 42 | IMPLEMENT_MODULE(FProjectVersionFromGitModule, ProjectVersionFromGit) 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ProjectVersionFromGit 2 | This plugin set version for project from git tag format MAJOR.MINOR.PATCH also set branch name, commit hash and utc-datetime build. 3 | 4 | **C++/Blueprints functions:** 5 | - GetProjectVersion() 6 | - GetProjectVersionMajor() 7 | - GetProjectVersionMinor() 8 | - GetProjectVersionPatch() 9 | - GetProjectVersionBranchName() 10 | - GetProjectVersionCommitHash() 11 | - GetProjectVersionDateTimeBuild() 12 | - GetProjectVersionFormatAll() 13 | 14 | # Install into Project 15 | You can install manually by extracting archive `ProjectVersionFromGit-X.X.X-UE-X.X.zip` from 16 | [Releases](https://github.com/mrbindraw/ProjectVersionFromGit/releases) to your project plugins folder 17 | or build example project `ExamplePrj-UE-X.X-ProjectVersionFromGit-X.X.X.zip`. 18 | 19 | # Install into Unreal Engine 20 | You can install it from the marketplace [ProjectVersionFromGit](https://www.fab.com/listings/044c4f9a-eedc-487b-a973-c1c940470373) 21 | 22 | Manual: 23 | 1. Download and extracting archive `ProjectVersionFromGit-X.X.X-UE-X.X.zip` from [Releases](https://github.com/mrbindraw/ProjectVersionFromGit/releases) to any disk path, for example: `D:\Plugins` 24 | 2. Than open any terminal (cmd, powershell) in `D:\Plugins` folder 25 | 3. Launch `RunUAT` in the terminal with arguments, for example: 26 | 27 | Windows: 28 | ``` 29 | D:\EpicGames\UE_5.4\Engine\Build\BatchFiles\RunUAT.bat BuildPlugin -Plugin=D:\Plugins\ProjectVersionFromGit\ProjectVersionFromGit.uplugin -Package=D:\Plugins\UE_5.4\ProjectVersionFromGit -Rocket 30 | ``` 31 | Mac: 32 | ``` 33 | sh "/Users/Shared/Epic Games/UE_5.4/Engine/Build/BatchFiles/RunUAT.sh" BuildPlugin -Plugin="$PWD/ProjectVersionFromGit/ProjectVersionFromGit.uplugin" -Package="$PWD/5.4/ProjectVersionFromGit" -Rocket 34 | ``` 35 | 4. If you see the message `BUILD SUCCESSFUL` in the terminal after the build is complete, 36 | copy the `ProjectVersionFromGit` folder from `D:\Plugins\UE_5.4` to `D:\EpicGames\UE_5.4\Engine\Plugins\Marketplace` 37 | > [!IMPORTANT] 38 | > **The engine path and folder names may differ on your system.** 39 | -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/Public/ProjectVersionFromGitBPLibrary.h: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "Engine/Engine.h" 6 | #include "Misc/DateTime.h" 7 | #include "Misc/Paths.h" 8 | #include "Internationalization/Regex.h" 9 | #include "GenericPlatform/GenericPlatformProcess.h" 10 | #include "Misc/DefaultValueHelper.h" 11 | #include "Misc/ConfigCacheIni.h" 12 | #include "Misc/EngineVersion.h" 13 | #include "Runtime/Launch/Resources/Version.h" 14 | #include "ProjectVersionGitSettings.h" 15 | #include "Async/Async.h" 16 | 17 | #include "Kismet/BlueprintFunctionLibrary.h" 18 | #include "ProjectVersionFromGitBPLibrary.generated.h" 19 | 20 | DECLARE_LOG_CATEGORY_EXTERN(LogProjectVersionFromGitBPLibrary, Log, All); 21 | 22 | DECLARE_DYNAMIC_DELEGATE(FParseVersionDelegate); 23 | 24 | UCLASS() 25 | class PROJECTVERSIONFROMGIT_API UProjectVersionFromGitBPLibrary : public UBlueprintFunctionLibrary 26 | { 27 | GENERATED_UCLASS_BODY() 28 | 29 | public: 30 | virtual void PostInitProperties() override; 31 | 32 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 33 | static FText GetProjectVersion(); 34 | 35 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 36 | static int32 GetProjectVersionMajor(); 37 | 38 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 39 | static int32 GetProjectVersionMinor(); 40 | 41 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 42 | static int32 GetProjectVersionPatch(); 43 | 44 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 45 | static FText GetProjectVersionBranchName(); 46 | 47 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 48 | static FText GetProjectVersionCommitHash(); 49 | 50 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 51 | static FText GetProjectVersionDateTimeBuild(); 52 | 53 | UFUNCTION(BlueprintPure, Category = "ProjectVersionFromGit") 54 | static FText GetProjectVersionFormatAll(); 55 | 56 | UFUNCTION(BlueprintCallable, Category = "ProjectVersionFromGit") 57 | static void GetProjectVersionInfo(FParseVersionDelegate OnCompleted); 58 | 59 | static bool ExecProcess(const TCHAR* URL, const TCHAR* Params, int32* OutReturnCode, FString* OutStdOut, FString* OutStdErr, const TCHAR* OptionalWorkingDirectory); 60 | 61 | private: 62 | static FText ProjectVersion; 63 | static FText ProjectVersionFormatAll; 64 | static FText CommitHash; 65 | static FText BranchName; 66 | static FText DateTimeBuild; 67 | static int32 Major; 68 | static int32 Minor; 69 | static int32 Patch; 70 | 71 | static FString SectionName; 72 | static FString VersionFileIni; 73 | 74 | static FString GitStdOutput; 75 | }; 76 | -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/Private/ProjectVersionGitSettings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | #include "ProjectVersionGitSettings.h" 4 | 5 | DEFINE_LOG_CATEGORY(LogProjectVersionGitSettings) 6 | 7 | FPostInitPropertiesDelegate UProjectVersionGitSettings::OnPostInitPropertiesCompleted; 8 | 9 | #if WITH_EDITOR 10 | FPostEditChangePropertyDelegate UProjectVersionGitSettings::OnPostEditChangePropertyCompleted; 11 | #endif 12 | 13 | UProjectVersionGitSettings::UProjectVersionGitSettings(const FObjectInitializer& ObjectInitializer): 14 | Super(ObjectInitializer) 15 | { 16 | /* 17 | * Check more info about git path: 18 | * Engine/Plugins/Developer/GitSourceControl/Source/GitSourceControl/Private/GitSourceControlUtils.cpp#L170 19 | * FString FindGitBinaryPath() 20 | * Open terminal 21 | * $ whereis git 22 | * $ which -a git 23 | */ 24 | 25 | #if PLATFORM_WINDOWS 26 | GitBinPath = "git.exe"; 27 | #else 28 | GitBinPath = "/usr/bin/git"; 29 | #endif 30 | } 31 | 32 | void UProjectVersionGitSettings::PostInitProperties() 33 | { 34 | Super::PostInitProperties(); 35 | 36 | #if WITH_EDITOR 37 | static const FString ConfigIniName = TEXT("DefaultProjectVersionGitSettings.ini"); 38 | static const FString ConfigIniPath = FConfigCacheIni::NormalizeConfigIniPath(FString::Printf(TEXT("%s%s"), *FPaths::SourceConfigDir(), *ConfigIniName)); 39 | static const FString SectionName = TEXT("/Script/ProjectVersionFromGit.ProjectVersionGitSettings"); 40 | 41 | if (!FPaths::FileExists(ConfigIniPath)) 42 | { 43 | FConfigFile ConfigFile; 44 | GConfig->SetFile(ConfigIniPath, &ConfigFile); 45 | 46 | GConfig->SetString( 47 | *SectionName, 48 | TEXT("GitBinPath"), 49 | *GitBinPath, 50 | ConfigIniPath 51 | ); 52 | 53 | GConfig->Flush(false, ConfigIniPath); 54 | 55 | UE_LOG(LogProjectVersionGitSettings, Log, TEXT("---> Created Config: %s, Path: %s"), *ConfigIniName, *ConfigIniPath); 56 | } 57 | else 58 | { 59 | GConfig->GetString( 60 | *SectionName, 61 | TEXT("GitBinPath"), 62 | GitBinPath, 63 | ConfigIniPath 64 | ); 65 | } 66 | #endif // WITH_EDITOR 67 | 68 | UE_LOG(LogProjectVersionGitSettings, Log, TEXT("---> PostInitProperties, GitBinPath: %s"), *GitBinPath); 69 | 70 | OnPostInitPropertiesCompleted.Broadcast(); 71 | } 72 | 73 | #if WITH_EDITOR 74 | void UProjectVersionGitSettings::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) 75 | { 76 | Super::PostEditChangeProperty(PropertyChangedEvent); 77 | 78 | UE_LOG(LogProjectVersionGitSettings, Log, TEXT("---> PostEditChangeProperty, GitBinPath: %s"), *GitBinPath); 79 | 80 | OnPostEditChangePropertyCompleted.Broadcast(); 81 | } 82 | #endif // WITH_EDITOR 83 | -------------------------------------------------------------------------------- /Source/ProjectVersionFromGit/Private/ProjectVersionFromGitBPLibrary.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Andrew Bindraw. All Rights Reserved. 2 | 3 | #include "ProjectVersionFromGitBPLibrary.h" 4 | 5 | FText UProjectVersionFromGitBPLibrary::ProjectVersion = FText::GetEmpty(); 6 | FText UProjectVersionFromGitBPLibrary::ProjectVersionFormatAll = FText::GetEmpty(); 7 | FText UProjectVersionFromGitBPLibrary::BranchName = FText::GetEmpty(); 8 | FText UProjectVersionFromGitBPLibrary::CommitHash = FText::GetEmpty(); 9 | FText UProjectVersionFromGitBPLibrary::DateTimeBuild = FText::GetEmpty(); 10 | 11 | int32 UProjectVersionFromGitBPLibrary::Major = 0; 12 | int32 UProjectVersionFromGitBPLibrary::Minor = 0; 13 | int32 UProjectVersionFromGitBPLibrary::Patch = 0; 14 | 15 | FString UProjectVersionFromGitBPLibrary::SectionName = FString(TEXT("VersionInfo")); 16 | FString UProjectVersionFromGitBPLibrary::VersionFileIni = FString(TEXT("Version.ini")); 17 | 18 | FString UProjectVersionFromGitBPLibrary::GitStdOutput = FString(TEXT("")); 19 | 20 | DEFINE_LOG_CATEGORY(LogProjectVersionFromGitBPLibrary) 21 | 22 | UProjectVersionFromGitBPLibrary::UProjectVersionFromGitBPLibrary(const FObjectInitializer& ObjectInitializer) 23 | : Super(ObjectInitializer) 24 | { 25 | 26 | } 27 | 28 | void UProjectVersionFromGitBPLibrary::PostInitProperties() 29 | { 30 | Super::PostInitProperties(); 31 | 32 | UProjectVersionGitSettings::OnPostInitPropertiesCompleted.AddLambda([]() 33 | { 34 | GetProjectVersionInfo(FParseVersionDelegate()); 35 | }); 36 | 37 | #if WITH_EDITOR 38 | UProjectVersionGitSettings::OnPostEditChangePropertyCompleted.AddLambda([]() 39 | { 40 | GetProjectVersionInfo(FParseVersionDelegate()); 41 | }); 42 | #endif 43 | } 44 | 45 | bool UProjectVersionFromGitBPLibrary::ExecProcess(const TCHAR* URL, const TCHAR* Params, int32* OutReturnCode, FString* OutStdOut, FString* OutStdErr, const TCHAR* OptionalWorkingDirectory) 46 | { 47 | if (!GEngine->IsEditor()) 48 | { 49 | return false; 50 | } 51 | 52 | #if (ENGINE_MAJOR_VERSION > 4 || ENGINE_MINOR_VERSION >= 23) 53 | return FPlatformProcess::ExecProcess(URL, Params, OutReturnCode, OutStdOut, OutStdErr, OptionalWorkingDirectory); 54 | #else 55 | const FString command = FString(URL) + FString(TEXT(" -C ")) + FString(OptionalWorkingDirectory); 56 | return FPlatformProcess::ExecProcess(*command, Params, OutReturnCode, OutStdOut, OutStdErr); 57 | #endif 58 | } 59 | 60 | void UProjectVersionFromGitBPLibrary::GetProjectVersionInfo(FParseVersionDelegate OnCompleted) 61 | { 62 | AsyncTask(ENamedThreads::AnyHiPriThreadNormalTask, [OnCompleted]() 63 | { 64 | static const FString VersionFileIniPath = FConfigCacheIni::NormalizeConfigIniPath(FString::Printf(TEXT("%s%s"), *FPaths::SourceConfigDir(), *VersionFileIni)); 65 | 66 | if (GEngine->IsEditor()) 67 | { 68 | const auto Cfg = GetMutableDefault(); 69 | 70 | FString OutStdOut; 71 | FString OutStdErr; 72 | int32 OutReturnCode; 73 | static const FString OptionalWorkingDirectory = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir()); 74 | 75 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- Cfg->GitBinPath: %s"), *Cfg->GitBinPath); 76 | 77 | ExecProcess(*Cfg->GitBinPath, TEXT("describe --tags --abbrev=0"), &OutReturnCode, &OutStdOut, &OutStdErr, *OptionalWorkingDirectory); 78 | OutStdOut.TrimStartAndEndInline(); 79 | //UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- Git tag: %s"), *OutStdOut); 80 | 81 | const FRegexPattern myPattern(TEXT("([0-9]+\\.[0-9]+\\.[0-9]+)+")); 82 | FRegexMatcher myMatcher(myPattern, OutStdOut); 83 | 84 | if (myMatcher.FindNext()) 85 | { 86 | int32 beginPos = myMatcher.GetMatchBeginning(); 87 | int32 endPos = myMatcher.GetMatchEnding(); 88 | //UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("Regex git tag pos: %i %i"), beginPos, endPos); 89 | OutStdOut = OutStdOut.Mid(beginPos, endPos - beginPos); 90 | } 91 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- Git tag: %s"), *OutStdOut); 92 | 93 | if (OutStdOut.IsEmpty()) 94 | { 95 | ProjectVersion = FText::FromString(TEXT("0.0.0")); 96 | Major = Minor = Patch = 0; 97 | } 98 | else 99 | { 100 | OutStdOut.TrimStartAndEndInline(); 101 | TArray OutArrayParse; 102 | OutStdOut.ParseIntoArrayWS(OutArrayParse, TEXT(".")); 103 | 104 | if (OutArrayParse.Num() == 3) 105 | { 106 | FDefaultValueHelper::ParseInt(OutArrayParse[0], Major); 107 | FDefaultValueHelper::ParseInt(OutArrayParse[1], Minor); 108 | FDefaultValueHelper::ParseInt(OutArrayParse[2], Patch); 109 | 110 | ProjectVersion = FText::FromString(OutStdOut); 111 | } 112 | else 113 | { 114 | ProjectVersion = FText::FromString(TEXT("0.0.0")); 115 | Major = Minor = Patch = 0; 116 | } 117 | } 118 | OutStdOut = FString(TEXT("")); 119 | 120 | 121 | // Get BranchName 122 | ExecProcess(*Cfg->GitBinPath, TEXT("symbolic-ref --short HEAD"), &OutReturnCode, &OutStdOut, &OutStdErr, *OptionalWorkingDirectory); 123 | OutStdOut.TrimStartAndEndInline(); 124 | if (OutStdOut.IsEmpty()) 125 | { 126 | BranchName = FText::FromString(TEXT("unknown")); 127 | } 128 | else 129 | { 130 | BranchName = FText::FromString(OutStdOut); 131 | } 132 | OutStdOut = FString(TEXT("")); 133 | 134 | // Get CommitHash 135 | ExecProcess(*Cfg->GitBinPath, TEXT("status --short"), &OutReturnCode, &OutStdOut, &OutStdErr, *OptionalWorkingDirectory); 136 | OutStdOut.TrimStartAndEndInline(); 137 | GitStdOutput = OutStdOut; 138 | OutStdOut.Reset(); 139 | 140 | ExecProcess(*Cfg->GitBinPath, TEXT("describe --always --abbrev=8"), &OutReturnCode, &OutStdOut, &OutStdErr, *OptionalWorkingDirectory); 141 | OutStdOut.TrimStartAndEndInline(); 142 | 143 | if (GitStdOutput.IsEmpty()) 144 | { 145 | CommitHash = FText::FromString(OutStdOut); 146 | } 147 | else 148 | { 149 | CommitHash = FText::FromString(FString(TEXT("unclean-")) + OutStdOut); 150 | } 151 | OutStdOut = FString(TEXT("")); 152 | 153 | 154 | DateTimeBuild = FText::FromString(FDateTime::UtcNow().ToString() + TEXT("-UTC")); 155 | 156 | ProjectVersionFormatAll = FText::Format(FText::FromString(TEXT("{0}-{1}-{2}-{3}")), ProjectVersion, BranchName, CommitHash, DateTimeBuild); 157 | 158 | if (!GitStdOutput.IsEmpty()) 159 | { 160 | UE_LOG(LogProjectVersionFromGitBPLibrary, Warning, TEXT("-------- Git status --short: %s"), *GitStdOutput); 161 | } 162 | 163 | FConfigFile ConfigFile; 164 | GConfig->SetFile(VersionFileIniPath, &ConfigFile); 165 | 166 | GConfig->SetText( 167 | *SectionName, 168 | TEXT("ProjectVersion"), 169 | ProjectVersion, 170 | VersionFileIniPath 171 | ); 172 | 173 | GConfig->SetInt( 174 | *SectionName, 175 | TEXT("Major"), 176 | Major, 177 | VersionFileIniPath 178 | ); 179 | 180 | GConfig->SetInt( 181 | *SectionName, 182 | TEXT("Minor"), 183 | Minor, 184 | VersionFileIniPath 185 | ); 186 | 187 | GConfig->SetInt( 188 | *SectionName, 189 | TEXT("Patch"), 190 | Patch, 191 | VersionFileIniPath 192 | ); 193 | 194 | GConfig->SetText( 195 | *SectionName, 196 | TEXT("BranchName"), 197 | BranchName, 198 | VersionFileIniPath 199 | ); 200 | 201 | GConfig->SetText( 202 | *SectionName, 203 | TEXT("CommitHash"), 204 | CommitHash, 205 | VersionFileIniPath 206 | ); 207 | 208 | GConfig->SetText( 209 | *SectionName, 210 | TEXT("DateTimeBuild"), 211 | DateTimeBuild, 212 | VersionFileIniPath 213 | ); 214 | 215 | GConfig->SetText( 216 | *SectionName, 217 | TEXT("ProjectVersionFormatAll"), 218 | ProjectVersionFormatAll, 219 | VersionFileIniPath 220 | ); 221 | 222 | GConfig->Flush(false, VersionFileIniPath); 223 | } 224 | else 225 | { 226 | GConfig->GetText( 227 | *SectionName, 228 | TEXT("ProjectVersion"), 229 | ProjectVersion, 230 | VersionFileIniPath 231 | ); 232 | 233 | GConfig->GetInt( 234 | *SectionName, 235 | TEXT("Major"), 236 | Major, 237 | VersionFileIniPath 238 | ); 239 | 240 | GConfig->GetInt( 241 | *SectionName, 242 | TEXT("Minor"), 243 | Minor, 244 | VersionFileIniPath 245 | ); 246 | 247 | GConfig->GetInt( 248 | *SectionName, 249 | TEXT("Patch"), 250 | Patch, 251 | VersionFileIniPath 252 | ); 253 | 254 | GConfig->GetText( 255 | *SectionName, 256 | TEXT("BranchName"), 257 | BranchName, 258 | VersionFileIniPath 259 | ); 260 | 261 | GConfig->GetText( 262 | *SectionName, 263 | TEXT("CommitHash"), 264 | CommitHash, 265 | VersionFileIniPath 266 | ); 267 | 268 | GConfig->GetText( 269 | *SectionName, 270 | TEXT("DateTimeBuild"), 271 | DateTimeBuild, 272 | VersionFileIniPath 273 | ); 274 | 275 | GConfig->GetText( 276 | *SectionName, 277 | TEXT("ProjectVersionFormatAll"), 278 | ProjectVersionFormatAll, 279 | VersionFileIniPath 280 | ); 281 | } 282 | 283 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- ProjectVersion: %s"), *ProjectVersion.ToString()); 284 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- Major: %d"), Major); 285 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- Minor: %d"), Minor); 286 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- Patch: %d"), Patch); 287 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- BranchName: %s"), *BranchName.ToString()); 288 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- CommitHash: %s"), *CommitHash.ToString()); 289 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- DateTimeBuild: %s"), *DateTimeBuild.ToString()); 290 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- ProjectVersionFormatAll: %s"), *ProjectVersionFormatAll.ToString()); 291 | UE_LOG(LogProjectVersionFromGitBPLibrary, Log, TEXT("-------- VersionFileIniPath: %s"), *VersionFileIniPath); 292 | 293 | AsyncTask(ENamedThreads::GameThread, [OnCompleted]() 294 | { 295 | OnCompleted.ExecuteIfBound(); 296 | }); 297 | }); 298 | } 299 | 300 | FText UProjectVersionFromGitBPLibrary::GetProjectVersion() 301 | { 302 | return ProjectVersion; 303 | } 304 | 305 | FText UProjectVersionFromGitBPLibrary::GetProjectVersionBranchName() 306 | { 307 | return BranchName; 308 | } 309 | 310 | FText UProjectVersionFromGitBPLibrary::GetProjectVersionCommitHash() 311 | { 312 | return CommitHash; 313 | } 314 | 315 | int32 UProjectVersionFromGitBPLibrary::GetProjectVersionMajor() 316 | { 317 | return Major; 318 | } 319 | 320 | int32 UProjectVersionFromGitBPLibrary::GetProjectVersionMinor() 321 | { 322 | return Minor; 323 | } 324 | 325 | int32 UProjectVersionFromGitBPLibrary::GetProjectVersionPatch() 326 | { 327 | return Patch; 328 | } 329 | 330 | FText UProjectVersionFromGitBPLibrary::GetProjectVersionDateTimeBuild() 331 | { 332 | return DateTimeBuild; 333 | } 334 | 335 | FText UProjectVersionFromGitBPLibrary::GetProjectVersionFormatAll() 336 | { 337 | return ProjectVersionFormatAll; 338 | } 339 | --------------------------------------------------------------------------------