diff --git a/.gitignore b/.gitignore index 8a6addb..0f7f99e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ [Bb]in [Oo]bj *.suo -*.user \ No newline at end of file +*.user +/.vs +/packages diff --git a/WhenTheVersion.Tests/AssemblyInfoReaderTests.cs b/WhenTheVersion.Tests/AssemblyInfoReaderTests.cs new file mode 100644 index 0000000..5526025 --- /dev/null +++ b/WhenTheVersion.Tests/AssemblyInfoReaderTests.cs @@ -0,0 +1,66 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using WhenTheVersion; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; + +namespace WhenTheVersion.Tests +{ + [TestClass()] + public class AssemblyInfoReaderTests + { + string _projectDirectory = Directory.GetParent(Environment.CurrentDirectory).Parent.FullName; + + [TestMethod()] + public void GetRevisionInfoTestCaseStraightForward() + { + AssemblyInfoReader assemblyInfoReader = new AssemblyInfoReader(Path.Combine(_projectDirectory, "AssemblyInfoTestCase1.cs")); + var revisionInfo = assemblyInfoReader.GetRevisionInfo(); + //In this case it should not fail + Assert.AreEqual(true, revisionInfo.Succeed); + } + + + [TestMethod()] + public void GetRevisionInfoTestCaseWithAsterisks() + { + AssemblyInfoReader assemblyInfoReader = new AssemblyInfoReader(Path.Combine(_projectDirectory, "AssemblyInfoTestCase2.cs")); + var revisionInfo = assemblyInfoReader.GetRevisionInfo(); + //In this case it should not succeed + Assert.AreEqual(true, !revisionInfo.Succeed); + + } + + [TestMethod()] + public void GetRevisionInfoTestCaseWithComments() + { + AssemblyInfoReader assemblyInfoReader = new AssemblyInfoReader(Path.Combine(_projectDirectory, "AssemblyInfoTestCase3.cs")); + var revisionInfo = assemblyInfoReader.GetRevisionInfo(); + //In this case it should succeed + Assert.AreEqual(true, revisionInfo.Succeed); + Assert.AreEqual(16, revisionInfo.NextRevisionNumber); + } + + + [TestMethod()] + public void GetRevisionInfoTestCaseMissingAssemblyVersionInfo() + { + AssemblyInfoReader assemblyInfoReader = new AssemblyInfoReader(Path.Combine(_projectDirectory, "AssemblyInfoTestCase4.cs")); + var revisionInfo = assemblyInfoReader.GetRevisionInfo(); + //This needs to fail as file doesn't have AssemblyInfo line + Assert.AreEqual(false, revisionInfo.Succeed); + } + + [TestMethod()] + [ExpectedException(typeof(FileNotFoundException))] + public void GetRevisionInfoTestCaseMissingFile() + { + AssemblyInfoReader assemblyInfoReader = new AssemblyInfoReader(Path.Combine(_projectDirectory, "AssemblyInfoTestCase6.cs")); + //This needs to throw FileNotFoundException + var revisionInfo = assemblyInfoReader.GetRevisionInfo(); + } + } +} \ No newline at end of file diff --git a/WhenTheVersion.Tests/AssemblyInfoTestCase1.cs b/WhenTheVersion.Tests/AssemblyInfoTestCase1.cs new file mode 100644 index 0000000..db5a2d8 --- /dev/null +++ b/WhenTheVersion.Tests/AssemblyInfoTestCase1.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e54a2b6f-998e-45e0-9329-8117e77e3067")] + +[assembly: AssemblyVersion("2019.6.20.0")] +[assembly: AssemblyFileVersion("2019.6.20.0")] \ No newline at end of file diff --git a/WhenTheVersion.Tests/AssemblyInfoTestCase2.cs b/WhenTheVersion.Tests/AssemblyInfoTestCase2.cs new file mode 100644 index 0000000..4ad8769 --- /dev/null +++ b/WhenTheVersion.Tests/AssemblyInfoTestCase2.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e54a2b6f-998e-45e0-9329-8117e77e3067")] + +[assembly: AssemblyVersion("2019.6.*")] +[assembly: AssemblyFileVersion("2019.6.*")] \ No newline at end of file diff --git a/WhenTheVersion.Tests/AssemblyInfoTestCase3.cs b/WhenTheVersion.Tests/AssemblyInfoTestCase3.cs new file mode 100644 index 0000000..6012cc5 --- /dev/null +++ b/WhenTheVersion.Tests/AssemblyInfoTestCase3.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e54a2b6f-998e-45e0-9329-8117e77e3067")] + +//[assembly: AssemblyVersion("2019.6.20.1")] - This should not be used and next version should be 16 +//[assembly: AssemblyVersion("2019.6.20.12")] - This should not be used and next version should be 16 + +[assembly: AssemblyVersion("2019.6.20.15")] +[assembly: AssemblyFileVersion("2019.6.20.15")] \ No newline at end of file diff --git a/WhenTheVersion.Tests/AssemblyInfoTestCase4.cs b/WhenTheVersion.Tests/AssemblyInfoTestCase4.cs new file mode 100644 index 0000000..188a5a6 --- /dev/null +++ b/WhenTheVersion.Tests/AssemblyInfoTestCase4.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e54a2b6f-998e-45e0-9329-8117e77e3067")] + +//[assembly: AssemblyVersion("2019.6.20.1")] - This should not be used and next version should be 0 +//[assembly: AssemblyVersion("2019.6.20.12")] - This should not be used and next version should be 0 \ No newline at end of file diff --git a/WhenTheVersion.Tests/Properties/AssemblyInfo.cs b/WhenTheVersion.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..df88222 --- /dev/null +++ b/WhenTheVersion.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("WhenTheVersion.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WhenTheVersion.Tests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b8012fc7-6098-416c-a5da-ad266ca00030")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WhenTheVersion.Tests/WhenTheVersion.Tests.csproj b/WhenTheVersion.Tests/WhenTheVersion.Tests.csproj new file mode 100644 index 0000000..e1a39d5 --- /dev/null +++ b/WhenTheVersion.Tests/WhenTheVersion.Tests.csproj @@ -0,0 +1,110 @@ + + + + + Debug + AnyCPU + {B8012FC7-6098-416C-A5DA-AD266CA00030} + Library + Properties + WhenTheVersion.Tests + WhenTheVersion.Tests + v4.6 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + + + + + + + + + + {2cacb06c-1f98-4938-a333-92eba724cef9} + WhenTheVersion + + + + + + + False + + + False + + + False + + + False + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + \ No newline at end of file diff --git a/WhenTheVersion.Tests/packages.config b/WhenTheVersion.Tests/packages.config new file mode 100644 index 0000000..fc09f95 --- /dev/null +++ b/WhenTheVersion.Tests/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/WhenTheVersion.sln b/WhenTheVersion.sln index 5dae9c0..417ea70 100644 --- a/WhenTheVersion.sln +++ b/WhenTheVersion.sln @@ -1,8 +1,12 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29009.5 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WhenTheVersion", "WhenTheVersion\WhenTheVersion.csproj", "{2CACB06C-1F98-4938-A333-92EBA724CEF9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WhenTheVersion.Tests", "WhenTheVersion.Tests\WhenTheVersion.Tests.csproj", "{B8012FC7-6098-416C-A5DA-AD266CA00030}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -19,8 +23,19 @@ Global {2CACB06C-1F98-4938-A333-92EBA724CEF9}.Release|Any CPU.Build.0 = Release|Any CPU {2CACB06C-1F98-4938-A333-92EBA724CEF9}.Release|x86.ActiveCfg = Release|x86 {2CACB06C-1F98-4938-A333-92EBA724CEF9}.Release|x86.Build.0 = Release|x86 + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Debug|x86.ActiveCfg = Debug|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Debug|x86.Build.0 = Debug|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Release|Any CPU.Build.0 = Release|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Release|x86.ActiveCfg = Release|Any CPU + {B8012FC7-6098-416C-A5DA-AD266CA00030}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8DC6B4A4-B8E9-43BD-949D-9F1201181102} + EndGlobalSection EndGlobal diff --git a/WhenTheVersion/AssemblyInfoReader.cs b/WhenTheVersion/AssemblyInfoReader.cs new file mode 100644 index 0000000..42018cd --- /dev/null +++ b/WhenTheVersion/AssemblyInfoReader.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Linq; +using System.Text.RegularExpressions; + +namespace WhenTheVersion +{ + public class AssemblyInfoReader + { + private readonly string _fileNameWithPath; + + public AssemblyInfoReader(string fileNameWithPath) + { + _fileNameWithPath = fileNameWithPath; + } + + public RevisionInfo GetRevisionInfo() + { + if (File.Exists(_fileNameWithPath) == false) + throw new FileNotFoundException(_fileNameWithPath); + + //AsseemblyInfo file will be just couple of lines so no harm in reading entire file + var fileContents = RemoveAllComments(File.ReadAllText(_fileNameWithPath)); + + if (string.IsNullOrWhiteSpace(fileContents)) + return new RevisionInfo(0, 0, "File contents are empty"); + + const string GROUP_VERSION_NUMBER = "VersionNumber"; + + Regex extractAssemblyVersionLine = new Regex($@"Assembly(File)?Version\(""(?<{GROUP_VERSION_NUMBER}>.*)""\)"); //It will be case sensitive search + + Match lineMatch = extractAssemblyVersionLine.Match(fileContents); //Grab the first match only + + if (lineMatch.Success == false) + return new RevisionInfo(0, 0, "Can't find any line with text 'AssemblyFileVersion' or 'AssemblyVersion'"); + + var versionNumber = lineMatch.Groups[GROUP_VERSION_NUMBER].Value; + var lastRevisionNumber = versionNumber.Split('.').LastOrDefault(); + + if (int.TryParse(lastRevisionNumber, out var lastNumber)) + return new RevisionInfo(lastNumber, lastNumber + 1); + + return new RevisionInfo(0, 0, $"Can't parse {lastRevisionNumber} to int"); + } + string RemoveAllComments(string contents) + { + if (string.IsNullOrWhiteSpace(contents)) + return contents; + + contents += Environment.NewLine; + + //https://stackoverflow.com/a/3524689 + var blockComments = @"/\*(.*?)\*/"; + var lineComments = @"//(.*?)\r?\n"; + var strings = @"""((\\[^\n]|[^""\n])*)"""; + var verbatimStrings = @"@(""[^""]*"")+"; + + string noComments = Regex.Replace(contents, blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings, me => + { + if (me.Value.StartsWith("/*") || me.Value.StartsWith("//")) + return me.Value.StartsWith("//") ? Environment.NewLine : ""; + // Keep the literal strings + return me.Value; + }, RegexOptions.Singleline); + + return noComments; + } + } +} diff --git a/WhenTheVersion/Program.cs b/WhenTheVersion/Program.cs index 07add0e..715c829 100644 --- a/WhenTheVersion/Program.cs +++ b/WhenTheVersion/Program.cs @@ -2,14 +2,17 @@ using System.IO; using System.Diagnostics; -namespace WhatTheVersion { +namespace WhenTheVersion +{ - class Program { + class Program + { - const string DayPlaceholder = "{DD}"; - const string MonthPlaceholder = "{MM}"; - const string YearPlaceholder = "{YYYY}"; - const string SVNPlaceholder = "{SVN}"; + const string DayPlaceholder = "{DD}"; + const string MonthPlaceholder = "{MM}"; + const string YearPlaceholder = "{YYYY}"; + const string SVNPlaceholder = "{SVN}"; + const string AutoIncrementPlaceholder = "{AUTO}"; const string SubWCrevPlaceholder = "$WCREV$"; @@ -23,7 +26,8 @@ class Program { /// path-to-SubWCrev.exe (optional) /// svn-working-copy-path (required if path-to-SubWCrev.exe is given) /// - static int Main(string[] args) { + static int Main(string[] args) + { // is the usage correct? if (!(args.Length == 2 || args.Length == 4)) @@ -36,28 +40,37 @@ static int Main(string[] args) { // read the input file - try { - inputFileContents = File.ReadAllText(args[0]); - } catch (Exception) { + try + { + inputFileContents = File.ReadAllText(args[ArgumentIndex.InputFile]); + } + catch (Exception exc) + { + WriteErrorMessageToConsole(exc.Message); return PrintUsage(ExitCode.WTV_Problem_Reading_Input_File); } - + // do the replacements - try { + try + { outputFileContents = DoReplacements(inputFileContents, args); - } catch (Exception) { + } + catch (Exception) + { return PrintUsage(ExitCode.WTV_Problem_Doing_Replacements); } - + // write out - try { - File.WriteAllText(args[1], outputFileContents); - } - catch (Exception) { + try + { + File.WriteAllText(args[ArgumentIndex.OutputFile], outputFileContents); + } + catch (Exception) + { return PrintUsage(ExitCode.WTV_Problem_Writing_To_Output_File); - } + } // done @@ -69,14 +82,24 @@ static int Main(string[] args) { /// /// Replaces the Date and SVN placeholders with the actual values /// - private static string DoReplacements(string inputFileContents, string[] args) { + private static string DoReplacements(string inputFileContents, string[] args) + { DateTime now = DateTime.UtcNow; - return inputFileContents - .Replace(DayPlaceholder, now.Day.ToString()) - .Replace(MonthPlaceholder, now.Month.ToString()) - .Replace(YearPlaceholder, now.Year.ToString()) - .Replace(SVNPlaceholder, GetSVNRevisionNumber(args).ToString()); + + var updatedContents = inputFileContents + .Replace(DayPlaceholder, now.Day.ToString()) + .Replace(MonthPlaceholder, now.Month.ToString()) + .Replace(YearPlaceholder, now.Year.ToString()) + .Replace(SVNPlaceholder, GetSVNRevisionNumber(args).ToString()); + + var revisionInfo = GetRevisionInfo(inputFileContents, args); + if (revisionInfo == null) return updatedContents; + + if (revisionInfo.Succeed == false) + WriteErrorMessageToConsole(revisionInfo.ErrorIfAny); + + return updatedContents.Replace(AutoIncrementPlaceholder, revisionInfo.NextRevisionNumber.ToString()); } @@ -87,34 +110,42 @@ private static string DoReplacements(string inputFileContents, string[] args) { /// /// Always returns a value, but writes errors to the Console (returning 0) /// - private static ushort GetSVNRevisionNumber(string[] args) { + private static ushort GetSVNRevisionNumber(string[] args) + { ushort svnRevisionNumber = 0; - if (args.Length == 4) { + if (args.Length == 4) + { // is the given path to SubWCrev.exe OK? - if (!File.Exists(args[2])) { + if (!File.Exists(args[ArgumentIndex.SubWCRev])) + { // hmm, file doesn't exist, is this an environment variable containing the path instead? - try { - args[2] = Environment.GetEnvironmentVariable(args[2]); - } - catch (Exception) { /* exception doesn't matter */ } + try + { + args[ArgumentIndex.SubWCRev] = Environment.GetEnvironmentVariable(args[ArgumentIndex.SubWCRev]); + } + catch (Exception) + { /* exception doesn't matter */ + } } // try again in case we've found an environment variable.. - if (!File.Exists(args[2])) { - WriteErrorMessageToConsole("SubWCrev.exe not found at: " + args[2]); + if (!File.Exists(args[ArgumentIndex.SubWCRev])) + { + WriteErrorMessageToConsole("SubWCrev.exe not found at: " + args[ArgumentIndex.SubWCRev]); return svnRevisionNumber; } // do the call to SubWCRev.exe.. - try { - svnRevisionNumber = CallSubWCrev(args); - } catch (Exception ex) { - WriteErrorMessageToConsole(ex.Message); - } - - + try + { + svnRevisionNumber = CallSubWCrev(args); + } + catch (Exception ex) + { + WriteErrorMessageToConsole(ex.Message); + } } return svnRevisionNumber; @@ -127,26 +158,29 @@ private static ushort GetSVNRevisionNumber(string[] args) { /// Calls SubWCRev.exe to get the Subversion Working Copy Revision number /// /// - private static ushort CallSubWCrev(string[] args) { + private static ushort CallSubWCrev(string[] args) + { ushort svnRevisionNumber = 0; // create a temporary file call SubWCrev.exe on string tempFilename = Path.GetTempFileName(); - try { + try + { File.WriteAllText(tempFilename, SubWCrevPlaceholder); // make sure working copy path is enclosed in quotes // in case the path contains spaces.. - string workingCopyPath = args[3].StartsWith("\"") - ? args[3] : "\"" + args[3] + "\""; + string workingCopyPath = args[ArgumentIndex.SVNWorkingCopy].StartsWith("\"") + ? args[ArgumentIndex.SVNWorkingCopy] : "\"" + args[ArgumentIndex.SVNWorkingCopy] + "\""; // call SubWCrev.exe on our temporary file ProcessStartInfo subWCrevProcessInfo = new ProcessStartInfo( - args[2], - workingCopyPath + " \"" + tempFilename + "\" \"" + tempFilename + "\"") { CreateNoWindow = true }; + args[ArgumentIndex.SubWCRev], + workingCopyPath + " \"" + tempFilename + "\" \"" + tempFilename + "\"") + { CreateNoWindow = true }; Process subWCrevProcessCall = Process.Start(subWCrevProcessInfo); subWCrevProcessCall.WaitForExit(); @@ -156,7 +190,8 @@ private static ushort CallSubWCrev(string[] args) { // did it work? // SubWCRev.exe error codes: // source: http://code.google.com/p/tortoisesvn/source/browse/trunk/src/SubWCRev/SubWCRev.cpp - switch (subWCrevProcessCall.ExitCode) { + switch (subWCrevProcessCall.ExitCode) + { case 0: // Call completed OK @@ -208,18 +243,26 @@ private static ushort CallSubWCrev(string[] args) { default: throw new ArgumentException("SubWCRev.exe - unknown exit code status (sorry!)"); - } + } - } catch (ArgumentException) { + } + catch (ArgumentException) + { throw; - } catch (Exception ex) { + } + catch (Exception ex) + { throw new ArgumentException("Problem running SubWCrev.exe", ex); - } finally { + } + finally + { // tidy up - try { + try + { File.Delete(tempFilename); - } catch (Exception) { } + } + catch (Exception) { } } @@ -232,7 +275,8 @@ private static ushort CallSubWCrev(string[] args) { /// Writes an error message to the Console /// /// - private static void WriteErrorMessageToConsole(string message) { + private static void WriteErrorMessageToConsole(string message) + { ConsoleColor originalColor = Console.ForegroundColor; Console.WriteLine(""); @@ -252,7 +296,8 @@ private static void WriteErrorMessageToConsole(string message) { /// /// Prints usage instructions to the Console, and returns the int value for the ExitCode passed in /// - private static int PrintUsage(ExitCode exitCode) { + private static int PrintUsage(ExitCode exitCode) + { ConsoleColor originalColor = Console.ForegroundColor; Console.WriteLine(""); @@ -271,6 +316,7 @@ private static int PrintUsage(ExitCode exitCode) { Console.WriteLine(" {MM} - Month"); Console.WriteLine(" {YYYY} - Year"); Console.WriteLine(" {SVN} - SubVersion revision (must specify the path to SubWCrev.exe and working copy path)"); + Console.WriteLine(" {AUTO} - Will read the existing Build number from the file and will increment it by 1"); Console.WriteLine(""); Console.WriteLine(" Example Pre-Build command: (remove the line breaks)"); Console.WriteLine(" \"C:\\Path\\To\\WTV.exe\""); @@ -279,10 +325,23 @@ private static int PrintUsage(ExitCode exitCode) { Console.WriteLine(" \"C:\\Program Files\\TortoiseSVN\\bin\\SubWCRev.exe\""); Console.WriteLine(" \"$(SolutionDir).\""); + Console.WriteLine(" Example Pre-Build command: (remove the line breaks)"); + Console.WriteLine(" \"C:\\Path\\To\\WTV.exe\""); + Console.WriteLine(" \"$(ProjectDir)Properties\\AssemblyInfo.Template.cs\""); + Console.WriteLine(" \"$(ProjectDir)Properties\\AssemblyInfo.cs\""); + Console.WriteLine(" \"SubWCRev.exe\""); + Console.WriteLine(" \"$(SolutionDir).\""); + return (int)exitCode; } + private static RevisionInfo GetRevisionInfo(string inputFileContents, string[] args) + { + if (inputFileContents.IndexOf(AutoIncrementPlaceholder) == -1) + return null; + return new AssemblyInfoReader(args[ArgumentIndex.OutputFile]).GetRevisionInfo(); + } @@ -290,7 +349,8 @@ private static int PrintUsage(ExitCode exitCode) { /// /// Enumeration for exit / return codes /// - enum ExitCode : int { + enum ExitCode : int + { Success = 0, WTV_Wrong_No_Of_Arguments = 1, WTV_Problem_Reading_Input_File = 2, @@ -300,6 +360,13 @@ enum ExitCode : int { } + static class ArgumentIndex + { + public const int InputFile = 0; + public const int OutputFile = 1; + public const int SubWCRev = 2; + public const int SVNWorkingCopy = 3; + } } } diff --git a/WhenTheVersion/RevisionInfo.cs b/WhenTheVersion/RevisionInfo.cs new file mode 100644 index 0000000..55a6247 --- /dev/null +++ b/WhenTheVersion/RevisionInfo.cs @@ -0,0 +1,19 @@ +namespace WhenTheVersion +{ + public class RevisionInfo + { + public RevisionInfo(int revisionNumber, int nextRevisionNumber, string errorIfAny = null) + { + RevisionNumber = revisionNumber; + NextRevisionNumber = nextRevisionNumber; + ErrorIfAny = errorIfAny; + } + + public int RevisionNumber { get; } + public int NextRevisionNumber { get; } + public string ErrorIfAny { get; set; } + public bool Succeed => string.IsNullOrWhiteSpace(ErrorIfAny); + + public override string ToString() => Succeed ? $"RevisionNumber: {RevisionNumber}, NextRevisionNumber: {NextRevisionNumber}" : ErrorIfAny; + } +} diff --git a/WhenTheVersion/WhenTheVersion.csproj b/WhenTheVersion/WhenTheVersion.csproj index 551be84..362a4ec 100644 --- a/WhenTheVersion/WhenTheVersion.csproj +++ b/WhenTheVersion/WhenTheVersion.csproj @@ -1,5 +1,5 @@  - + Debug x86 @@ -10,7 +10,7 @@ Properties WhenTheVersion WTV - v2.0 + v4.6 512 @@ -24,6 +24,7 @@ DEBUG;TRACE prompt 4 + false x86 @@ -33,6 +34,7 @@ TRACE prompt 4 + false wtv.ico @@ -40,17 +42,21 @@ AnyCPU bin\Debug\ + false AnyCPU bin\Release\ + false + + diff --git a/WhenTheVersion/app.config b/WhenTheVersion/app.config index 49666a2..7674e72 100644 --- a/WhenTheVersion/app.config +++ b/WhenTheVersion/app.config @@ -1,6 +1,6 @@ - - + +