diff --git a/src/GitVersionCore/Model/AssemblyInfo.cs b/src/GitVersionCore/Model/AssemblyInfoData.cs similarity index 85% rename from src/GitVersionCore/Model/AssemblyInfo.cs rename to src/GitVersionCore/Model/AssemblyInfoData.cs index f32470ec5f..ec886c0fa8 100644 --- a/src/GitVersionCore/Model/AssemblyInfo.cs +++ b/src/GitVersionCore/Model/AssemblyInfoData.cs @@ -2,7 +2,7 @@ namespace GitVersion { - public class AssemblyInfo + public class AssemblyInfoData { public bool ShouldUpdate; public bool EnsureAssemblyInfo; diff --git a/src/GitVersionCore/Model/GitVersionOptions.cs b/src/GitVersionCore/Model/GitVersionOptions.cs index aa9bf12ab3..4e616b3101 100644 --- a/src/GitVersionCore/Model/GitVersionOptions.cs +++ b/src/GitVersionCore/Model/GitVersionOptions.cs @@ -25,7 +25,7 @@ public GitVersionOptions() public string ProjectRootDirectory => projectRootDirectory.Value; public string DynamicGitRepositoryPath => dynamicGitRepositoryPath.Value; - public AssemblyInfo AssemblyInfo { get; } = new AssemblyInfo(); + public AssemblyInfoData AssemblyInfo { get; } = new AssemblyInfoData(); public AuthenticationInfo Authentication { get; } = new AuthenticationInfo(); public ConfigInfo ConfigInfo { get; } = new ConfigInfo(); public RepositoryInfo RepositoryInfo { get; } = new RepositoryInfo(); diff --git a/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs b/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs index 78e667b7e6..bef1316c34 100644 --- a/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs +++ b/src/GitVersionCore/VersionConverters/AssemblyInfo/AssemblyInfoFileUpdater.cs @@ -43,10 +43,8 @@ public AssemblyInfoFileUpdater(ILog log, IFileSystem fileSystem) public void Execute(VersionVariables variables, AssemblyInfoContext context) { - var assemblyInfoFileNames = new HashSet(context.AssemblyInfoFiles); + var assemblyInfoFiles = GetAssemblyInfoFiles(context).ToList(); log.Info("Updating assembly info files"); - - var assemblyInfoFiles = GetAssemblyInfoFiles(context.WorkingDirectory, assemblyInfoFileNames, context.EnsureAssemblyInfo).ToList(); log.Info($"Found {assemblyInfoFiles.Count} files"); var assemblyVersion = variables.AssemblySemVer; @@ -159,9 +157,13 @@ private string ReplaceOrInsertAfterLastAssemblyAttributeOrAppend(Regex replaceRe return inputString; } - private IEnumerable GetAssemblyInfoFiles(string workingDirectory, ISet assemblyInfoFileNames, bool ensureAssemblyInfo) + private IEnumerable GetAssemblyInfoFiles(AssemblyInfoContext context) { - if (assemblyInfoFileNames != null && assemblyInfoFileNames.Any(x => !string.IsNullOrWhiteSpace(x))) + var workingDirectory = context.WorkingDirectory; + var ensureAssemblyInfo = context.EnsureAssemblyInfo; + var assemblyInfoFileNames = new HashSet(context.AssemblyInfoFiles); + + if (assemblyInfoFileNames.Any(x => !string.IsNullOrWhiteSpace(x))) { foreach (var item in assemblyInfoFileNames) { diff --git a/src/GitVersionExe.Tests/ArgumentParserTests.cs b/src/GitVersionExe.Tests/ArgumentParserTests.cs index ed8cf1e93c..82ed95fe67 100644 --- a/src/GitVersionExe.Tests/ArgumentParserTests.cs +++ b/src/GitVersionExe.Tests/ArgumentParserTests.cs @@ -1,3 +1,5 @@ +using System.IO; +using GitTools.Testing; using GitVersion; using GitVersion.Logging; using GitVersion.Model; @@ -20,6 +22,7 @@ public void SetUp() var sp = ConfigureServices(services => { services.AddSingleton(); + services.AddSingleton(); }); argumentParser = sp.GetService(); } @@ -257,19 +260,74 @@ public void CreateMulitpleAssemblyInfoProtected(string command) [Test] public void UpdateAssemblyInfoWithFilename() { - var arguments = argumentParser.ParseArguments("-updateAssemblyInfo CommonAssemblyInfo.cs"); + using var repo = new EmptyRepositoryFixture(); + + var assemblyFile = Path.Combine(repo.RepositoryPath, "CommonAssemblyInfo.cs"); + using var file = File.Create(assemblyFile); + + var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo CommonAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateAssemblyInfoFileName.ShouldContain("CommonAssemblyInfo.cs"); + arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(1); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); } [Test] public void UpdateAssemblyInfoWithMultipleFilenames() { - var arguments = argumentParser.ParseArguments("-updateAssemblyInfo CommonAssemblyInfo.cs VersionAssemblyInfo.cs"); + using var repo = new EmptyRepositoryFixture(); + + var assemblyFile1 = Path.Combine(repo.RepositoryPath, "CommonAssemblyInfo.cs"); + using var file = File.Create(assemblyFile1); + + var assemblyFile2 = Path.Combine(repo.RepositoryPath, "VersionAssemblyInfo.cs"); + using var file2 = File.Create(assemblyFile2); + + var arguments = argumentParser.ParseArguments($"-targetpath {repo.RepositoryPath} -updateAssemblyInfo CommonAssemblyInfo.cs VersionAssemblyInfo.cs"); arguments.UpdateAssemblyInfo.ShouldBe(true); arguments.UpdateAssemblyInfoFileName.Count.ShouldBe(2); - arguments.UpdateAssemblyInfoFileName.ShouldContain("CommonAssemblyInfo.cs"); - arguments.UpdateAssemblyInfoFileName.ShouldContain("VersionAssemblyInfo.cs"); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("CommonAssemblyInfo.cs")); + arguments.UpdateAssemblyInfoFileName.ShouldContain(x => Path.GetFileName(x).Equals("VersionAssemblyInfo.cs")); + } + + [Test] + public void UpdateAssemblyInfoWithMultipleFilenamesMatchingGlobbing() + { + using var repo = new EmptyRepositoryFixture(); + + var assemblyFile1 = Path.Combine(repo.RepositoryPath, "CommonAssemblyInfo.cs"); + using var file = File.Create(assemblyFile1); + + var assemblyFile2 = Path.Combine(repo.RepositoryPath, "VersionAssemblyInfo.cs"); + using var file2 = File.Create(assemblyFile2); + + var subdir = Path.Combine(repo.RepositoryPath, "subdir"); + Directory.CreateDirectory(subdir); + var assemblyFile3 = Path.Combine(subdir, "LocalAssemblyInfo.cs"); + using var file3 = File.Create(assemblyFile3); + + 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")); + } + + [Test] + public void UpdateAssemblyInfoWithRelativeFilename() + { + using var repo = new EmptyRepositoryFixture(); + + var assemblyFile = Path.Combine(repo.RepositoryPath, "CommonAssemblyInfo.cs"); + using var file = File.Create(assemblyFile); + + var targetPath = Path.Combine(repo.RepositoryPath, "subdir1", "subdir2"); + Directory.CreateDirectory(targetPath); + + 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")); } [Test] @@ -301,14 +359,6 @@ public void OverrideconfigWithInvalidOption(string options) exception.Message.ShouldContain("Could not parse /overrideconfig option"); } - [Test] - public void UpdateAssemblyInfoWithRelativeFilename() - { - var arguments = argumentParser.ParseArguments("-updateAssemblyInfo ..\\..\\CommonAssemblyInfo.cs"); - arguments.UpdateAssemblyInfo.ShouldBe(true); - arguments.UpdateAssemblyInfoFileName.ShouldContain("..\\..\\CommonAssemblyInfo.cs"); - } - [Test] public void EnsureAssemblyInfoTrueWhenFound() { diff --git a/src/GitVersionExe.Tests/ArgumentBuilder.cs b/src/GitVersionExe.Tests/Helpers/ArgumentBuilder.cs similarity index 100% rename from src/GitVersionExe.Tests/ArgumentBuilder.cs rename to src/GitVersionExe.Tests/Helpers/ArgumentBuilder.cs diff --git a/src/GitVersionExe.Tests/AssemblyParallelizable.cs b/src/GitVersionExe.Tests/Helpers/AssemblyParallelizable.cs similarity index 100% rename from src/GitVersionExe.Tests/AssemblyParallelizable.cs rename to src/GitVersionExe.Tests/Helpers/AssemblyParallelizable.cs diff --git a/src/GitVersionExe.Tests/ExecutionResults.cs b/src/GitVersionExe.Tests/Helpers/ExecutionResults.cs similarity index 100% rename from src/GitVersionExe.Tests/ExecutionResults.cs rename to src/GitVersionExe.Tests/Helpers/ExecutionResults.cs diff --git a/src/GitVersionExe.Tests/GitVersionHelper.cs b/src/GitVersionExe.Tests/Helpers/GitVersionHelper.cs similarity index 100% rename from src/GitVersionExe.Tests/GitVersionHelper.cs rename to src/GitVersionExe.Tests/Helpers/GitVersionHelper.cs diff --git a/src/GitVersionExe.Tests/ProgramFixture.cs b/src/GitVersionExe.Tests/Helpers/ProgramFixture.cs similarity index 100% rename from src/GitVersionExe.Tests/ProgramFixture.cs rename to src/GitVersionExe.Tests/Helpers/ProgramFixture.cs diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index c1494a7375..1a9e3903f4 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -16,11 +16,13 @@ public class ArgumentParser : IArgumentParser private readonly IEnvironment environment; private readonly ICurrentBuildAgent buildAgent; private readonly IConsole console; + private readonly IGlobbingResolver globbingResolver; - public ArgumentParser(IEnvironment environment, ICurrentBuildAgent buildAgent, IConsole console) + public ArgumentParser(IEnvironment environment, ICurrentBuildAgent buildAgent, IConsole console, IGlobbingResolver globbingResolver) { this.environment = environment ?? throw new ArgumentNullException(nameof(environment)); this.console = console ?? throw new ArgumentNullException(nameof(console)); + this.globbingResolver = globbingResolver ?? throw new ArgumentNullException(nameof(globbingResolver)); this.buildAgent = buildAgent; } @@ -87,6 +89,8 @@ public Arguments ParseArguments(string[] commandLineArguments) ? System.Environment.CurrentDirectory : firstArgument; + arguments.TargetPath = arguments.TargetPath.TrimEnd('/', '\\'); + arguments.UpdateAssemblyInfoFileName = ResolveFiles(arguments.TargetPath, arguments.UpdateAssemblyInfoFileName).ToHashSet(); arguments.NoFetch = arguments.NoFetch || buildAgent != null && buildAgent.PreventFetch(); return arguments; @@ -234,7 +238,6 @@ private void ParseArguments(Arguments arguments, NameValueCollection switchesAnd if (name.IsSwitch("showConfig")) { ParseShowConfig(value, arguments); - return; } @@ -311,6 +314,21 @@ private void ParseArguments(Arguments arguments, NameValueCollection switchesAnd throw new WarningException(couldNotParseMessage); } + private void AddAuthentication(Arguments arguments) + { + var username = environment.GetEnvironmentVariable("GITVERSION_REMOTE_USERNAME"); + if (!string.IsNullOrWhiteSpace(username)) + { + arguments.Authentication.Username = username; + } + + var password = environment.GetEnvironmentVariable("GITVERSION_REMOTE_PASSWORD"); + if (!string.IsNullOrWhiteSpace(password)) + { + arguments.Authentication.Username = password; + } + } + private static void ParseShowConfig(string value, Arguments arguments) { if (value.IsTrue()) @@ -440,7 +458,10 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s else if (!value.IsSwitchArgument()) { arguments.UpdateAssemblyInfo = true; - arguments.UpdateAssemblyInfoFileName.Add(value); + if (value != null) + { + arguments.UpdateAssemblyInfoFileName.Add(value); + } } else { @@ -453,18 +474,18 @@ private static void ParseUpdateAssemblyInfo(Arguments arguments, string value, s } } - private void AddAuthentication(Arguments arguments) + private IEnumerable ResolveFiles(string workingDirectory, ISet assemblyInfoFiles) { - var username = environment.GetEnvironmentVariable("GITVERSION_REMOTE_USERNAME"); - if (!string.IsNullOrWhiteSpace(username)) - { - arguments.Authentication.Username = username; - } + if (assemblyInfoFiles == null) yield break; - var password = environment.GetEnvironmentVariable("GITVERSION_REMOTE_PASSWORD"); - if (!string.IsNullOrWhiteSpace(password)) + foreach (var file in assemblyInfoFiles) { - arguments.Authentication.Username = password; + var paths = globbingResolver.Resolve(workingDirectory, file); + + foreach (var path in paths) + { + yield return Path.GetFullPath(Path.Combine(workingDirectory, path)); + } } } diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index a2b8cc5e2d..baf9abe2c4 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -52,15 +52,17 @@ public class Arguments public GitVersionOptions ToOptions() { + var workingDirectory = TargetPath.TrimEnd('/', '\\'); + return new GitVersionOptions { - WorkingDirectory = TargetPath.TrimEnd('/', '\\'), + WorkingDirectory = workingDirectory, AssemblyInfo = { ShouldUpdate = UpdateAssemblyInfo, EnsureAssemblyInfo = EnsureAssemblyInfo, - Files = UpdateAssemblyInfoFileName, + Files = UpdateAssemblyInfoFileName }, Authentication = diff --git a/src/GitVersionExe/GitVersionExe.csproj b/src/GitVersionExe/GitVersionExe.csproj index 899980aa74..7424ee3d7d 100644 --- a/src/GitVersionExe/GitVersionExe.csproj +++ b/src/GitVersionExe/GitVersionExe.csproj @@ -29,6 +29,7 @@ + diff --git a/src/GitVersionExe/GitVersionExeModule.cs b/src/GitVersionExe/GitVersionExeModule.cs index beab0395c2..df4e5e7a96 100644 --- a/src/GitVersionExe/GitVersionExeModule.cs +++ b/src/GitVersionExe/GitVersionExeModule.cs @@ -7,6 +7,8 @@ public class GitVersionExeModule : IGitVersionModule public void RegisterTypes(IServiceCollection services) { services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/src/GitVersionExe/GlobbingResolver.cs b/src/GitVersionExe/GlobbingResolver.cs new file mode 100644 index 0000000000..31a4d56eba --- /dev/null +++ b/src/GitVersionExe/GlobbingResolver.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Extensions.FileSystemGlobbing; +using Microsoft.Extensions.FileSystemGlobbing.Abstractions; + +namespace GitVersion +{ + public class GlobbingResolver : IGlobbingResolver + { + private Matcher matcher = new Matcher(StringComparison.OrdinalIgnoreCase); + + public IEnumerable Resolve(string workingDirectory, string pattern) + { + matcher.AddInclude(pattern); + return matcher.Execute(GetDirectoryInfoWrapper(workingDirectory)).Files.Select(file => file.Path); + } + + protected virtual DirectoryInfoBase GetDirectoryInfoWrapper(string workingDirectory) => new DirectoryInfoWrapper(new DirectoryInfo(workingDirectory)); + } +} diff --git a/src/GitVersionExe/IGlobbingResolver.cs b/src/GitVersionExe/IGlobbingResolver.cs new file mode 100644 index 0000000000..879c646d53 --- /dev/null +++ b/src/GitVersionExe/IGlobbingResolver.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace GitVersion +{ + public interface IGlobbingResolver + { + public IEnumerable Resolve(string workingDirectory, string pattern); + } +}