diff --git a/docs/usage/command-line.md b/docs/usage/command-line.md index dc61f9a66d..2c19f8b6d4 100644 --- a/docs/usage/command-line.md +++ b/docs/usage/command-line.md @@ -80,5 +80,8 @@ It will not change config file 'GitVersion.yml'. ### Example: How to override configuration option 'tag-prefix' to use prefix 'custom' `GitVersion.exe /output json /overrideconfig tag-prefix=custom` +## Writing version metadata in WiX format +To support integration with WiX projects, use `GitVersion.exe /updatewixversionfile`. All the [variables](../more-info/variables.md) are written to `GitVersion_WixVersion.wxi` under the current working directory and can be referenced in the WiX project files. + ## Mono To use on mac or linux, install `mono-complete` then just run `mono GitVersion.exe` diff --git a/src/GitVersionCore.Tests/Approved/WixFileTests.UpdateWixVersionFile.approved.txt b/src/GitVersionCore.Tests/Approved/WixFileTests.UpdateWixVersionFile.approved.txt new file mode 100644 index 0000000000..7648bd1ef3 --- /dev/null +++ b/src/GitVersionCore.Tests/Approved/WixFileTests.UpdateWixVersionFile.approved.txt @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/GitVersionCore.Tests/WixFileTests.cs b/src/GitVersionCore.Tests/WixFileTests.cs new file mode 100644 index 0000000000..6140d15bc4 --- /dev/null +++ b/src/GitVersionCore.Tests/WixFileTests.cs @@ -0,0 +1,54 @@ +namespace GitVersionCore.Tests +{ + using System; + using System.IO; + using System.Text; + using GitVersion; + using NUnit.Framework; + using Shouldly; + + [TestFixture] + [Parallelizable(ParallelScope.None)] + class WixFileTests + { + [SetUp] + public void Setup() + { + ShouldlyConfiguration.ShouldMatchApprovedDefaults.LocateTestMethodUsingAttribute(); + } + + [Test] + [Category("NoMono")] + [Description("Won't run on Mono due to source information not being available for ShouldMatchApproved.")] + public void UpdateWixVersionFile() + { + var fileSystem = new TestFileSystem(); + var workingDir = Path.GetTempPath(); + var semVer = new SemanticVersion + { + Major = 1, + Minor = 2, + Patch = 3, + BuildMetaData = "5.Branch.develop" + }; + + semVer.BuildMetaData.Sha = "commitSha"; + semVer.BuildMetaData.ShortSha = "commitShortSha"; + semVer.BuildMetaData.CommitDate = DateTimeOffset.Parse("2019-02-20 23:59:59Z"); + + var config = new TestEffectiveConfiguration(buildMetaDataPadding: 2, legacySemVerPadding: 5); + var vars = VariableProvider.GetVariablesFor(semVer, config, false); + + StringBuilder log = new StringBuilder(); + Action action = s => log.AppendLine(s); + Logger.SetLoggers(action, action, action, action); + using (var wixVersionFileUpdater = new WixVersionFileUpdater(workingDir, vars, fileSystem)) + { + wixVersionFileUpdater.Update(); + } + + fileSystem.ReadAllText(WixVersionFileUpdater.GetWixVersionFileName()). + ShouldMatchApproved(c => c.SubFolder(Path.Combine("Approved"))); + } + } +} diff --git a/src/GitVersionCore/WixVersionFileUpdater.cs b/src/GitVersionCore/WixVersionFileUpdater.cs new file mode 100644 index 0000000000..1abe2d86a6 --- /dev/null +++ b/src/GitVersionCore/WixVersionFileUpdater.cs @@ -0,0 +1,65 @@ +namespace GitVersion +{ + using Helpers; + + using System; + using System.Text; + using System.Xml; + + public class WixVersionFileUpdater : IDisposable + { + string workingDirectory; + VersionVariables variables; + IFileSystem fileSystem; + private const string WIX_VERSION_FILE = "GitVersion_WixVersion.wxi "; + + public WixVersionFileUpdater(string workingDirectory, VersionVariables variables, IFileSystem fileSystem) + { + this.workingDirectory = workingDirectory; + this.variables = variables; + this.fileSystem = fileSystem; + } + + public static string GetWixVersionFileName() + { + return WIX_VERSION_FILE; + } + + public void Update() + { + Logger.WriteInfo("Updating GitVersion_WixVersion.wxi"); + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(GetWixFormatFromVersionVariables()); + + XmlDeclaration xmlDecl = doc.CreateXmlDeclaration("1.0", "utf-8", null); + XmlElement root = doc.DocumentElement; + doc.InsertBefore(xmlDecl, root); + + using (var fs = fileSystem.OpenWrite(WIX_VERSION_FILE)) + { + doc.Save(fs); + } + } + + private string GetWixFormatFromVersionVariables() + { + StringBuilder builder = new StringBuilder(); + builder.Append("\n"); + var availableVariables = VersionVariables.AvailableVariables; + foreach (var variable in availableVariables) + { + string value = null; + variables.TryGetValue(variable, out value); + builder.Append(string.Format("\t\n", variable, value)); + } + builder.Append("\n"); + return builder.ToString(); + } + + public void Dispose() + { + Logger.WriteInfo(string.Format("Done writing {0}", WIX_VERSION_FILE)); + } + } +} diff --git a/src/GitVersionExe.Tests/HelpWriterTests.cs b/src/GitVersionExe.Tests/HelpWriterTests.cs index 1b48500636..ef8e8f4c72 100644 --- a/src/GitVersionExe.Tests/HelpWriterTests.cs +++ b/src/GitVersionExe.Tests/HelpWriterTests.cs @@ -17,7 +17,8 @@ public void AllArgsAreInHelp() { "LogFilePath" , "/l" }, { "DynamicRepositoryLocation" , "/dynamicRepoLocation" }, { "IsHelp", "/?" }, - { "IsVersion", "/version" } + { "IsVersion", "/version" }, + { "UpdateWixVersionFile", "/updatewixversionfile" } }; string helpText = null; diff --git a/src/GitVersionExe.Tests/UpdateWixVersionFileTests.cs b/src/GitVersionExe.Tests/UpdateWixVersionFileTests.cs new file mode 100644 index 0000000000..e63fd4a398 --- /dev/null +++ b/src/GitVersionExe.Tests/UpdateWixVersionFileTests.cs @@ -0,0 +1,109 @@ +namespace GitVersionExe.Tests +{ + using System.IO; + using System.Linq; + using NUnit.Framework; + + using GitVersion; + using GitTools.Testing; + using System.Collections.Generic; + using System.Xml; + + [TestFixture] + [Parallelizable(ParallelScope.None)] + class UpdateWixVersionFileTests + { + private string WixVersionFileName; + + [SetUp] + public void Setup() + { + WixVersionFileName = WixVersionFileUpdater.GetWixVersionFileName(); + } + + [Test] + [Category("NoMono")] + [Description("Doesn't work on Mono/Unix because of the path heuristics that needs to be done there in order to figure out whether the first argument actually is a path.")] + public void WixVersionFileCreationTest() + { + using (var fixture = new EmptyRepositoryFixture()) + { + fixture.MakeATaggedCommit("1.2.3"); + fixture.MakeACommit(); + + GitVersionHelper.ExecuteIn(fixture.RepositoryPath, arguments: " -updatewixversionfile"); + Assert.IsTrue(File.Exists(Path.Combine(fixture.RepositoryPath, WixVersionFileName))); + } + } + + [Test] + [Category("NoMono")] + [Description("Doesn't work on Mono/Unix because of the path heuristics that needs to be done there in order to figure out whether the first argument actually is a path.")] + public void WixVersionFileVarCountTest() + { + //Make sure we have captured all the version variables by count in the Wix version file + using (var fixture = new EmptyRepositoryFixture()) + { + fixture.MakeATaggedCommit("1.2.3"); + fixture.MakeACommit(); + + var gitVersionExecutionResults = GitVersionHelper.ExecuteIn(fixture.RepositoryPath, arguments: null); + VersionVariables vars = gitVersionExecutionResults.OutputVariables; + + GitVersionHelper.ExecuteIn(fixture.RepositoryPath, arguments: " -updatewixversionfile"); + + var gitVersionVarsInWix = GetGitVersionVarsInWixFile(Path.Combine(fixture.RepositoryPath, WixVersionFileName)); + var gitVersionVars = VersionVariables.AvailableVariables; + + Assert.AreEqual(gitVersionVars.Count(), gitVersionVarsInWix.Count); + } + } + + [Test] + [Category("NoMono")] + [Description("Doesn't work on Mono/Unix because of the path heuristics that needs to be done there in order to figure out whether the first argument actually is a path.")] + public void WixVersionFileContentTest() + { + using (var fixture = new EmptyRepositoryFixture()) + { + fixture.MakeATaggedCommit("1.2.3"); + fixture.MakeACommit(); + + var gitVersionExecutionResults = GitVersionHelper.ExecuteIn(fixture.RepositoryPath, arguments: null); + VersionVariables vars = gitVersionExecutionResults.OutputVariables; + + GitVersionHelper.ExecuteIn(fixture.RepositoryPath, arguments: " -updatewixversionfile"); + + var gitVersionVarsInWix = GetGitVersionVarsInWixFile(Path.Combine(fixture.RepositoryPath, WixVersionFileName)); + var gitVersionVars = VersionVariables.AvailableVariables; + + foreach (var variable in gitVersionVars) + { + string value = null; + vars.TryGetValue(variable, out value); + //Make sure the variable is present in the Wix file + Assert.IsTrue(gitVersionVarsInWix.ContainsKey(variable)); + //Make sure the values are equal + Assert.AreEqual(value, gitVersionVarsInWix[variable]); + } + } + } + + private Dictionary GetGitVersionVarsInWixFile(string file) + { + var gitVersionVarsInWix = new Dictionary(); + using (var reader = new XmlTextReader(file)) + { + while (reader.Read()) + { + if (reader.Name == "define") + { + string[] component = reader.Value.Split('='); + gitVersionVarsInWix[component[0]] = component[1].TrimStart('"').TrimEnd('"'); + } + } + } + return gitVersionVarsInWix; + } + } +} diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index afafc0af8c..9fe03d7217 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -337,6 +337,12 @@ public static Arguments ParseArguments(List commandLineArguments) continue; } + if (name.IsSwitch("updatewixversionfile")) + { + arguments.UpdateWixVersionFile = true; + continue; + } + var couldNotParseMessage = string.Format("Could not parse command line parameter '{0}'.", name); // If we've reached through all argument switches without a match, we can relatively safely assume that the first argument isn't a switch, but the target path. diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index fb0871b43b..04689a4438 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -43,6 +43,8 @@ public Arguments() public ISet UpdateAssemblyInfoFileName; public bool EnsureAssemblyInfo; + public bool UpdateWixVersionFile; + public bool ShowConfig; public bool NoFetch; public bool NoCache; diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index ca2f4161d2..3a5bda3b97 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -48,7 +48,13 @@ Specify name of AssemblyInfo file. Can also /updateAssemblyInfo GlobalAssemblyIn it be created with these attributes: AssemblyFileVersion, AssemblyVersion and AssemblyInformationalVersion --- Supports writing version info for: C#, F#, VB -# Remote repository args + + # Create or update Wix version file + /updatewixversionfile + All the GitVersion variables are written to 'GitVersion_WixVersion.wxi'. + The variables can then be referenced in other WiX project files for versioning. + + # Remote repository args /url Url to remote git repository. /b Name of the branch to use on the remote repository, must be used in combination with /url. /u Username in case authentication is required. diff --git a/src/GitVersionExe/SpecifiedArgumentRunner.cs b/src/GitVersionExe/SpecifiedArgumentRunner.cs index f4b675a7f4..f8f7ed5b80 100644 --- a/src/GitVersionExe/SpecifiedArgumentRunner.cs +++ b/src/GitVersionExe/SpecifiedArgumentRunner.cs @@ -54,6 +54,14 @@ public static void Run(Arguments arguments, IFileSystem fileSystem) } } + if (arguments.UpdateWixVersionFile) + { + using (var wixVersionFileUpdater = new WixVersionFileUpdater(targetPath, variables, fileSystem)) + { + wixVersionFileUpdater.Update(); + } + } + using (var assemblyInfoUpdater = new AssemblyInfoFileUpdater(arguments.UpdateAssemblyInfoFileName, targetPath, variables, fileSystem, arguments.EnsureAssemblyInfo)) { if (arguments.UpdateAssemblyInfo)