/* * Created by SharpDevelop. * User: Daniel Grunwald * Date: 21.07.2005 * Time: 12:00 */ using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using System.Collections.Specialized; namespace UpdateAssemblyInfo { // Updates the version numbers in the assembly information. class MainClass { static Regex AssemblyVersion = new Regex(@"AssemblyVersion\(.*\)]"); static Regex BindingRedirect = new Regex(@""); const string mainConfig = "Main/StartUp/Project/Configuration/"; public static int Main(string[] args) { try { if (args.Length != 1) { PrintHelp(); return 1; } if (!File.Exists("SharpDevelop.sln")) { if (File.Exists("..\\src\\SharpDevelop.sln")) { Directory.SetCurrentDirectory("..\\src"); } } if (!File.Exists("SharpDevelop.sln")) { Console.WriteLine("Working directory must be SharpDevelop\\src or SharpDevelop\\bin!"); return 2; } string arg = args[0]; if (arg == "StartupOnly") { RetrieveRevisionNumber(); UpdateStartup(); } else if (arg == "Libraries") { RetrieveRevisionNumber(); UpdateLibraries(GetMajorVersion() + "." + revisionNumber); } else if (arg == "ResetLibraries") { UpdateLibraries("2.0.0.1"); } else { PrintHelp(); return 1; } return 0; } catch (Exception ex) { Console.WriteLine(ex); return 3; } } static void PrintHelp() { Console.WriteLine("Application must be started with 1 argument:"); Console.WriteLine("UpdateAssemblyInfo StartupOnly // updates version info in Startup project"); Console.WriteLine("UpdateAssemblyInfo Libraries // updates all versions in the libraries, but not in Startup"); Console.WriteLine("UpdateAssemblyInfo ResetLibraries // resets versions in the libraries to 2.0.0.1 (use this before committing)"); } static void UpdateStartup() { string content; using (StreamReader r = new StreamReader(mainConfig + "AssemblyInfo.template")) { content = r.ReadToEnd(); } content = content.Replace("-INSERTREVISION-", revisionNumber); if (File.Exists(mainConfig + "AssemblyInfo.cs")) { using (StreamReader r = new StreamReader(mainConfig + "AssemblyInfo.cs")) { if (r.ReadToEnd() == content) { // nothing changed, do not overwrite file to prevent recompilation of StartUp // every time. return; } } } using (StreamWriter w = new StreamWriter(mainConfig + "AssemblyInfo.cs", false, Encoding.UTF8)) { w.Write(content); } } static string GetMajorVersion() { string version = "?"; // Get main version from startup using (StreamReader r = new StreamReader(mainConfig + "AssemblyInfo.template")) { string line; while ((line = r.ReadLine()) != null) { const string search = "string Version = \""; int pos = line.IndexOf(search); if (pos >= 0) { int e = line.IndexOf('"', pos + search.Length + 1); version = line.Substring(pos + search.Length, e - pos - search.Length); break; } } } return version; } static void UpdateLibraries(string versionNumber) { StringCollection col = SearchDirectory("AddIns", "AssemblyInfo.cs"); SearchDirectory("Main", "AssemblyInfo.cs", col); SearchDirectory("Libraries", "AssemblyInfo.cs", col); string[] dontTouchList = new string[] { "Main/StartUp/Project/", // Startup is special case "Libraries/log4net/", "Libraries/NUnit.Framework/", "Libraries/DockPanel_Src/", "AddIns/Misc/Debugger/TreeListView/Project/", }; foreach (string fileName in col) { bool doSetVersion = true; foreach (string dontTouch in dontTouchList) { if (fileName.StartsWith(dontTouch.Replace("/", Path.DirectorySeparatorChar.ToString()))) { doSetVersion = false; break; } } if (doSetVersion) { Console.WriteLine("Set revision to file: " + fileName + " to " + versionNumber); SetVersionInfo(fileName, AssemblyVersion, "AssemblyVersion(\"" + versionNumber + "\")]"); } } SetVersionInfo("Main/StartUp/Project/SharpDevelop.exe.config", BindingRedirect, ""); } #region SearchDirectory static StringCollection SearchDirectory(string directory, string filemask) { StringCollection collection = new StringCollection(); SearchDirectory(directory, filemask, collection); return collection; } static void SearchDirectory(string directory, string filemask, StringCollection collection) { try { string[] file = Directory.GetFiles(directory, filemask); foreach (string f in file) { collection.Add(f); } string[] dir = Directory.GetDirectories(directory); foreach (string d in dir) { if (d.EndsWith("\\.svn")) continue; SearchDirectory(d, filemask, collection); } } catch (Exception ex) { Console.WriteLine(ex); } } #endregion static void SetVersionInfo(string fileName, Regex regex, string replacement) { string content; using (StreamReader inFile = new StreamReader(fileName)) { content = inFile.ReadToEnd(); } string newContent = regex.Replace(content, replacement); if (newContent == content) return; using (StreamWriter outFile = new StreamWriter(fileName, false, Encoding.UTF8)) { outFile.Write(newContent); } } #region Retrieve Revision Number static string revisionNumber = "0"; static string ReadRevisionFromFile() { try { using (StreamReader reader = new StreamReader(@"..\REVISION")) { return reader.ReadLine(); } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(); Console.WriteLine("The revision number of the SharpDevelop version being compiled could not be retrieved."); Console.WriteLine(); Console.WriteLine("Build continues with revision number '9999'..."); try { Process[] p = Process.GetProcessesByName("msbuild"); if (p != null && p.Length > 0) { System.Threading.Thread.Sleep(3000); } } catch {} return "9999"; } } static void RetrieveRevisionNumber() { // we use NSvn to be independent from the installed subversion client // NSvn is a quite big library (>1 MB). // We don't want to have it twice in the repository, so we must use the version in the // subversion addin directory without copying it to the UpdateAssemblyInfo directory. // That means we have to use reflection on the library. string oldWorkingDir = Environment.CurrentDirectory; try { // Set working directory so msvcp70.dll and msvcr70.dll can be found Environment.CurrentDirectory = Path.Combine(oldWorkingDir, "AddIns\\Misc\\SubversionAddIn\\RequiredLibraries"); Assembly asm = Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, "NSvn.Core.dll")); Type clientType = asm.GetType("NSvn.Core.Client"); object clientInstance = Activator.CreateInstance(clientType); object statusInstance = clientType.InvokeMember("SingleStatus", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, clientInstance, new object[] { oldWorkingDir }); Type statusType = statusInstance.GetType(); object entryInstance = statusType.InvokeMember("Entry", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public, null, statusInstance, new object[0]); Type entryType = entryInstance.GetType(); int revision = (int)entryType.InvokeMember("Revision", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public, null, entryInstance, new object[0]); revisionNumber = revision.ToString(); } catch (Exception e) { Console.WriteLine("Reading revision number with NSvn failed: " + e.Message); } finally { Environment.CurrentDirectory = oldWorkingDir; } if (revisionNumber == null || revisionNumber.Length == 0 || revisionNumber == "0") { revisionNumber = ReadRevisionFromFile(); } if (revisionNumber == null || revisionNumber.Length == 0 || revisionNumber == "0") { throw new ApplicationException("Error reading revision number"); } } #endregion } }