From 42c3bf59a8200715133d9129e52842d73313e4ed Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 10 May 2020 04:34:10 -0400 Subject: [PATCH 01/13] Adds capability to update project files --- .../Helpers/TestFileSystem.cs | 2 +- .../AssemblyInfoFileUpdaterTests.cs | 2 +- .../ProjectFileUpdaterTests.cs | 318 ++++++++++++++++++ src/GitVersionCore/Common/IFileSystem.cs | 2 +- src/GitVersionCore/Core/FileSystem.cs | 4 +- src/GitVersionCore/Core/GitVersionTool.cs | 20 +- src/GitVersionCore/GitVersionCoreModule.cs | 1 + src/GitVersionCore/Model/AssemblyInfoData.cs | 1 + .../AssemblyInfo/AssemblyInfoFileUpdater.cs | 2 +- .../AssemblyInfo/ProjectFileUpdater.cs | 213 ++++++++++++ src/GitVersionExe/ArgumentParser.cs | 6 + src/GitVersionExe/Arguments.cs | 2 + 12 files changed, 564 insertions(+), 9 deletions(-) create mode 100644 src/GitVersionCore.Tests/VersionConverters/ProjectFileUpdaterTests.cs create mode 100644 src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs diff --git a/src/GitVersionCore.Tests/Helpers/TestFileSystem.cs b/src/GitVersionCore.Tests/Helpers/TestFileSystem.cs index 2bbed5a83c..ddfac75184 100644 --- a/src/GitVersionCore.Tests/Helpers/TestFileSystem.cs +++ b/src/GitVersionCore.Tests/Helpers/TestFileSystem.cs @@ -73,7 +73,7 @@ public void WriteAllText(string file, string fileContents, Encoding encoding) fileSystem[path] = encoding.GetBytes(fileContents); } - public IEnumerable DirectoryGetFiles(string directory, string searchPattern, SearchOption searchOption) + public IEnumerable DirectoryEnumerateFiles(string directory, string searchPattern, SearchOption searchOption) { throw new NotImplementedException(); } diff --git a/src/GitVersionCore.Tests/VersionConverters/AssemblyInfoFileUpdaterTests.cs b/src/GitVersionCore.Tests/VersionConverters/AssemblyInfoFileUpdaterTests.cs index e64de23625..a148690f64 100644 --- a/src/GitVersionCore.Tests/VersionConverters/AssemblyInfoFileUpdaterTests.cs +++ b/src/GitVersionCore.Tests/VersionConverters/AssemblyInfoFileUpdaterTests.cs @@ -139,7 +139,7 @@ public void ShouldStartSearchFromWorkingDirectory() using var assemblyInfoFileUpdater = new AssemblyInfoFileUpdater(log, fileSystem); assemblyInfoFileUpdater.Execute(variables, new AssemblyInfoContext(workingDir, false, assemblyInfoFiles.ToArray())); - fileSystem.Received().DirectoryGetFiles(Arg.Is(workingDir), Arg.Any(), Arg.Any()); + fileSystem.Received().DirectoryEnumerateFiles(Arg.Is(workingDir), Arg.Any(), Arg.Any()); } [TestCase("cs", "[assembly: AssemblyVersion(\"1.0.0.0\")]\r\n[assembly: AssemblyInformationalVersion(\"1.0.0.0\")]\r\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]")] diff --git a/src/GitVersionCore.Tests/VersionConverters/ProjectFileUpdaterTests.cs b/src/GitVersionCore.Tests/VersionConverters/ProjectFileUpdaterTests.cs new file mode 100644 index 0000000000..1be9f3f599 --- /dev/null +++ b/src/GitVersionCore.Tests/VersionConverters/ProjectFileUpdaterTests.cs @@ -0,0 +1,318 @@ +using System; +using System.IO; +using System.Xml.Linq; +using GitVersion; +using GitVersion.Extensions; +using GitVersion.Logging; +using GitVersion.OutputVariables; +using GitVersion.VersionCalculation; +using GitVersion.VersionConverters.AssemblyInfo; +using GitVersionCore.Tests.Helpers; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using NUnit.Framework; +using Shouldly; + +namespace GitVersionCore.Tests +{ + [TestFixture] + [Parallelizable(ParallelScope.None)] + public class ProjectFileUpdaterTests : TestBase + { + private IVariableProvider variableProvider; + private ILog log; + private IFileSystem fileSystem; + + [SetUp] + public void Setup() + { + ShouldlyConfiguration.ShouldMatchApprovedDefaults.LocateTestMethodUsingAttribute(); + var sp = ConfigureServices(); + log = Substitute.For(); + fileSystem = sp.GetService(); + variableProvider = sp.GetService(); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + + +")] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void CanUpdateProjectFileWithStandardProjectFileXml(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var canUpdate = projectFileUpdater.CanUpdateProjectFile(XElement.Parse(xml)); + + canUpdate.ShouldBe(true); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + + +")] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void CannotUpdateProjectFileWithIncorrectProjectSdk(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var canUpdate = projectFileUpdater.CanUpdateProjectFile(XElement.Parse(xml)); + + canUpdate.ShouldBe(false); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + + +")] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void CannotUpdateProjectFileWithMissingProjectSdk(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var canUpdate = projectFileUpdater.CanUpdateProjectFile(XElement.Parse(xml)); + + canUpdate.ShouldBe(false); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + false + + +")] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void CannotUpdateProjectFileWithoutAssemblyInfoGeneration(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var canUpdate = projectFileUpdater.CanUpdateProjectFile(XElement.Parse(xml)); + + canUpdate.ShouldBe(false); + } + + [TestCase(@" + + +")] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void CannotUpdateProjectFileWithoutAPropertyGroup(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var canUpdate = projectFileUpdater.CanUpdateProjectFile(XElement.Parse(xml)); + + canUpdate.ShouldBe(false); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + +" + )] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void UpdateProjectXmlVersionElementWithStandardXmlInsertsElement(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var variables = variableProvider.GetVariablesFor(SemanticVersion.Parse("2.0.0", "v"), new TestEffectiveConfiguration(), false); + var xmlRoot = XElement.Parse(xml); + projectFileUpdater.UpdateProjectVersionElement(xmlRoot, ProjectFileUpdater.AssemblyVersionElement, variables.AssemblySemVer); + + var expectedXml = XElement.Parse(@" + + + Exe + netcoreapp3.1 + 2.0.0.0 + +"); + xmlRoot.ToString().ShouldBe(expectedXml.ToString()); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + 1.0.0.0 + +" + )] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void UpdateProjectXmlVersionElementWithStandardXmlModifiesElement(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var variables = variableProvider.GetVariablesFor(SemanticVersion.Parse("2.0.0", "v"), new TestEffectiveConfiguration(), false); + var xmlRoot = XElement.Parse(xml); + projectFileUpdater.UpdateProjectVersionElement(xmlRoot, ProjectFileUpdater.AssemblyVersionElement, variables.AssemblySemVer); + + var expectedXml = XElement.Parse(@" + + + Exe + netcoreapp3.1 + 2.0.0.0 + +"); + xmlRoot.ToString().ShouldBe(expectedXml.ToString()); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + 1.0.0.0 + + + 1.0.0.0 + +" + )] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void UpdateProjectXmlVersionElementWithDuplicatePropertyGroupsModifiesLastElement(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var variables = variableProvider.GetVariablesFor(SemanticVersion.Parse("2.0.0", "v"), new TestEffectiveConfiguration(), false); + var xmlRoot = XElement.Parse(xml); + projectFileUpdater.UpdateProjectVersionElement(xmlRoot, ProjectFileUpdater.AssemblyVersionElement, variables.AssemblySemVer); + + var expectedXml = XElement.Parse(@" + + + Exe + netcoreapp3.1 + 1.0.0.0 + + + 2.0.0.0 + +"); + xmlRoot.ToString().ShouldBe(expectedXml.ToString()); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + 1.0.0.0 + 1.0.0.0 + +" + )] + + [Category(NoMono)] + [Description(NoMonoDescription)] + public void UpdateProjectXmlVersionElementWithMultipleVersionElementsLastOneIsModified(string xml) + { + using var projectFileUpdater = new ProjectFileUpdater(log, fileSystem); + + var variables = variableProvider.GetVariablesFor(SemanticVersion.Parse("2.0.0", "v"), new TestEffectiveConfiguration(), false); + var xmlRoot = XElement.Parse(xml); + projectFileUpdater.UpdateProjectVersionElement(xmlRoot, ProjectFileUpdater.AssemblyVersionElement, variables.AssemblySemVer); + + var expectedXml = XElement.Parse(@" + + + Exe + netcoreapp3.1 + 1.0.0.0 + 2.0.0.0 + +"); + xmlRoot.ToString().ShouldBe(expectedXml.ToString()); + } + + [TestCase(@" + + + Exe + netcoreapp3.1 + +")] + [Category(NoMono)] + [Description(NoMonoDescription)] + public void UpdateProjectFileAddsVersionToFile(string xml) + { + var fileName = Path.Combine(Path.GetTempPath(), "TestProject.csproj"); + + VerifyAssemblyInfoFile(xml, fileName, AssemblyVersioningScheme.MajorMinorPatch, verify: (fs, variables) => + { + using var projectFileUpdater = new ProjectFileUpdater(log, fs); + projectFileUpdater.Execute(variables, new AssemblyInfoContext(Path.GetTempPath(), false, fileName)); + + var expectedXml = @" + + + Exe + netcoreapp3.1 + 2.3.1.0 + 2.3.1.0 + 2.3.1+3.Branch.foo.Sha.hash + +"; + var transformedXml = fs.ReadAllText(fileName); + transformedXml.ShouldBe(XElement.Parse(expectedXml).ToString()); + }); + } + + private void VerifyAssemblyInfoFile( + string projectFileContent, + string fileName, + AssemblyVersioningScheme versioningScheme = AssemblyVersioningScheme.MajorMinorPatch, + Action verify = null) + { + fileSystem = Substitute.For(); + var version = new SemanticVersion + { + BuildMetaData = new SemanticVersionBuildMetaData("versionSourceHash", 3, "foo", "hash", "shortHash", DateTimeOffset.Now), + Major = 2, + Minor = 3, + Patch = 1 + }; + + fileSystem.Exists(fileName).Returns(true); + fileSystem.ReadAllText(fileName).Returns(projectFileContent); + fileSystem.When(f => f.WriteAllText(fileName, Arg.Any())).Do(c => + { + projectFileContent = c.ArgAt(1); + fileSystem.ReadAllText(fileName).Returns(projectFileContent); + }); + + var config = new TestEffectiveConfiguration(assemblyVersioningScheme: versioningScheme); + var variables = variableProvider.GetVariablesFor(version, config, false); + + verify?.Invoke(fileSystem, variables); + } + } +} diff --git a/src/GitVersionCore/Common/IFileSystem.cs b/src/GitVersionCore/Common/IFileSystem.cs index 55dd3e0b5c..bfd32bcbd5 100644 --- a/src/GitVersionCore/Common/IFileSystem.cs +++ b/src/GitVersionCore/Common/IFileSystem.cs @@ -13,7 +13,7 @@ public interface IFileSystem string ReadAllText(string path); void WriteAllText(string file, string fileContents); void WriteAllText(string file, string fileContents, Encoding encoding); - IEnumerable DirectoryGetFiles(string directory, string searchPattern, SearchOption searchOption); + IEnumerable DirectoryEnumerateFiles(string directory, string searchPattern, SearchOption searchOption); Stream OpenWrite(string path); Stream OpenRead(string path); void CreateDirectory(string path); diff --git a/src/GitVersionCore/Core/FileSystem.cs b/src/GitVersionCore/Core/FileSystem.cs index 3f5ef24f7f..cb64fee773 100644 --- a/src/GitVersionCore/Core/FileSystem.cs +++ b/src/GitVersionCore/Core/FileSystem.cs @@ -46,9 +46,9 @@ public void WriteAllText(string file, string fileContents, Encoding encoding) File.WriteAllText(file, fileContents, encoding); } - public IEnumerable DirectoryGetFiles(string directory, string searchPattern, SearchOption searchOption) + public IEnumerable DirectoryEnumerateFiles(string directory, string searchPattern, SearchOption searchOption) { - return Directory.GetFiles(directory, searchPattern, searchOption); + return Directory.EnumerateFiles(directory, searchPattern, searchOption); } public Stream OpenWrite(string path) diff --git a/src/GitVersionCore/Core/GitVersionTool.cs b/src/GitVersionCore/Core/GitVersionTool.cs index 041f79a520..4786d9a577 100644 --- a/src/GitVersionCore/Core/GitVersionTool.cs +++ b/src/GitVersionCore/Core/GitVersionTool.cs @@ -4,6 +4,7 @@ using GitVersion.OutputVariables; using GitVersion.VersionCalculation; using GitVersion.VersionCalculation.Cache; +using GitVersion.VersionConverters; using GitVersion.VersionConverters.AssemblyInfo; using GitVersion.VersionConverters.GitVersionInfo; using GitVersion.VersionConverters.OutputGenerator; @@ -24,6 +25,7 @@ public class GitVersionTool : IGitVersionTool private readonly IWixVersionFileUpdater wixVersionFileUpdater; private readonly IGitVersionInfoGenerator gitVersionInfoGenerator; private readonly IAssemblyInfoFileUpdater assemblyInfoFileUpdater; + private readonly IProjectFileUpdater projectFileUpdater; private readonly IOptions options; private readonly Lazy versionContext; @@ -32,7 +34,7 @@ public class GitVersionTool : IGitVersionTool public GitVersionTool(ILog log, INextVersionCalculator nextVersionCalculator, IVariableProvider variableProvider, IGitPreparer gitPreparer, IGitVersionCache gitVersionCache, IGitVersionCacheKeyFactory cacheKeyFactory, IOutputGenerator outputGenerator, IWixVersionFileUpdater wixVersionFileUpdater, IGitVersionInfoGenerator gitVersionInfoGenerator, IAssemblyInfoFileUpdater assemblyInfoFileUpdater, - IOptions options, Lazy versionContext) + IOptions options, Lazy versionContext, IProjectFileUpdater projectFileUpdater) { this.log = log ?? throw new ArgumentNullException(nameof(log)); @@ -50,6 +52,7 @@ public GitVersionTool(ILog log, INextVersionCalculator nextVersionCalculator, IV this.options = options ?? throw new ArgumentNullException(nameof(options)); this.versionContext = versionContext ?? throw new ArgumentNullException(nameof(versionContext)); + this.projectFileUpdater = projectFileUpdater; } public VersionVariables CalculateVersionVariables() @@ -95,9 +98,20 @@ public void UpdateAssemblyInfo(VersionVariables variables) if (gitVersionOptions.AssemblyInfo.ShouldUpdate) { - using (assemblyInfoFileUpdater) + var assemblyInfoContext = new AssemblyInfoContext(gitVersionOptions.WorkingDirectory, gitVersionOptions.AssemblyInfo.EnsureAssemblyInfo, gitVersionOptions.AssemblyInfo.Files.ToArray()); + if (gitVersionOptions.AssemblyInfo.IsTargetingProjectFiles) { - assemblyInfoFileUpdater.Execute(variables, new AssemblyInfoContext(gitVersionOptions.WorkingDirectory, gitVersionOptions.AssemblyInfo.EnsureAssemblyInfo, gitVersionOptions.AssemblyInfo.Files.ToArray())); + using (projectFileUpdater) + { + projectFileUpdater.Execute(variables, assemblyInfoContext); + } + } + else + { + using (assemblyInfoFileUpdater) + { + assemblyInfoFileUpdater.Execute(variables, assemblyInfoContext); + } } } } diff --git a/src/GitVersionCore/GitVersionCoreModule.cs b/src/GitVersionCore/GitVersionCoreModule.cs index 99f7c6bde3..93279c23b2 100644 --- a/src/GitVersionCore/GitVersionCoreModule.cs +++ b/src/GitVersionCore/GitVersionCoreModule.cs @@ -50,6 +50,7 @@ public void RegisterTypes(IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(sp => sp.GetService().Create()); diff --git a/src/GitVersionCore/Model/AssemblyInfoData.cs b/src/GitVersionCore/Model/AssemblyInfoData.cs index ec886c0fa8..2fda58757a 100644 --- a/src/GitVersionCore/Model/AssemblyInfoData.cs +++ b/src/GitVersionCore/Model/AssemblyInfoData.cs @@ -4,6 +4,7 @@ namespace GitVersion { public class AssemblyInfoData { + public bool IsTargetingProjectFiles; public bool ShouldUpdate; public bool EnsureAssemblyInfo; public ISet Files = new HashSet(); diff --git a/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs b/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs index bef1316c34..dbf5a9ee92 100644 --- a/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs +++ b/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs @@ -177,7 +177,7 @@ private IEnumerable GetAssemblyInfoFiles(AssemblyInfoContext context) } else { - foreach (var item in fileSystem.DirectoryGetFiles(workingDirectory, "AssemblyInfo.*", SearchOption.AllDirectories)) + foreach (var item in fileSystem.DirectoryEnumerateFiles(workingDirectory, "AssemblyInfo.*", SearchOption.AllDirectories)) { var assemblyInfoFile = new FileInfo(item); diff --git a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs new file mode 100644 index 0000000000..05be8b46ca --- /dev/null +++ b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using GitVersion.Logging; +using GitVersion.OutputVariables; + +namespace GitVersion.VersionConverters.AssemblyInfo +{ + public interface IProjectFileUpdater : IVersionConverter + { + } + + public class ProjectFileUpdater: IProjectFileUpdater + { + internal const string AssemblyVersionElement = "AssemblyVersion"; + internal const string FileVersionElement = "FileVersion"; + internal const string InformationalVersionElement = "InformationalVersion"; + + private readonly List restoreBackupTasks = new List(); + private readonly List cleanupBackupTasks = new List(); + + private readonly IFileSystem fileSystem; + private readonly ILog log; + + public ProjectFileUpdater(ILog log, IFileSystem fileSystem) + { + this.fileSystem = fileSystem; + this.log = log; + } + + public void Execute(VersionVariables variables, AssemblyInfoContext context) + { + if (context.EnsureAssemblyInfo) + throw new WarningException($"Configuration setting {nameof(context.EnsureAssemblyInfo)} is not valid when updating .csproj files!"); + + var csProjFilesToUpdate = GetCsProjFiles(context).ToList(); + + var assemblyVersion = variables.AssemblySemVer; + var assemblyInfoVersion = variables.InformationalVersion; + var assemblyFileVersion = variables.AssemblySemFileVer; + + foreach (var csProjFile in csProjFilesToUpdate) + { + var localCsProjFile = csProjFile.FullName; + + var originalFileContents = fileSystem.ReadAllText(localCsProjFile); + var fileXml = XElement.Parse(originalFileContents); + + if (!CanUpdateProjectFile(fileXml)) + { + continue; + } + + var backupCsProjFile = localCsProjFile + ".bak"; + fileSystem.Copy(localCsProjFile, backupCsProjFile, true); + + restoreBackupTasks.Add(() => + { + if (fileSystem.Exists(localCsProjFile)) + { + fileSystem.Delete(localCsProjFile); + } + + fileSystem.Move(backupCsProjFile, localCsProjFile); + }); + + cleanupBackupTasks.Add(() => fileSystem.Delete(backupCsProjFile)); + + if (!string.IsNullOrWhiteSpace(assemblyVersion)) + { + UpdateProjectVersionElement(fileXml, AssemblyVersionElement, assemblyVersion); + } + + if (!string.IsNullOrWhiteSpace(assemblyFileVersion)) + { + UpdateProjectVersionElement(fileXml, FileVersionElement, assemblyFileVersion); + } + + if (!string.IsNullOrWhiteSpace(assemblyInfoVersion)) + { + UpdateProjectVersionElement(fileXml, InformationalVersionElement, assemblyInfoVersion); + } + + var outputXmlString = fileXml.ToString(); + if (originalFileContents != outputXmlString) + { + fileSystem.WriteAllText(localCsProjFile, outputXmlString); + } + } + + CommitChanges(); + } + + internal bool CanUpdateProjectFile(XElement csProjRoot) + { + if (csProjRoot.Name != "Project") + { + log.Warning($"Invalid project file specified, root element must be -- skipping"); + return false; + } + + var supportedSdk = "Microsoft.NET.Sdk"; + var sdkAttribute = csProjRoot.Attribute("Sdk"); + if (sdkAttribute == null || sdkAttribute.Value != supportedSdk) + { + log.Warning($"Specified project file Sdk ({sdkAttribute?.Value} is not supported, please ensure the project sdk is {supportedSdk} -- skipping"); + return false; + } + + var propertyGroups = csProjRoot.Descendants("PropertyGroup").ToList(); + if (!propertyGroups.Any()) + { + log.Warning("Unable to locate any elements in specified project file. Are you sure it is in a correct format? -- skipping"); + return false; + } + + var lastGenerateAssemblyInfoElement = propertyGroups.SelectMany(s => s.Elements("GenerateAssemblyInfo")).LastOrDefault(); + if (lastGenerateAssemblyInfoElement != null && (bool) lastGenerateAssemblyInfoElement == false) + { + log.Warning($"Project file specifies false: versions set in this project file will not affect the output artifacts -- skipping"); + return false; + } + + return true; + } + + internal void UpdateProjectVersionElement(XElement csProjRoot, string versionElement, string versionValue) + { + var propertyGroups = csProjRoot.Descendants("PropertyGroup").ToList(); + + var propertyGroupToModify = propertyGroups.LastOrDefault(l => l.Element(versionElement) != null) + ?? propertyGroups.First(); + + var versionXmlElement = propertyGroupToModify.Elements(versionElement).LastOrDefault(); + if (versionXmlElement != null) + { + versionXmlElement.Value = versionValue; + } + else + { + propertyGroupToModify.SetElementValue(versionElement, versionValue); + } + } + + public void Dispose() + { + foreach (var restoreBackup in restoreBackupTasks) + { + restoreBackup(); + } + + cleanupBackupTasks.Clear(); + restoreBackupTasks.Clear(); + } + + private void CommitChanges() + { + foreach (var cleanupBackupTask in cleanupBackupTasks) + { + cleanupBackupTask(); + } + + cleanupBackupTasks.Clear(); + restoreBackupTasks.Clear(); + } + + private IEnumerable GetCsProjFiles(AssemblyInfoContext context) + { + var workingDirectory = context.WorkingDirectory; + var assemblyInfoFileNames = new HashSet(context.AssemblyInfoFiles); + + if (assemblyInfoFileNames.Any(x => !string.IsNullOrWhiteSpace(x))) + { + foreach (var item in assemblyInfoFileNames) + { + var fullPath = Path.Combine(workingDirectory, item); + + if (fileSystem.Exists(fullPath)) + { + yield return new FileInfo(fullPath); + } + else + { + log.Warning($"Specified file {fullPath} was not found and will not be updated."); + } + } + } + else + { + foreach (var item in fileSystem.DirectoryEnumerateFiles(workingDirectory, "*", SearchOption.AllDirectories).Where(IsSupportedProjectFile)) + { + var assemblyInfoFile = new FileInfo(item); + + yield return assemblyInfoFile; + } + } + } + + private bool IsSupportedProjectFile(string fileName) + { + if (string.IsNullOrEmpty(fileName)) + { + return false; + } + + return fileName.EndsWith(".csproj") || + fileName.EndsWith(".fsproj") || + fileName.EndsWith(".vbproj"); + } + } +} diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 2c8c777222..444c97731a 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -236,6 +236,12 @@ private static bool ParseSwitches(Arguments arguments, string name, string[] val return true; } + if (name.IsSwitch("targetprojectfiles")) + { + arguments.TargetProjectFiles = true; + return true; + } + if (name.IsSwitch("nofetch")) { arguments.NoFetch = true; diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 9c9afd22f7..017dc923ba 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -38,6 +38,7 @@ public class Arguments public ISet Output = new HashSet(); public Verbosity Verbosity = Verbosity.Normal; + public bool TargetProjectFiles; public bool UpdateAssemblyInfo; public ISet UpdateAssemblyInfoFileName = new HashSet(); public bool EnsureAssemblyInfo; @@ -61,6 +62,7 @@ public GitVersionOptions ToOptions() AssemblyInfo = { + IsTargetingProjectFiles = TargetProjectFiles, ShouldUpdate = UpdateAssemblyInfo, EnsureAssemblyInfo = EnsureAssemblyInfo, Files = UpdateAssemblyInfoFileName From 0fc122d900cc9680d78786877c8581ead412e7d1 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 10 May 2020 04:42:14 -0400 Subject: [PATCH 02/13] Adds helptext --- src/GitVersionExe/HelpWriter.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 4dd030aa77..5069fd4543 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -53,6 +53,9 @@ path The directory containing .git. If not defined current directory # AssemblyInfo updating /updateassemblyinfo Will recursively search for all 'AssemblyInfo.cs' files in the git repo and update them + /targetprojectfiles + Will target project files (cs/fs/vbproj files) to update instead of AssemblyInfo class files, + Note: This is only compatible with the newer Sdk projects /updateassemblyinfofilename Specify name of AssemblyInfo file. Can also /updateAssemblyInfo GlobalAssemblyInfo.cs as a shorthand /ensureassemblyinfo From 90bef79a98c9d1dc9251ff15ae2946dafae7ebf1 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 10 May 2020 04:59:17 -0400 Subject: [PATCH 03/13] Updates var names and text to move away from only supporting csproj files --- .../AssemblyInfo/ProjectFileUpdater.cs | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs index 05be8b46ca..33afe94572 100644 --- a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs +++ b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs @@ -33,40 +33,41 @@ public ProjectFileUpdater(ILog log, IFileSystem fileSystem) public void Execute(VersionVariables variables, AssemblyInfoContext context) { if (context.EnsureAssemblyInfo) - throw new WarningException($"Configuration setting {nameof(context.EnsureAssemblyInfo)} is not valid when updating .csproj files!"); + throw new WarningException($"Configuration setting {nameof(context.EnsureAssemblyInfo)} is not valid when updating project files!"); - var csProjFilesToUpdate = GetCsProjFiles(context).ToList(); + var projectFilesToUpdate = GetProjectFiles(context).ToList(); var assemblyVersion = variables.AssemblySemVer; var assemblyInfoVersion = variables.InformationalVersion; var assemblyFileVersion = variables.AssemblySemFileVer; - foreach (var csProjFile in csProjFilesToUpdate) + foreach (var projectFile in projectFilesToUpdate) { - var localCsProjFile = csProjFile.FullName; + var localProjectFile = projectFile.FullName; - var originalFileContents = fileSystem.ReadAllText(localCsProjFile); + var originalFileContents = fileSystem.ReadAllText(localProjectFile); var fileXml = XElement.Parse(originalFileContents); if (!CanUpdateProjectFile(fileXml)) { + log.Warning($"Unable to update file: {localProjectFile}"); continue; } - var backupCsProjFile = localCsProjFile + ".bak"; - fileSystem.Copy(localCsProjFile, backupCsProjFile, true); + var backupProjectFile = localProjectFile + ".bak"; + fileSystem.Copy(localProjectFile, backupProjectFile, true); restoreBackupTasks.Add(() => { - if (fileSystem.Exists(localCsProjFile)) + if (fileSystem.Exists(localProjectFile)) { - fileSystem.Delete(localCsProjFile); + fileSystem.Delete(localProjectFile); } - fileSystem.Move(backupCsProjFile, localCsProjFile); + fileSystem.Move(backupProjectFile, localProjectFile); }); - cleanupBackupTasks.Add(() => fileSystem.Delete(backupCsProjFile)); + cleanupBackupTasks.Add(() => fileSystem.Delete(backupProjectFile)); if (!string.IsNullOrWhiteSpace(assemblyVersion)) { @@ -86,49 +87,49 @@ public void Execute(VersionVariables variables, AssemblyInfoContext context) var outputXmlString = fileXml.ToString(); if (originalFileContents != outputXmlString) { - fileSystem.WriteAllText(localCsProjFile, outputXmlString); + fileSystem.WriteAllText(localProjectFile, outputXmlString); } } CommitChanges(); } - internal bool CanUpdateProjectFile(XElement csProjRoot) + internal bool CanUpdateProjectFile(XElement xmlRoot) { - if (csProjRoot.Name != "Project") + if (xmlRoot.Name != "Project") { - log.Warning($"Invalid project file specified, root element must be -- skipping"); + log.Warning($"Invalid project file specified, root element must be ."); return false; } var supportedSdk = "Microsoft.NET.Sdk"; - var sdkAttribute = csProjRoot.Attribute("Sdk"); + var sdkAttribute = xmlRoot.Attribute("Sdk"); if (sdkAttribute == null || sdkAttribute.Value != supportedSdk) { - log.Warning($"Specified project file Sdk ({sdkAttribute?.Value} is not supported, please ensure the project sdk is {supportedSdk} -- skipping"); + log.Warning($"Specified project file Sdk ({sdkAttribute?.Value}) is not supported, please ensure the project sdk is {supportedSdk}."); return false; } - var propertyGroups = csProjRoot.Descendants("PropertyGroup").ToList(); + var propertyGroups = xmlRoot.Descendants("PropertyGroup").ToList(); if (!propertyGroups.Any()) { - log.Warning("Unable to locate any elements in specified project file. Are you sure it is in a correct format? -- skipping"); + log.Warning("Unable to locate any elements in specified project file. Are you sure it is in a correct format?"); return false; } var lastGenerateAssemblyInfoElement = propertyGroups.SelectMany(s => s.Elements("GenerateAssemblyInfo")).LastOrDefault(); if (lastGenerateAssemblyInfoElement != null && (bool) lastGenerateAssemblyInfoElement == false) { - log.Warning($"Project file specifies false: versions set in this project file will not affect the output artifacts -- skipping"); + log.Warning($"Project file specifies false: versions set in this project file will not affect the output artifacts."); return false; } return true; } - internal void UpdateProjectVersionElement(XElement csProjRoot, string versionElement, string versionValue) + internal void UpdateProjectVersionElement(XElement xmlRoot, string versionElement, string versionValue) { - var propertyGroups = csProjRoot.Descendants("PropertyGroup").ToList(); + var propertyGroups = xmlRoot.Descendants("PropertyGroup").ToList(); var propertyGroupToModify = propertyGroups.LastOrDefault(l => l.Element(versionElement) != null) ?? propertyGroups.First(); @@ -166,7 +167,7 @@ private void CommitChanges() restoreBackupTasks.Clear(); } - private IEnumerable GetCsProjFiles(AssemblyInfoContext context) + private IEnumerable GetProjectFiles(AssemblyInfoContext context) { var workingDirectory = context.WorkingDirectory; var assemblyInfoFileNames = new HashSet(context.AssemblyInfoFiles); From 6455b82338225e6b8b049ed1f1f380874eca4e42 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 10 May 2020 05:09:59 -0400 Subject: [PATCH 04/13] Fixes whitespacing issues --- .../VersionConverters/AssemblyInfo/ProjectFileUpdater.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs index 33afe94572..aeeada4abd 100644 --- a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs +++ b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs @@ -12,7 +12,7 @@ public interface IProjectFileUpdater : IVersionConverter { } - public class ProjectFileUpdater: IProjectFileUpdater + public class ProjectFileUpdater: IProjectFileUpdater { internal const string AssemblyVersionElement = "AssemblyVersion"; internal const string FileVersionElement = "FileVersion"; @@ -118,7 +118,7 @@ internal bool CanUpdateProjectFile(XElement xmlRoot) } var lastGenerateAssemblyInfoElement = propertyGroups.SelectMany(s => s.Elements("GenerateAssemblyInfo")).LastOrDefault(); - if (lastGenerateAssemblyInfoElement != null && (bool) lastGenerateAssemblyInfoElement == false) + if (lastGenerateAssemblyInfoElement != null && (bool)lastGenerateAssemblyInfoElement == false) { log.Warning($"Project file specifies false: versions set in this project file will not affect the output artifacts."); return false; From d3fb557716f11deced2abeeeac0a89dcabf42dc0 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 10 May 2020 05:11:48 -0400 Subject: [PATCH 05/13] Whitespace round2 --- .../VersionConverters/AssemblyInfo/ProjectFileUpdater.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs index aeeada4abd..84a9224ff7 100644 --- a/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs +++ b/src/GitVersionCore/VersionConverters/AssemblyInfo/ProjectFileUpdater.cs @@ -12,7 +12,7 @@ public interface IProjectFileUpdater : IVersionConverter { } - public class ProjectFileUpdater: IProjectFileUpdater + public class ProjectFileUpdater : IProjectFileUpdater { internal const string AssemblyVersionElement = "AssemblyVersion"; internal const string FileVersionElement = "FileVersion"; From 0b647ded2bd7a93b9b26312dae76c1ab96b6d3ce Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 10 May 2020 17:48:48 -0400 Subject: [PATCH 06/13] Renames switch to /updateprojectfiles --- src/GitVersionExe/ArgumentParser.cs | 4 ++-- src/GitVersionExe/Arguments.cs | 4 ++-- src/GitVersionExe/HelpWriter.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 444c97731a..f413a84c17 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -236,9 +236,9 @@ private static bool ParseSwitches(Arguments arguments, string name, string[] val return true; } - if (name.IsSwitch("targetprojectfiles")) + if (name.IsSwitch("updateprojectfiles")) { - arguments.TargetProjectFiles = true; + arguments.UpdateProjectFiles = true; return true; } diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 017dc923ba..94d8a22575 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -38,7 +38,7 @@ public class Arguments public ISet Output = new HashSet(); public Verbosity Verbosity = Verbosity.Normal; - public bool TargetProjectFiles; + public bool UpdateProjectFiles; public bool UpdateAssemblyInfo; public ISet UpdateAssemblyInfoFileName = new HashSet(); public bool EnsureAssemblyInfo; @@ -62,7 +62,7 @@ public GitVersionOptions ToOptions() AssemblyInfo = { - IsTargetingProjectFiles = TargetProjectFiles, + IsTargetingProjectFiles = UpdateProjectFiles, ShouldUpdate = UpdateAssemblyInfo, EnsureAssemblyInfo = EnsureAssemblyInfo, Files = UpdateAssemblyInfoFileName diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 5069fd4543..3e4d374afc 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -53,7 +53,7 @@ path The directory containing .git. If not defined current directory # AssemblyInfo updating /updateassemblyinfo Will recursively search for all 'AssemblyInfo.cs' files in the git repo and update them - /targetprojectfiles + /updateprojectfiles Will target project files (cs/fs/vbproj files) to update instead of AssemblyInfo class files, Note: This is only compatible with the newer Sdk projects /updateassemblyinfofilename From bcd2eb9f555469f7a15beb250a39380f987e9299 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 11 May 2020 14:36:22 -0400 Subject: [PATCH 07/13] Allows execution of updating project files without updating AssemblyInfo files --- src/GitVersionCore/Core/GitVersionTool.cs | 21 +++--- src/GitVersionCore/Model/AssemblyInfoData.cs | 4 +- .../ArgumentParserTests.cs | 22 +++--- src/GitVersionExe/ArgumentParser.cs | 67 ++++++++++++++++--- src/GitVersionExe/Arguments.cs | 8 +-- src/GitVersionExe/HelpWriter.cs | 8 ++- src/GitVersionTask/GitVersionTaskExecutor.cs | 2 +- 7 files changed, 87 insertions(+), 45 deletions(-) diff --git a/src/GitVersionCore/Core/GitVersionTool.cs b/src/GitVersionCore/Core/GitVersionTool.cs index 4786d9a577..90dc23a310 100644 --- a/src/GitVersionCore/Core/GitVersionTool.cs +++ b/src/GitVersionCore/Core/GitVersionTool.cs @@ -4,7 +4,6 @@ using GitVersion.OutputVariables; using GitVersion.VersionCalculation; using GitVersion.VersionCalculation.Cache; -using GitVersion.VersionConverters; using GitVersion.VersionConverters.AssemblyInfo; using GitVersion.VersionConverters.GitVersionInfo; using GitVersion.VersionConverters.OutputGenerator; @@ -95,23 +94,19 @@ public void OutputVariables(VersionVariables variables) public void UpdateAssemblyInfo(VersionVariables variables) { var gitVersionOptions = options.Value; + var assemblyInfoContext = new AssemblyInfoContext(gitVersionOptions.WorkingDirectory, gitVersionOptions.AssemblyInfo.EnsureAssemblyInfo, gitVersionOptions.AssemblyInfo.Files.ToArray()); - if (gitVersionOptions.AssemblyInfo.ShouldUpdate) + if (gitVersionOptions.AssemblyInfo.UpdateProjectFiles) { - var assemblyInfoContext = new AssemblyInfoContext(gitVersionOptions.WorkingDirectory, gitVersionOptions.AssemblyInfo.EnsureAssemblyInfo, gitVersionOptions.AssemblyInfo.Files.ToArray()); - if (gitVersionOptions.AssemblyInfo.IsTargetingProjectFiles) + using (projectFileUpdater) { - using (projectFileUpdater) - { - projectFileUpdater.Execute(variables, assemblyInfoContext); - } + projectFileUpdater.Execute(variables, assemblyInfoContext); } - else + } else if (gitVersionOptions.AssemblyInfo.UpdateAssemblyInfo) + { + using (assemblyInfoFileUpdater) { - using (assemblyInfoFileUpdater) - { - assemblyInfoFileUpdater.Execute(variables, assemblyInfoContext); - } + assemblyInfoFileUpdater.Execute(variables, assemblyInfoContext); } } } diff --git a/src/GitVersionCore/Model/AssemblyInfoData.cs b/src/GitVersionCore/Model/AssemblyInfoData.cs index 2fda58757a..36d6f23552 100644 --- a/src/GitVersionCore/Model/AssemblyInfoData.cs +++ b/src/GitVersionCore/Model/AssemblyInfoData.cs @@ -4,8 +4,8 @@ namespace GitVersion { public class AssemblyInfoData { - public bool IsTargetingProjectFiles; - public bool ShouldUpdate; + public bool UpdateAssemblyInfo; + public bool UpdateProjectFiles; public bool EnsureAssemblyInfo; public ISet Files = new HashSet(); } diff --git a/src/GitVersionExe.Tests/ArgumentParserTests.cs b/src/GitVersionExe.Tests/ArgumentParserTests.cs index 9891f57e35..52a00fc84e 100644 --- a/src/GitVersionExe.Tests/ArgumentParserTests.cs +++ b/src/GitVersionExe.Tests/ArgumentParserTests.cs @@ -320,8 +320,8 @@ public void UpdateAssemblyInfoWithFilename() var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo CommonAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(1); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateFileNames.Count.ShouldBe(1); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); } [Test] @@ -337,9 +337,9 @@ public void UpdateAssemblyInfoWithMultipleFilenames() var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo CommonAssemblyInfo.cs VersionAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(2); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); + arguments.UpdateFileNames.Count.ShouldBe(2); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); } [Test] @@ -360,10 +360,10 @@ public void UpdateAssemblyInfoWithMultipleFilenamesMatchingGlobbing() var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo **/*AssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(3); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("LocalAssemblyInfo.cs")); + arguments.UpdateFileNames.Count.ShouldBe(3); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("LocalAssemblyInfo.cs")); } [Test] @@ -379,8 +379,8 @@ public void UpdateAssemblyInfoWithRelativeFilename() var arguments = argumentParser.ParseArguments($"-targetpath {targetPath} -updateAssemblyInfo ..\\..\\CommonAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(1); - arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateFileNames.Count.ShouldBe(1); + arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); } [Test] diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index f413a84c17..5534c33a7d 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -104,7 +104,7 @@ public Arguments ParseArguments(string[] commandLineArguments) : firstArgument; arguments.TargetPath = arguments.TargetPath.TrimEnd('/', '\\'); - arguments.UpdateAssemblyInfoFileName = ResolveFiles(arguments.TargetPath, arguments.UpdateAssemblyInfoFileName).ToHashSet(); + arguments.UpdateFileNames = ResolveFiles(arguments.TargetPath, arguments.UpdateFileNames).ToHashSet(); arguments.NoFetch = arguments.NoFetch || buildAgent != null && buildAgent.PreventFetch(); return arguments; @@ -205,6 +205,12 @@ private static bool ParseSwitches(Arguments arguments, string name, string[] val if (ParseExecArguments(arguments, name, values, value)) return true; + if (name.IsSwitch("updateprojectfiles")) + { + ParseUpdateProjectInfo(arguments, value, values); + return true; + } + if (name.IsSwitch("updateAssemblyInfo")) { ParseUpdateAssemblyInfo(arguments, value, values); @@ -236,12 +242,6 @@ private static bool ParseSwitches(Arguments arguments, string name, string[] val return true; } - if (name.IsSwitch("updateprojectfiles")) - { - arguments.UpdateProjectFiles = true; - return true; - } - if (name.IsSwitch("nofetch")) { arguments.NoFetch = true; @@ -424,7 +424,7 @@ private static void ParseEnsureAssemblyInfo(Arguments arguments, string value) arguments.EnsureAssemblyInfo = false; } - if (arguments.UpdateAssemblyInfoFileName.Count > 1 && arguments.EnsureAssemblyInfo) + if (arguments.UpdateFileNames.Count > 1 && arguments.EnsureAssemblyInfo) { throw new WarningException("Can't specify multiple assembly info files when using /ensureassemblyinfo switch, either use a single assembly info file or do not specify /ensureassemblyinfo and create assembly info files manually"); } @@ -504,7 +504,7 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s arguments.UpdateAssemblyInfo = true; foreach (var v in values) { - arguments.UpdateAssemblyInfoFileName.Add(v); + arguments.UpdateFileNames.Add(v); } } else if (!value.IsSwitchArgument()) @@ -512,7 +512,7 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s arguments.UpdateAssemblyInfo = true; if (value != null) { - arguments.UpdateAssemblyInfoFileName.Add(value); + arguments.UpdateFileNames.Add(value); } } else @@ -520,12 +520,57 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s arguments.UpdateAssemblyInfo = true; } - if (arguments.UpdateAssemblyInfoFileName.Count > 1 && arguments.EnsureAssemblyInfo) + if (arguments.UpdateProjectFiles) + { + throw new WarningException("Cannot specify both updateprojectfiles and updateassemblyinfo in the same run. Please rerun GitVersion with only one parameter"); + } + if (arguments.UpdateFileNames.Count > 1 && arguments.EnsureAssemblyInfo) { throw new WarningException("Can't specify multiple assembly info files when using -ensureassemblyinfo switch, either use a single assembly info file or do not specify -ensureassemblyinfo and create assembly info files manually"); } } + private static void ParseUpdateProjectInfo(Arguments arguments, string value, string[] values) + { + if (value.IsTrue()) + { + arguments.UpdateProjectFiles = true; + } + else if (value.IsFalse()) + { + arguments.UpdateProjectFiles = false; + } + else if (values != null && values.Length > 1) + { + arguments.UpdateProjectFiles = true; + foreach (var v in values) + { + arguments.UpdateFileNames.Add(v); + } + } + else if (!value.IsSwitchArgument()) + { + arguments.UpdateProjectFiles = true; + if (value != null) + { + arguments.UpdateFileNames.Add(value); + } + } + else + { + arguments.UpdateProjectFiles = true; + } + + if (arguments.UpdateAssemblyInfo) + { + throw new WarningException("Cannot specify both updateassemblyinfo and updateprojectfiles in the same run. Please rerun GitVersion with only one parameter"); + } + if (arguments.EnsureAssemblyInfo) + { + throw new WarningException("Cannot specify -ensureassemblyinfo with updateprojectfiles: please ensure your project file exists before attempting to update it"); + } + } + private static void EnsureArgumentValueCount(IReadOnlyList values) { if (values != null && values.Count > 1) diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 94d8a22575..9d93a23afd 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -40,8 +40,8 @@ public class Arguments public bool UpdateProjectFiles; public bool UpdateAssemblyInfo; - public ISet UpdateAssemblyInfoFileName = new HashSet(); public bool EnsureAssemblyInfo; + public ISet UpdateFileNames = new HashSet(); [Obsolete] public string Proj; @@ -62,10 +62,10 @@ public GitVersionOptions ToOptions() AssemblyInfo = { - IsTargetingProjectFiles = UpdateProjectFiles, - ShouldUpdate = UpdateAssemblyInfo, + UpdateProjectFiles = UpdateProjectFiles, + UpdateAssemblyInfo = UpdateAssemblyInfo, EnsureAssemblyInfo = EnsureAssemblyInfo, - Files = UpdateAssemblyInfoFileName + Files = UpdateFileNames }, Authentication = diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 3e4d374afc..f48db23dab 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -54,10 +54,12 @@ path The directory containing .git. If not defined current directory /updateassemblyinfo Will recursively search for all 'AssemblyInfo.cs' files in the git repo and update them /updateprojectfiles - Will target project files (cs/fs/vbproj files) to update instead of AssemblyInfo class files, + Will recursively search for all project files (.csproj/.vbproj/.fsproj) files in the git repo and update them Note: This is only compatible with the newer Sdk projects - /updateassemblyinfofilename - Specify name of AssemblyInfo file. Can also /updateAssemblyInfo GlobalAssemblyInfo.cs as a shorthand + /updatefilenames + Specify name(s) of files to update. If updating assemblyinfo these should be AssemblyInfo class files, + otherwise these should be your xml project files. + Note: Can also /updateAssemblyInfo GlobalAssemblyInfo.cs as a shorthand /ensureassemblyinfo If the assembly info file specified with /updateassemblyinfo or /updateassemblyinfofilename is not found, it be created with these attributes: AssemblyFileVersion, AssemblyVersion and AssemblyInformationalVersion diff --git a/src/GitVersionTask/GitVersionTaskExecutor.cs b/src/GitVersionTask/GitVersionTaskExecutor.cs index fec45bb227..bc28131aad 100644 --- a/src/GitVersionTask/GitVersionTaskExecutor.cs +++ b/src/GitVersionTask/GitVersionTaskExecutor.cs @@ -37,7 +37,7 @@ public void UpdateAssemblyInfo(UpdateAssemblyInfo task) task.AssemblyInfoTempFilePath = Path.Combine(fileWriteInfo.WorkingDirectory, fileWriteInfo.FileName); var gitVersionOptions = options.Value; - gitVersionOptions.AssemblyInfo.ShouldUpdate = true; + gitVersionOptions.AssemblyInfo.UpdateAssemblyInfo = true; gitVersionOptions.AssemblyInfo.EnsureAssemblyInfo = true; gitVersionOptions.WorkingDirectory = fileWriteInfo.WorkingDirectory; gitVersionOptions.AssemblyInfo.Files.Add(fileWriteInfo.FileName); From 53dcbb7dd6f2c350231b48d45d7ca6526185fa5a Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 11 May 2020 14:38:34 -0400 Subject: [PATCH 08/13] Fixes whitespace issue --- src/GitVersionCore/Core/GitVersionTool.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/GitVersionCore/Core/GitVersionTool.cs b/src/GitVersionCore/Core/GitVersionTool.cs index 90dc23a310..1a5cdc0dcc 100644 --- a/src/GitVersionCore/Core/GitVersionTool.cs +++ b/src/GitVersionCore/Core/GitVersionTool.cs @@ -102,7 +102,8 @@ public void UpdateAssemblyInfo(VersionVariables variables) { projectFileUpdater.Execute(variables, assemblyInfoContext); } - } else if (gitVersionOptions.AssemblyInfo.UpdateAssemblyInfo) + } + else if (gitVersionOptions.AssemblyInfo.UpdateAssemblyInfo) { using (assemblyInfoFileUpdater) { From ab73019262f03192d5f59f6d0aa5832ac58d8eeb Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 11 May 2020 19:01:44 -0400 Subject: [PATCH 09/13] Revert helptext and add text specific for updating the project filenames --- src/GitVersionExe/HelpWriter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index f48db23dab..17e2844206 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -56,10 +56,10 @@ path The directory containing .git. If not defined current directory /updateprojectfiles Will recursively search for all project files (.csproj/.vbproj/.fsproj) files in the git repo and update them Note: This is only compatible with the newer Sdk projects - /updatefilenames - Specify name(s) of files to update. If updating assemblyinfo these should be AssemblyInfo class files, - otherwise these should be your xml project files. - Note: Can also /updateAssemblyInfo GlobalAssemblyInfo.cs as a shorthand + /updateassemblyinfofilename + Specify name of AssemblyInfo file. Can also /updateAssemblyInfo GlobalAssemblyInfo.cs as a shorthand + /updateprojectfilename + Specify name of Project file. Can also /updateProjectInfo Project.csproj as a shorthand /ensureassemblyinfo If the assembly info file specified with /updateassemblyinfo or /updateassemblyinfofilename is not found, it be created with these attributes: AssemblyFileVersion, AssemblyVersion and AssemblyInformationalVersion From efebd6a187a18e67754500dc03f1eecb50642372 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 11 May 2020 19:13:21 -0400 Subject: [PATCH 10/13] Removes project-file-name parameter --- src/GitVersionExe/HelpWriter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 17e2844206..5a85eafa91 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -58,8 +58,6 @@ path The directory containing .git. If not defined current directory Note: This is only compatible with the newer Sdk projects /updateassemblyinfofilename Specify name of AssemblyInfo file. Can also /updateAssemblyInfo GlobalAssemblyInfo.cs as a shorthand - /updateprojectfilename - Specify name of Project file. Can also /updateProjectInfo Project.csproj as a shorthand /ensureassemblyinfo If the assembly info file specified with /updateassemblyinfo or /updateassemblyinfofilename is not found, it be created with these attributes: AssemblyFileVersion, AssemblyVersion and AssemblyInformationalVersion From 7b04224540caf5f1d8c00a2b8b381909913eafd8 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 11 May 2020 19:19:02 -0400 Subject: [PATCH 11/13] Fixes parameter name in Arguments class --- .../ArgumentParserTests.cs | 22 +++++++++---------- src/GitVersionExe/ArgumentParser.cs | 14 ++++++------ src/GitVersionExe/Arguments.cs | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/GitVersionExe.Tests/ArgumentParserTests.cs b/src/GitVersionExe.Tests/ArgumentParserTests.cs index 52a00fc84e..9891f57e35 100644 --- a/src/GitVersionExe.Tests/ArgumentParserTests.cs +++ b/src/GitVersionExe.Tests/ArgumentParserTests.cs @@ -320,8 +320,8 @@ public void UpdateAssemblyInfoWithFilename() var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo CommonAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateFileNames.Count.ShouldBe(1); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(1); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); } [Test] @@ -337,9 +337,9 @@ public void UpdateAssemblyInfoWithMultipleFilenames() var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo CommonAssemblyInfo.cs VersionAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateFileNames.Count.ShouldBe(2); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(2); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); } [Test] @@ -360,10 +360,10 @@ public void UpdateAssemblyInfoWithMultipleFilenamesMatchingGlobbing() var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo **/*AssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateFileNames.Count.ShouldBe(3); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("LocalAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(3); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("LocalAssemblyInfo.cs")); } [Test] @@ -379,8 +379,8 @@ public void UpdateAssemblyInfoWithRelativeFilename() var arguments = argumentParser.ParseArguments($"-targetpath {targetPath} -updateAssemblyInfo ..\\..\\CommonAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateFileNames.Count.ShouldBe(1); - arguments.UpdateFileNames.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(1); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); } [Test] diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 5534c33a7d..3bef9f254e 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -104,7 +104,7 @@ public Arguments ParseArguments(string[] commandLineArguments) : firstArgument; arguments.TargetPath = arguments.TargetPath.TrimEnd('/', '\\'); - arguments.UpdateFileNames = ResolveFiles(arguments.TargetPath, arguments.UpdateFileNames).ToHashSet(); + arguments.UpdateAssemblyInfoFileName = ResolveFiles(arguments.TargetPath, arguments.UpdateAssemblyInfoFileName).ToHashSet(); arguments.NoFetch = arguments.NoFetch || buildAgent != null && buildAgent.PreventFetch(); return arguments; @@ -424,7 +424,7 @@ private static void ParseEnsureAssemblyInfo(Arguments arguments, string value) arguments.EnsureAssemblyInfo = false; } - if (arguments.UpdateFileNames.Count > 1 && arguments.EnsureAssemblyInfo) + if (arguments.UpdateAssemblyInfoFileName.Count > 1 && arguments.EnsureAssemblyInfo) { throw new WarningException("Can't specify multiple assembly info files when using /ensureassemblyinfo switch, either use a single assembly info file or do not specify /ensureassemblyinfo and create assembly info files manually"); } @@ -504,7 +504,7 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s arguments.UpdateAssemblyInfo = true; foreach (var v in values) { - arguments.UpdateFileNames.Add(v); + arguments.UpdateAssemblyInfoFileName.Add(v); } } else if (!value.IsSwitchArgument()) @@ -512,7 +512,7 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s arguments.UpdateAssemblyInfo = true; if (value != null) { - arguments.UpdateFileNames.Add(value); + arguments.UpdateAssemblyInfoFileName.Add(value); } } else @@ -524,7 +524,7 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s { throw new WarningException("Cannot specify both updateprojectfiles and updateassemblyinfo in the same run. Please rerun GitVersion with only one parameter"); } - if (arguments.UpdateFileNames.Count > 1 && arguments.EnsureAssemblyInfo) + if (arguments.UpdateAssemblyInfoFileName.Count > 1 && arguments.EnsureAssemblyInfo) { throw new WarningException("Can't specify multiple assembly info files when using -ensureassemblyinfo switch, either use a single assembly info file or do not specify -ensureassemblyinfo and create assembly info files manually"); } @@ -545,7 +545,7 @@ private static void ParseUpdateProjectInfo(Arguments arguments, string value, st arguments.UpdateProjectFiles = true; foreach (var v in values) { - arguments.UpdateFileNames.Add(v); + arguments.UpdateAssemblyInfoFileName.Add(v); } } else if (!value.IsSwitchArgument()) @@ -553,7 +553,7 @@ private static void ParseUpdateProjectInfo(Arguments arguments, string value, st arguments.UpdateProjectFiles = true; if (value != null) { - arguments.UpdateFileNames.Add(value); + arguments.UpdateAssemblyInfoFileName.Add(value); } } else diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 9d93a23afd..b225d08426 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -41,7 +41,7 @@ public class Arguments public bool UpdateProjectFiles; public bool UpdateAssemblyInfo; public bool EnsureAssemblyInfo; - public ISet UpdateFileNames = new HashSet(); + public ISet UpdateAssemblyInfoFileName = new HashSet(); [Obsolete] public string Proj; @@ -65,7 +65,7 @@ public GitVersionOptions ToOptions() UpdateProjectFiles = UpdateProjectFiles, UpdateAssemblyInfo = UpdateAssemblyInfo, EnsureAssemblyInfo = EnsureAssemblyInfo, - Files = UpdateFileNames + Files = UpdateAssemblyInfoFileName }, Authentication = From 67f7f2901a3fc902d70d1ec947360a7ba4d6cbfe Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 12 May 2020 18:46:06 -0400 Subject: [PATCH 12/13] Adds tests to cover parsing project parameters --- .../ArgumentParserTests.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/GitVersionExe.Tests/ArgumentParserTests.cs b/src/GitVersionExe.Tests/ArgumentParserTests.cs index 9891f57e35..40dd317592 100644 --- a/src/GitVersionExe.Tests/ArgumentParserTests.cs +++ b/src/GitVersionExe.Tests/ArgumentParserTests.cs @@ -295,6 +295,16 @@ public void UpdateAssemblyInfoTrue(string command) arguments.UpdateAssemblyInfo.ShouldBe(true); } + [TestCase("-updateProjectFiles assemblyInfo.csproj")] + [TestCase("-updateProjectFiles assemblyInfo.csproj")] + [TestCase("-updateProjectFiles assemblyInfo.csproj otherAssemblyInfo.fsproj")] + [TestCase("-updateProjectFiles")] + public void UpdateProjectTrue(string command) + { + var arguments = argumentParser.ParseArguments(command); + arguments.UpdateProjectFiles.ShouldBe(true); + } + [TestCase("-updateAssemblyInfo false")] [TestCase("-updateAssemblyInfo 0")] public void UpdateAssemblyInfoFalse(string command) @@ -310,6 +320,13 @@ public void CreateMulitpleAssemblyInfoProtected(string command) exception.Message.ShouldBe("Can't specify multiple assembly info files when using /ensureassemblyinfo switch, either use a single assembly info file or do not specify /ensureassemblyinfo and create assembly info files manually"); } + [TestCase("-updateProjectFiles Assembly.csproj Assembly1.csproj -ensureassemblyinfo")] + public void UpdateProjectInfoWithEnsureAssemblyInfoProtected(string command) + { + var exception = Assert.Throws(() => argumentParser.ParseArguments(command)); + exception.Message.ShouldBe("Cannot specify -ensureassemblyinfo with updateprojectfiles: please ensure your project file exists before attempting to update it"); + } + [Test] public void UpdateAssemblyInfoWithFilename() { @@ -342,6 +359,24 @@ public void UpdateAssemblyInfoWithMultipleFilenames() arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); } + [Test] + public void UpdateProjectFilesWithMultipleFilenames() + { + using var repo = new EmptyRepositoryFixture(); + + var assemblyFile1 = Path.Combine(repo.RepositoryPath, "CommonAssemblyInfo.csproj"); + using var file = File.Create(assemblyFile1); + + var assemblyFile2 = Path.Combine(repo.RepositoryPath, "VersionAssemblyInfo.csproj"); + using var file2 = File.Create(assemblyFile2); + + var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateProjectFiles CommonAssemblyInfo.csproj VersionAssemblyInfo.csproj"); + arguments.UpdateProjectFiles.ShouldBe(true); + arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(2); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.csproj")); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.csproj")); + } + [Test] public void UpdateAssemblyInfoWithMultipleFilenamesMatchingGlobbing() { From 66faf2cc6130a67c709d038842658bdb4f0de686 Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 12 May 2020 18:54:10 -0400 Subject: [PATCH 13/13] Fixes broken unit test --- src/GitVersionExe.Tests/ArgumentParserTests.cs | 2 +- src/GitVersionExe/ArgumentParser.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/GitVersionExe.Tests/ArgumentParserTests.cs b/src/GitVersionExe.Tests/ArgumentParserTests.cs index 40dd317592..3e3d2836df 100644 --- a/src/GitVersionExe.Tests/ArgumentParserTests.cs +++ b/src/GitVersionExe.Tests/ArgumentParserTests.cs @@ -320,7 +320,7 @@ public void CreateMulitpleAssemblyInfoProtected(string command) exception.Message.ShouldBe("Can't specify multiple assembly info files when using /ensureassemblyinfo switch, either use a single assembly info file or do not specify /ensureassemblyinfo and create assembly info files manually"); } - [TestCase("-updateProjectFiles Assembly.csproj Assembly1.csproj -ensureassemblyinfo")] + [TestCase("-updateProjectFiles Assembly.csproj -ensureassemblyinfo")] public void UpdateProjectInfoWithEnsureAssemblyInfoProtected(string command) { var exception = Assert.Throws(() => argumentParser.ParseArguments(command)); diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 3bef9f254e..c420152f0e 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -424,6 +424,11 @@ private static void ParseEnsureAssemblyInfo(Arguments arguments, string value) arguments.EnsureAssemblyInfo = false; } + if (arguments.UpdateProjectFiles) + { + throw new WarningException("Cannot specify -ensureassemblyinfo with updateprojectfiles: please ensure your project file exists before attempting to update it"); + } + if (arguments.UpdateAssemblyInfoFileName.Count > 1 && arguments.EnsureAssemblyInfo) { throw new WarningException("Can't specify multiple assembly info files when using /ensureassemblyinfo switch, either use a single assembly info file or do not specify /ensureassemblyinfo and create assembly info files manually");