├── .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 | 
37 |
38 | You can also trigger saving the hash manually via Menu > Tools > Git > SaveHash
39 |
40 | 
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 | 
45 |
46 | Older versions of Unity (pre 2018.4) use the EditorPrefs ("kamgam.EditorGitTools.*").
47 |
48 | 
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 |
--------------------------------------------------------------------------------