using System; using UnityEngine; namespace UnityBuilderAction.Versioning { public static class Git { const string application = @"git"; /// /// Generate a version based on the latest tag and the amount of commits. /// Format: 0.1.2 (where 2 is the amount of commits). /// /// If no tag is present in the repository then v0.0 is assumed. /// This would result in 0.0.# where # is the amount of commits. /// public static string GenerateSemanticCommitVersion() { string version; if (HasAnyVersionTags()) { version = GetSemanticCommitVersion(); Console.WriteLine("Repository has a valid version tag."); } else { version = $"0.0.{GetTotalNumberOfCommits()}"; Console.WriteLine("Repository does not have tags to base the version on."); } Console.WriteLine($"Version is {version}"); return version; } /// /// Get the version of the current tag. /// /// The tag must point at HEAD for this method to work. /// /// Output Format: /// #.* (where # is the major version and * can be any number of any type of character) /// public static string GetTagVersion() { string version = Run(@"tag --points-at HEAD | grep v[0-9]*"); version = version.Substring(1); return version; } /// /// Get the total number of commits. /// static int GetTotalNumberOfCommits() { string numberOfCommitsAsString = Run(@"git rev-list --count HEAD"); return int.Parse(numberOfCommitsAsString); } /// /// Whether or not the repository has any version tags yet. /// static bool HasAnyVersionTags() { return "0" != Run(@"tag --list --merged HEAD | grep v[0-9]* | wc -l"); } /// /// Retrieves the build version from git based on the most recent matching tag and /// commit history. This returns the version as: {major.minor.build} where 'build' /// represents the nth commit after the tagged commit. /// Note: The initial 'v' and the commit hash are removed. /// static string GetSemanticCommitVersion() { // v0.1-2-g12345678 (where 2 is the amount of commits, g stands for git) string version = GetVersionString(); // 0.1-2 version = version.Substring(1, version.LastIndexOf('-') - 1); // 0.1.2 version = version.Replace('-', '.'); return version; } /// /// Get version string. /// /// Format: `v0.1-2-g12345678` (where 2 is the amount of commits since the last tag) /// /// See: https://softwareengineering.stackexchange.com/questions/141973/how-do-you-achieve-a-numeric-versioning-scheme-with-git /// static string GetVersionString() { return Run(@"describe --tags --long --match ""v[0-9]*"""); // Todo - implement split function based on this more complete query // return Run(@"describe --long --tags --dirty --always"); } /// /// Runs git binary with any given arguments and returns the output. /// static string Run(string arguments) { using (var process = new System.Diagnostics.Process()) { string workingDirectory = Application.dataPath; int exitCode = process.Run(application, arguments, workingDirectory, out string output, out string errors); if (exitCode != 0) { throw new GitException(exitCode, errors); } return output; } } } }