├── .gitignore ├── CHANGELOG.md ├── CHANGELOG.md.meta ├── Documentation~ ├── menu.png ├── prefs.png ├── settings.png └── warning.png ├── Editor.meta ├── Editor ├── EditorGitTool.cs ├── EditorGitTool.cs.meta ├── EditorGitToolSettings.cs ├── EditorGitToolSettings.cs.meta ├── kamgam.UnityEditorGitTool.Editor.asmdef └── kamgam.UnityEditorGitTool.Editor.asmdef.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── package.json └── package.json.meta /.gitignore: -------------------------------------------------------------------------------- 1 | /Editor/GitToolSettings.asset 2 | /Editor/GitToolSettings.asset.meta 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # UnityEditorGitTool Changelog 2 | 3 | TODO: Keep a changelog[1]. 4 | 5 | [1]: https://keepachangelog.com/en/1.0.0/ 6 | -------------------------------------------------------------------------------- /CHANGELOG.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a994d0e3409e4da784053635261dbed1 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Documentation~/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamgam/UnityEditorGitTool/38968313901ee7f4a42111509c0a47e07c108f07/Documentation~/menu.png -------------------------------------------------------------------------------- /Documentation~/prefs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamgam/UnityEditorGitTool/38968313901ee7f4a42111509c0a47e07c108f07/Documentation~/prefs.png -------------------------------------------------------------------------------- /Documentation~/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamgam/UnityEditorGitTool/38968313901ee7f4a42111509c0a47e07c108f07/Documentation~/settings.png -------------------------------------------------------------------------------- /Documentation~/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kamgam/UnityEditorGitTool/38968313901ee7f4a42111509c0a47e07c108f07/Documentation~/warning.png -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a44bf68466724016bb9ba649fe2d0b68 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/EditorGitTool.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | using UnityEditor.Build; 5 | using UnityEditor.Build.Reporting; 6 | using UnityEngine; 7 | 8 | namespace kamgam.editor.GitTool 9 | { 10 | /// 11 | /// Saves the git hash into a text asset. 12 | /// 13 | public static class EditorGitTool 14 | { 15 | public const string DefaultGitHashFilePath = "Assets/Resources/GitHash.asset"; 16 | 17 | #if !UNITY_2018_4_OR_NEWER 18 | private static bool prefsLoaded = false; 19 | public static string GitHashFilePath = DefaultGitHashFilePath; 20 | public static bool ShowWarning = true; 21 | 22 | [PreferenceItem("Git Tool")] 23 | private static void CustomPreferencesGUI() 24 | { 25 | if (!prefsLoaded) 26 | { 27 | GitHashFilePath = EditorPrefs.GetString("kamgam.EditorGitTools.DefaultGitHashFilePath", GitHashFilePath); 28 | ShowWarning = EditorPrefs.GetBool("kamgam.EditorGitTools.ShowWarning", ShowWarning); 29 | prefsLoaded = true; 30 | } 31 | 32 | GitHashFilePath = EditorGUILayout.TextField(GitHashFilePath); 33 | ShowWarning = EditorGUILayout.Toggle("Show Warning: ", ShowWarning); 34 | 35 | if (GUI.changed) 36 | { 37 | EditorPrefs.SetString("kamgam.EditorGitTools.DefaultGitHashFilePath", GitHashFilePath); 38 | EditorPrefs.SetBool("kamgam.EditorGitTools.ShowWarning", ShowWarning); 39 | } 40 | } 41 | #endif 42 | 43 | /// 44 | /// Update the hash from the menu. 45 | /// 46 | [MenuItem("Tools/Git/SaveHash")] 47 | public static void SaveHashFromMenu() 48 | { 49 | SaveHash(); 50 | } 51 | 52 | /// 53 | /// Fetch the hash from git, add postFix to it and then save it in gitHashFilePath. 54 | /// 55 | /// Text to be appended to the hash. 56 | /// Git hashfile path, will use the path set the settings if not specified. Example: "Assets/Resources/GitHash.asset" 57 | public static void SaveHash(string postFix = "", string gitHashFilePath = null) 58 | { 59 | if(string.IsNullOrEmpty(gitHashFilePath)) 60 | { 61 | #if UNITY_2018_4_OR_NEWER 62 | gitHashFilePath = EditorGitToolSettings.GetOrCreateSettings().GitHashTextAssetPath; 63 | #else 64 | gitHashFilePath = GitHashFilePath; 65 | #endif 66 | } 67 | 68 | Debug.Log("GitTools: PreExport() - writing git hash into '" + gitHashFilePath + "'"); 69 | 70 | string gitHash = ExecAndReadFirstLine("git rev-parse --short HEAD"); 71 | if (gitHash == null) 72 | { 73 | Debug.LogError("GitTools: not git hash found!"); 74 | gitHash = "unknown"; 75 | } 76 | 77 | Debug.Log("GitTools: git hash is '" + gitHash + "'"); 78 | 79 | AssetDatabase.DeleteAsset(gitHashFilePath); 80 | var text = new TextAsset(gitHash + postFix); 81 | // Check if a folder needs to be created 82 | if (!AssetDatabase.IsValidFolder("Assets/Resources")) 83 | AssetDatabase.CreateFolder("Assets", "Resources"); 84 | AssetDatabase.CreateAsset(text, gitHashFilePath); 85 | AssetDatabase.SaveAssets(); 86 | AssetDatabase.Refresh(); 87 | } 88 | 89 | /// 90 | /// Counts modified, new or simply unknown files in working tree. 91 | /// 92 | /// 93 | public static int CountChanges() 94 | { 95 | Debug.Log("GitTools: CountChanges() - counts modified, new or simply unknown files in working tree."); 96 | 97 | string statusResult = Exec("git status --porcelain"); 98 | if (statusResult == null) 99 | { 100 | return 0; 101 | } 102 | 103 | return countLines(statusResult); 104 | } 105 | 106 | private static int countLines(string str) 107 | { 108 | if (str == null) 109 | throw new ArgumentNullException("str"); 110 | if (str == string.Empty) 111 | return 0; 112 | int index = -1; 113 | int count = 0; 114 | while ( (index = str.IndexOf(Environment.NewLine, index + 1)) != -1 ) 115 | { 116 | count++; 117 | } 118 | 119 | return count + 1; 120 | } 121 | 122 | public static string ExecAndReadFirstLine(string command, int maxWaitTimeInSec = 5) 123 | { 124 | string result = Exec(command, maxWaitTimeInSec); 125 | 126 | // first line only 127 | if (result != null) 128 | { 129 | int i = result.IndexOf("\n"); 130 | if (i > 0) 131 | { 132 | result = result.Substring(0, i); 133 | } 134 | } 135 | 136 | return result; 137 | } 138 | 139 | public static string Exec(string command, int maxWaitTimeInSec = 5) 140 | { 141 | try 142 | { 143 | #if UNITY_EDITOR_WIN 144 | string shellCmd = "cmd.exe"; 145 | string shellCmdArg = "/c"; 146 | #elif UNITY_EDITOR_OSX || UNITY_EDITOR_LINUX 147 | string shellCmd = "bash"; 148 | string shellCmdArg = "-c"; 149 | #else 150 | string shellCmd = ""; 151 | string shellCmdArg = ""; 152 | #endif 153 | 154 | string cmdArguments = shellCmdArg + " \"" + command + "\""; 155 | Debug.Log("GitTool.Exec: Attempting to execute command: " + (shellCmd + " " + cmdArguments)); 156 | var procStartInfo = new System.Diagnostics.ProcessStartInfo(shellCmd, cmdArguments); 157 | procStartInfo.RedirectStandardOutput = true; 158 | procStartInfo.UseShellExecute = false; 159 | procStartInfo.CreateNoWindow = true; 160 | 161 | // Debug.Log("GitTool.Exec: Running process..."); 162 | System.Diagnostics.Process proc = new System.Diagnostics.Process(); 163 | proc.StartInfo = procStartInfo; 164 | proc.Start(); 165 | string result = proc.StandardOutput.ReadToEnd(); 166 | proc.WaitForExit(maxWaitTimeInSec * 1000); 167 | 168 | Debug.Log("GitTool.Exec: done"); 169 | return result; 170 | } 171 | catch (System.Exception e) 172 | { 173 | Debug.Log("GitTool.Exec Error: " + e); 174 | return null; 175 | } 176 | } 177 | } 178 | 179 | /// 180 | /// Hooks up to the BuildProcess and calls Git. 181 | /// 182 | class GitBuildProcessor : IPreprocessBuildWithReport 183 | { 184 | public int callbackOrder { get { return 0; } } 185 | 186 | public void OnPreprocessBuild(BuildReport report) 187 | { 188 | // show warning 189 | #if UNITY_2018_4_OR_NEWER 190 | bool showWarning = EditorGitToolSettings.GetOrCreateSettings().ShowWarning; 191 | #else 192 | bool showWarning = EditorGitTool.ShowWarning; 193 | #endif 194 | 195 | bool commitsPending = false; 196 | if(EditorGitTool.CountChanges() > 0 && showWarning) 197 | { 198 | commitsPending = true; 199 | var continueWithoutCommit = EditorUtility.DisplayDialog( 200 | "GIT: Commit your changes!", 201 | "There are still uncommitted changes.\nDo you want to proceed with the build?", 202 | "Build Anyway", "Cancel Build" 203 | ); 204 | if (continueWithoutCommit == false) 205 | { 206 | // In Unity 2018.4+ throwing a normal "Exception" in OnPreprocessBuild() will no longer stop the build, but throwing a "BuildFailedException" will. 207 | throw new BuildFailedException("User canceled build because there are still uncommitted changes."); 208 | } 209 | } 210 | 211 | // Export git hash to text asset for runtime use. 212 | // Add a "+" to the hash to indicate that this was built without commiting pending changes. 213 | EditorGitTool.SaveHash(commitsPending ? "+" : ""); 214 | } 215 | } 216 | } 217 | #endif 218 | -------------------------------------------------------------------------------- /Editor/EditorGitTool.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27ca2c98ded346348b1fd8df1454edbd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/EditorGitToolSettings.cs: -------------------------------------------------------------------------------- 1 | #if UNITY_EDITOR 2 | using System; 3 | using UnityEditor; 4 | using UnityEditor.Build; 5 | using UnityEditor.Build.Reporting; 6 | using UnityEngine; 7 | 8 | namespace kamgam.editor.GitTool 9 | { 10 | #if UNITY_2018_4_OR_NEWER 11 | // Create a new type of Settings Asset. 12 | class EditorGitToolSettings : ScriptableObject 13 | { 14 | public const string SettingsFilePath = "Assets/Editor/EditorGitToolSettings.asset"; 15 | 16 | [SerializeField] 17 | public string GitHashTextAssetPath; 18 | 19 | [SerializeField] 20 | public bool ShowWarning; 21 | 22 | private static EditorGitToolSettings settings = null; 23 | 24 | internal static EditorGitToolSettings GetOrCreateSettings() 25 | { 26 | if (settings != null) 27 | return settings; 28 | 29 | settings = AssetDatabase.LoadAssetAtPath(SettingsFilePath); 30 | if (settings == null) 31 | { 32 | settings = ScriptableObject.CreateInstance(); 33 | settings.GitHashTextAssetPath = EditorGitTool.DefaultGitHashFilePath; 34 | settings.ShowWarning = true; 35 | // Check if a folder needs to be created 36 | if (!AssetDatabase.IsValidFolder("Assets/Editor")) 37 | AssetDatabase.CreateFolder("Assets", "Editor"); 38 | AssetDatabase.CreateAsset(settings, SettingsFilePath); 39 | AssetDatabase.SaveAssets(); 40 | } 41 | return settings; 42 | } 43 | 44 | internal static SerializedObject GetSerializedSettings() 45 | { 46 | return new SerializedObject(GetOrCreateSettings()); 47 | } 48 | } 49 | 50 | // Register a SettingsProvider using IMGUI for the drawing framework: 51 | static class GitToolSettingsProvider 52 | { 53 | [SettingsProvider] 54 | public static SettingsProvider CreateGitToolSettingsProvider() 55 | { 56 | var provider = new SettingsProvider("Project/GitTool", SettingsScope.Project) 57 | { 58 | label = "Git Tool", 59 | guiHandler = (searchContext) => 60 | { 61 | var settings = EditorGitToolSettings.GetSerializedSettings(); 62 | settings.Update(); 63 | 64 | // Fix for default toggle not being clickable in some Unity versions (TODO: investigate). 65 | var showWarningProp = settings.FindProperty("ShowWarning"); 66 | showWarningProp.boolValue = EditorGUILayout.ToggleLeft("Show warning", showWarningProp.boolValue); 67 | 68 | EditorGUILayout.HelpBox("Should a warning be shown before building if there are uncommitted changes?", MessageType.None); 69 | EditorGUILayout.PropertyField(settings.FindProperty("GitHashTextAssetPath"), new GUIContent("Hash file path:")); 70 | EditorGUILayout.HelpBox("Defines the path where the hash is stored as a text asset file.\n"+ 71 | "If you want to load this at runtime then store it in Resources, example: 'Assets/Resources/GitHash.asset'.\n"+ 72 | "\nLoad with :\n" + 73 | " var gitHash = UnityEngine.Resources.Load(\"GitHash\"); \n"+ 74 | " if (gitHash != null)\n"+ 75 | " {\n"+ 76 | " string versionHash = gitHash.text;\n"+ 77 | " }\n", MessageType.None); 78 | settings.ApplyModifiedProperties(); 79 | }, 80 | 81 | // Populate the search keywords to enable smart search filtering and label highlighting. 82 | keywords = new System.Collections.Generic.HashSet(new[] { "git", "hash", "build" }) 83 | }; 84 | 85 | return provider; 86 | } 87 | } 88 | #endif 89 | } 90 | #endif 91 | -------------------------------------------------------------------------------- /Editor/EditorGitToolSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 531cb0f03120ea74c93a24348f5aa911 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/kamgam.UnityEditorGitTool.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kamgam.UnityEditorGitTool.Editor", 3 | "references": [ 4 | "kamgam.UnityEditorGitTool" 5 | ], 6 | "optionalUnityReferences": [], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [] 16 | } -------------------------------------------------------------------------------- /Editor/kamgam.UnityEditorGitTool.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a81c1cf987814eb1a93c69ec333d6335 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 KAMGAM 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 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f3318ae2baf405e9181442cac795999 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityEditorGitTool README 2 | 3 | A tool which automatically saves the git hash into a text asset before build. Useful if you want to use the hash at runtime. For example to display it in addition to the current version of the game. 4 | 5 | ## Installation 6 | 7 | ### Requirements 8 | 9 | * You need to have git installed ("git" command in PATH). To test simply open your commandline, type in "git" and see what happens. 10 | * Your project must use git (obviously). 11 | * Unity 2017+ (may work with earlier versions too, have not tested it there) 12 | 13 | ``` 14 | $ git clone https://github.com/kamgam/UnityEditorGitTool.git 15 | ``` 16 | 17 | ### Usage 18 | 19 | Find the `manifest.json` file in the `Packages` directory in your project and edit it as follows: 20 | ``` 21 | { 22 | "dependencies": { 23 | "com.kamgam.editor.gittool": "https://github.com/kamgam/UnityEditorGitTool.git", 24 | ... 25 | }, 26 | } 27 | ``` 28 | To select a particular version of the package, add the suffix `#{git-tag}`. 29 | 30 | * e.g. `"com..": "https://github.com/kamgam/UnityEditorGitTool.git#1.2.0"` 31 | 32 | At build time it will try to fetch the current hash from git and save it in a text asset (default: "Assets/Resources/GitHash.asset"). 33 | 34 | It can show a warning before the build if there are uncommited changes (enabled by default). This can be disabled in the settings. 35 | 36 | ![Alt Warning Dialog](Documentation~/warning.png?raw=true "Warning dialog at build time.") 37 | 38 | You can also trigger saving the hash manually via Menu > Tools > Git > SaveHash 39 | 40 | ![Alt Menu](Documentation~/menu.png?raw=true "Save hash manually.") 41 | 42 | The location of the hash file and whether or not a warning should be displayed can be configured in the settings. If Unity is version 2018.4 or newer then these settings are stored in an asset ("Assets/Editor/GitToolSettings.asset"). 43 | 44 | ![Alt Settings 2018.4+](Documentation~/settings.png?raw=true "Settings") 45 | 46 | Older versions of Unity (pre 2018.4) use the EditorPrefs ("kamgam.EditorGitTools.*"). 47 | 48 | ![Alt Settings < 2018.4](Documentation~/prefs.png?raw=true "Settings") 49 | 50 | ### Use at runtime 51 | Here is an example of how to read the hash at runtime. Notice that the path depends on your settings. This example assumes you are using the default path "Assets/Resources/GitHash.asset". 52 | ```csharp 53 | public static string _versionHash = null; 54 | public static string GetVersionHash() 55 | { 56 | if (_versionHash == null) 57 | { 58 | _versionHash = "unknown"; 59 | var gitHash = UnityEngine.Resources.Load("GitHash"); 60 | if (gitHash != null) 61 | { 62 | _versionHash = gitHash.text; 63 | } 64 | } 65 | return _versionHash; 66 | } 67 | ``` 68 | 69 | ## Acknowledgements 70 | 71 | This package was originally generated from [Shane Celis](https://twitter.com/shanecelis)'s [unity-package-template](https://github.com/shanecelis/unity-package-template). 72 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd2209f460c54090abd385952748ff83 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.kamgam.editor.gittool", 3 | "version": "0.1.0", 4 | "displayName": "KAMGAM UnityEditorGitTool", 5 | "description": "Generate a text asset with git information at build.", 6 | "unity": "2018.3", 7 | "type": "library", 8 | "author": { 9 | "name": "KAMGAM", 10 | "email": "office@kamgam.com", 11 | "url": "https://kamgam.com" 12 | }, 13 | "dependencies": { }, 14 | "license": "MIT", 15 | "keywords": [ 16 | "unity", 17 | "git" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a05883218c794732a847e904768e9d35 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------