Build.UpdateVersion can track the git revision now, in addition to svn and bzr.

This commit is contained in:
Andy Korth 2012-12-20 13:35:58 -06:00
parent 339ffa61db
commit 0847b2ca5c
2 changed files with 196 additions and 168 deletions

View file

@ -1,168 +1,191 @@
#region License #region License
// //
// The Open Toolkit Library License // The Open Toolkit Library License
// //
// Copyright (c) 2006 - 2010 the Open Toolkit library. // Copyright (c) 2006 - 2010 the Open Toolkit library.
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to // in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do // the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions: // so, subject to the following conditions:
// //
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// //
#endregion #endregion
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
namespace Build.UpdateVersion namespace Build.UpdateVersion
{ {
class Program class Program
{ {
const string Major = "1"; const string Major = "1";
const string Minor = "1"; const string Minor = "1";
static string RootDirectory; static string RootDirectory;
static string SourceDirectory; static string SourceDirectory;
public static void Main() public static void Main()
{ {
string wdir = Environment.CurrentDirectory; string wdir = Environment.CurrentDirectory;
if (Directory.GetParent(wdir).Name == "Source") if (Directory.GetParent(wdir).Name == "Source")
{ {
// Running through msbuild inside Source/Build.UpdateVersion/ // Running through msbuild inside Source/Build.UpdateVersion/
RootDirectory = "../.."; RootDirectory = "../..";
SourceDirectory = ".."; SourceDirectory = "..";
} }
else else
{ {
// Running manually inside Binaries/OpenTK/[Debug|Release]/ // Running manually inside Binaries/OpenTK/[Debug|Release]/
RootDirectory = "../../.."; RootDirectory = "../../..";
SourceDirectory = "../../../Source"; SourceDirectory = "../../../Source";
} }
DateTime now = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
GenerateVersionInfo(now, Path.Combine(RootDirectory, "Version.txt")); GenerateVersionInfo(now, Path.Combine(RootDirectory, "Version.txt"));
GenerateAssemblyInfo(now, Path.Combine(SourceDirectory, "GlobalAssemblyInfo.cs")); GenerateAssemblyInfo(now, Path.Combine(SourceDirectory, "GlobalAssemblyInfo.cs"));
} }
static void GenerateVersionInfo(DateTime now, string file) static void GenerateVersionInfo(DateTime now, string file)
{ {
string version = null; string version = null;
if (System.IO.File.Exists(file)) if (System.IO.File.Exists(file))
{ {
string[] lines = System.IO.File.ReadAllLines(file); string[] lines = System.IO.File.ReadAllLines(file);
if (lines.Length > 0 && !String.IsNullOrEmpty(lines[0])) if (lines.Length > 0 && !String.IsNullOrEmpty(lines[0]))
{ {
version = lines[0]; version = lines[0];
} }
} }
// If the file does not exist, create it. // If the file does not exist, create it.
if (version == null) if (version == null)
{ {
version = now.ToString("u").Split(' ')[0]; version = now.ToString("u").Split(' ')[0];
System.IO.File.WriteAllLines(file, new string[] { version }); System.IO.File.WriteAllLines(file, new string[] { version });
} }
} }
static void GenerateAssemblyInfo(DateTime now, string file) static void GenerateAssemblyInfo(DateTime now, string file)
{ {
// Build number is defined as the number of days since 1/1/2010. // Build number is defined as the number of days since 1/1/2010.
// Revision number is defined as the fraction of the current day, expressed in seconds. // Revision number is defined as the fraction of the current day, expressed in seconds.
double timespan = now.Subtract(new DateTime(2010, 1, 1)).TotalDays; double timespan = now.Subtract(new DateTime(2010, 1, 1)).TotalDays;
string build = ((int)timespan).ToString(); string build = ((int)timespan).ToString();
string revision = RetrieveSvnRevision() ?? RetrieveBzrRevision() ?? RetrieveSeconds(timespan); string revision = RetrieveGitRevision() ?? RetrieveSvnRevision() ?? RetrieveBzrRevision() ?? RetrieveSeconds(timespan);
revision = revision.Trim(); revision = revision.Trim();
File.WriteAllLines(file, new string[] Console.WriteLine("Build timestamp was: " + build);
{ Console.WriteLine("Revision detected was: " + revision);
"// This file is auto-generated through Source/Build.Tasks/GenerateAssemblyInfo.cs.",
"// Do not edit by hand!", File.WriteAllLines(file, new string[]
"", {
"using System;", "// This file is auto-generated through Source/Build.Tasks/GenerateAssemblyInfo.cs.",
"using System.Reflection;", "// Do not edit by hand!",
"using System.Resources;", "",
"using System.Runtime.CompilerServices;", "using System;",
"using System.Runtime.InteropServices;", "using System.Reflection;",
"", "using System.Resources;",
"[assembly: AssemblyCompany(\"The Open Toolkit Library\")]", "using System.Runtime.CompilerServices;",
"[assembly: AssemblyProduct(\"The Open Toolkit Library\")]", "using System.Runtime.InteropServices;",
"[assembly: AssemblyCopyright(\"Copyright © 2006 - 2010 the Open Toolkit Library\")]", "",
"[assembly: AssemblyTrademark(\"OpenTK\")]", "[assembly: AssemblyCompany(\"The Open Toolkit Library\")]",
String.Format("[assembly: AssemblyVersion(\"{0}.{1}.0.0\")]", Major, Minor), "[assembly: AssemblyProduct(\"The Open Toolkit Library\")]",
String.Format("[assembly: AssemblyFileVersion(\"{0}.{1}.{2}.{3}\")]", Major, Minor, build, revision), "[assembly: AssemblyCopyright(\"Copyright © 2006 - 2010 the Open Toolkit Library\")]",
}); "[assembly: AssemblyTrademark(\"OpenTK\")]",
} String.Format("[assembly: AssemblyVersion(\"{0}.{1}.0.0\")]", Major, Minor),
String.Format("[assembly: AssemblyFileVersion(\"{0}.{1}.{2}.{3}\")]", Major, Minor, build, revision),
static string RetrieveSeconds(double timespan) });
{ }
string revision = ((int)((timespan - (int)timespan) * UInt16.MaxValue)).ToString();
return revision; static string RetrieveSeconds(double timespan)
} {
string revision = ((int)((timespan - (int)timespan) * UInt16.MaxValue)).ToString();
static string RetrieveSvnRevision() return revision;
{ }
try
{ static string RetrieveGitRevision()
string output = RunProcess("svn", "info", RootDirectory); {
try
const string RevisionText = "Revision: "; {
int index = output.IndexOf(RevisionText); string output = RunProcess("git", "log -1", RootDirectory);
if (index > -1)
return output.Substring(index + RevisionText.Length, 5) const string RevisionText = "commit ";
.Replace('\r', ' ').Replace('\n', ' ').Trim(); int index = output.IndexOf(RevisionText);
} int endIndex = output.IndexOf("\n"); // since it's the first line...
catch (Exception e) if (index > -1)
{ return output.Substring(index + RevisionText.Length, endIndex - index - RevisionText.Length).Trim();
Debug.Print("Failed to retrieve svn revision. Error: {0}", e); }
} catch (Exception e)
return null; {
} Debug.Print("Failed to retrieve git revision. Error: {0}", e);
}
static string RetrieveBzrRevision() return null;
{ }
try
{
string output = RunProcess("bzr", "revno", RootDirectory); static string RetrieveSvnRevision()
return output != null && !output.StartsWith("bzr") ? output : null; {
} try
catch (Exception e) {
{ string output = RunProcess("svn", "info", RootDirectory);
Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
} const string RevisionText = "Revision: ";
return null; int index = output.IndexOf(RevisionText);
} if (index > -1)
return output.Substring(index + RevisionText.Length, 5)
static string RunProcess(string cmd, string args, string wdir) .Replace('\r', ' ').Replace('\n', ' ').Trim();
{ }
ProcessStartInfo info = new ProcessStartInfo(cmd, args); catch (Exception e)
info.WorkingDirectory = wdir; {
info.RedirectStandardOutput = true; Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
info.RedirectStandardError = true; }
info.UseShellExecute = false; return null;
Process p = new Process(); }
p.StartInfo = info;
p.Start(); static string RetrieveBzrRevision()
p.WaitForExit(); {
string output = p.StandardOutput.ReadToEnd(); try
return output; {
} string output = RunProcess("bzr", "revno", RootDirectory);
} return output != null && !output.StartsWith("bzr") ? output : null;
}
catch (Exception e)
{
Debug.Print("Failed to retrieve svn revision. Error: {0}", e);
}
return null;
}
static string RunProcess(string cmd, string args, string wdir)
{
ProcessStartInfo info = new ProcessStartInfo(cmd, args);
info.WorkingDirectory = wdir;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.UseShellExecute = false;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();
return output;
}
}
} }

View file

@ -41,7 +41,12 @@ namespace Examples
public static void Main() public static void Main()
{ {
try try
{ {
// This seems to be useful enough to leave in for a while.
TextWriterTraceListener console = new TextWriterTraceListener(System.Console.Out);
Trace.Listeners.Add (console);
Debug.Listeners.Add (console);
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);