diff --git a/rename-ue-project/Program.cs b/rename-ue-project/Program.cs new file mode 100644 index 0000000..c11a8fe --- /dev/null +++ b/rename-ue-project/Program.cs @@ -0,0 +1,91 @@ +using System.Text.RegularExpressions; + +namespace rename_ue_project +{ + internal class Program + { + const string OLD_PROJECT_NAME = "MotionMatching"; + const string UE_PROJECT_EXTENSION = ".uproject"; + const string GITIGNORE = ".gitignore"; + const string README = "READ.ME"; + const string CONFIG_FOLDER = "config"; + const string DEGAULT_GAME_INI = "DefaultGame.ini"; + + // todo: test this!! + /// + /// Replaces folder and ue project file with new project name. Also replaces occurrences in .gitignore and projectName in DefaultGame.ini + /// + /// + /// 0: absolute path to unreal project root + /// 1: new project name, must be no longer than 20 chars and [a-zA-Z0-9-_] + /// 2: long description for your game, can be markdown is used for READ.ME + /// + /// + /// if a file was not where expected + /// if an app parameter was invalid + static async Task Main(string[] args) + { + var projectPath = args[0]; + var projectName = args[1]; + var descLong = args[2]; + + + if (!Directory.Exists(projectPath)) + { + throw new IOException($"Directory {projectPath} does not exist"); + } + + // step 0: validate ue project name + var rgxName = "'^[a-zA-Z0-9_-]+$"; + Match m = Regex.Match(projectName, rgxName, RegexOptions.IgnoreCase); + if (m.Success) + { + throw new ArgumentException("Unreal project names can not be longer than 20 chars and must not contain special chars, except - and _"); + } + + // step 1: rename directory + if (!Directory.Exists(OLD_PROJECT_NAME)) + { + throw new IOException($"Directory {OLD_PROJECT_NAME} does not exist"); + } + + Directory.Move( + Path.Combine(projectPath, OLD_PROJECT_NAME), + Path.Combine(projectPath, projectName) + ); + Console.WriteLine("Renamed project directory"); + + // step 2: rename project file + File.Move( + Path.Combine(projectPath, projectName, $"{OLD_PROJECT_NAME}{UE_PROJECT_EXTENSION}"), + Path.Combine(projectPath, projectName, $"{projectName}{UE_PROJECT_EXTENSION}") + ); + + // step 3: replace everything in gitignore + var ignoreContent = await File.ReadAllTextAsync(Path.Combine(projectPath, GITIGNORE)); + ignoreContent = ignoreContent.Replace(OLD_PROJECT_NAME, projectName); + Console.WriteLine("Replaced project name in gitignore"); + + // step 4: write read.me in format # projectName + new line + descrLong + var readMe = @$"# {projectName}{Environment.NewLine}{descLong}"; + await File.WriteAllTextAsync(Path.Combine(projectPath, README), readMe); + Console.WriteLine("Wrote READ.ME"); + + // step 5: replace name in DefaultGame.ini + var configPath = Path.Combine(projectPath, projectName, CONFIG_FOLDER, DEGAULT_GAME_INI); + if (!File.Exists(configPath)) + { + throw new IOException($"Unreal config {DEGAULT_GAME_INI} not found at {configPath} - can not replace project name"); + } + + var defaultGameIni = await File.ReadAllTextAsync(configPath); + var rgxPrjName = @"(?<=ProjectName=)[^\s]+"; + + // Perform the replacement + defaultGameIni = Regex.Replace(defaultGameIni, rgxPrjName, projectName); + await File.WriteAllTextAsync(configPath, defaultGameIni); + Console.WriteLine($"Replaced project name in {DEGAULT_GAME_INI}"); + + } + } +} diff --git a/rename-ue-project/rename-ue-project.csproj b/rename-ue-project/rename-ue-project.csproj new file mode 100644 index 0000000..c14f5be --- /dev/null +++ b/rename-ue-project/rename-ue-project.csproj @@ -0,0 +1,11 @@ + + + + Exe + net8.0 + rename_ue_project + enable + enable + + + diff --git a/rename-ue-project/rename-ue-project.sln b/rename-ue-project/rename-ue-project.sln new file mode 100644 index 0000000..a6f6b52 --- /dev/null +++ b/rename-ue-project/rename-ue-project.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35013.160 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rename-ue-project", "rename-ue-project.csproj", "{A8D865C3-BFF0-4276-8260-EC60FC6493F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A8D865C3-BFF0-4276-8260-EC60FC6493F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8D865C3-BFF0-4276-8260-EC60FC6493F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8D865C3-BFF0-4276-8260-EC60FC6493F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8D865C3-BFF0-4276-8260-EC60FC6493F9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EF1712C3-E679-4CE7-9977-5B49871CA26D} + EndGlobalSection +EndGlobal