From dc4d28afa1a1d14884284c5d0e99447a5dc0a3e9 Mon Sep 17 00:00:00 2001 From: Bi0T1N Date: Fri, 21 Feb 2025 23:04:34 +0100 Subject: [PATCH 1/5] Support for dotted versions of the GitVersion config files by default follow the convention of having a leading dot for config files used e.g. for .gitignore, .editorconfig, .gitattributes, etc --- docs/input/docs/usage/cli/arguments.md | 8 +++---- .../OverrideConfigurationOptionParser.cs | 2 +- .../ConfigurationFileLocatorTests.cs | 14 +++++++++++++ .../ConfigurationFileLocator.cs | 21 +++++++++++++------ .../Core/GitVersionExecutorTests.cs | 2 ++ 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/docs/input/docs/usage/cli/arguments.md b/docs/input/docs/usage/cli/arguments.md index c47e115ba7..01d773c752 100644 --- a/docs/input/docs/usage/cli/arguments.md +++ b/docs/input/docs/usage/cli/arguments.md @@ -41,9 +41,9 @@ GitVersion [path] E.g. /output json /format {SemVer} - will output `1.2.3+beta.4` /output json /format {Major}.{Minor} - will output `1.2` /l Path to logfile. - /config Path to config file (defaults to GitVersion.yml or GitVersion.yaml) + /config Path to config file (defaults to GitVersion.yml, GitVersion.yaml, .GitVersion.yml or .GitVersion.yaml) /showconfig Outputs the effective GitVersion config (defaults + custom - from GitVersion.yml or GitVersion.yaml) in yaml format + from GitVersion.yml, GitVersion.yaml, .GitVersion.yml or .GitVersion.yaml) in yaml format /overrideconfig Overrides GitVersion config values inline (semicolon- separated key value pairs e.g. /overrideconfig tag-prefix=Foo) @@ -97,7 +97,7 @@ GitVersion [path] ## Override config -`/overrideconfig [key=value]` will override appropriate `key` from 'GitVersion.yml' or 'GitVersion.yaml'. +`/overrideconfig [key=value]` will override appropriate `key` from 'GitVersion.yml', 'GitVersion.yaml', '.GitVersion.yml' or '.GitVersion.yaml'. To specify multiple options add multiple `/overrideconfig [key=value]` entries: `/overrideconfig key1=value1 /overrideconfig key2=value2`. @@ -129,7 +129,7 @@ Following options are supported: Read more about [Configuration](/docs/reference/configuration). -Using `override-config` on the command line will not change the contents of the config file `GitVersion.yml` or `GitVersion.yaml`. +Using `override-config` on the command line will not change the contents of the config file `GitVersion.yml`, `GitVersion.yaml`, `.GitVersion.yml` or `.GitVersion.yaml`. ### Example: How to override configuration option 'tag-prefix' to use prefix 'custom' diff --git a/src/GitVersion.App/OverrideConfigurationOptionParser.cs b/src/GitVersion.App/OverrideConfigurationOptionParser.cs index 1d4d6fa985..f3e886ddcf 100644 --- a/src/GitVersion.App/OverrideConfigurationOptionParser.cs +++ b/src/GitVersion.App/OverrideConfigurationOptionParser.cs @@ -18,7 +18,7 @@ internal class OverrideConfigurationOptionParser /// /// /// - /// Lookup keys are created from to match 'GitVersion.yml' or 'GitVersion.yaml' file + /// Lookup keys are created from to match 'GitVersion.yml', 'GitVersion.yaml', '.GitVersion.yml' or '.GitVersion.yaml' file /// options as close as possible. /// private static ILookup GetSupportedProperties() => typeof(GitVersionConfiguration).GetProperties(BindingFlags.Public | BindingFlags.Instance) diff --git a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs index 48c43afa15..1f2db614d3 100644 --- a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs +++ b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs @@ -37,8 +37,20 @@ public void Setup() [TestCase(ConfigurationFileLocator.DefaultFileName, ConfigurationFileLocator.DefaultFileName)] [TestCase(ConfigurationFileLocator.DefaultFileName, ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultFileName, ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultFileName, ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName, ConfigurationFileLocator.DefaultFileName)] [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName, ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName, ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName, ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted, ConfigurationFileLocator.DefaultFileName)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted, ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted, ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted, ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted, ConfigurationFileLocator.DefaultFileName)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted, ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted, ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted, ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] public void ThrowsExceptionOnAmbiguousConfigFileLocation(string repoConfigFile, string workingConfigFile) { using var repositoryConfigFilePath = this.fileSystem.SetupConfigFile(path: this.repoPath, fileName: repoConfigFile); @@ -52,6 +64,8 @@ public void ThrowsExceptionOnAmbiguousConfigFileLocation(string repoConfigFile, [TestCase(ConfigurationFileLocator.DefaultFileName)] [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] public void NoWarnOnGitVersionYmlFile(string configurationFile) { using var _ = this.fileSystem.SetupConfigFile(path: this.repoPath, fileName: configurationFile); diff --git a/src/GitVersion.Configuration/ConfigurationFileLocator.cs b/src/GitVersion.Configuration/ConfigurationFileLocator.cs index 6d23ac35c5..14c8c69156 100644 --- a/src/GitVersion.Configuration/ConfigurationFileLocator.cs +++ b/src/GitVersion.Configuration/ConfigurationFileLocator.cs @@ -13,6 +13,9 @@ internal class ConfigurationFileLocator( { public const string DefaultFileName = "GitVersion.yml"; public const string DefaultAlternativeFileName = "GitVersion.yaml"; + public const string DefaultFileNameDotted = $".{DefaultFileName}"; + public const string DefaultAlternativeFileNameDotted = $".{DefaultAlternativeFileName}"; + public List PossibleConfigFileNames = [DefaultFileName, DefaultAlternativeFileName, DefaultFileNameDotted, DefaultAlternativeFileNameDotted]; private readonly IFileSystem fileSystem = fileSystem.NotNull(); private readonly ILog log = log.NotNull(); @@ -30,11 +33,17 @@ public void Verify(string? workingDirectory, string? projectRootDirectory) public string? GetConfigurationFile(string? directory) { if (directory is null) return null; - string?[] candidates = [this.ConfigurationFile, DefaultFileName, DefaultAlternativeFileName]; - var candidatePaths = - from candidate in candidates - where !candidate.IsNullOrWhiteSpace() - select PathHelper.Combine(directory, candidate); + var candidateList = new List(PossibleConfigFileNames); + if (!this.ConfigurationFile.IsNullOrEmpty()) + { + // give configuration value the highest priority + candidateList.Insert(0, this.ConfigurationFile); + } + + var candidatePaths = candidateList + .Where(candidate => !string.IsNullOrWhiteSpace(candidate)) + .Select(candidate => PathHelper.Combine(directory, candidate)) + .ToList(); foreach (var candidatePath in candidatePaths) { @@ -65,7 +74,7 @@ private void WarnAboutAmbiguousConfigFileSelection(string? workingDirectory, str if (!hasConfigInProjectRootDirectory && !hasConfigInWorkingDirectory) { - if (this.ConfigurationFile is not (DefaultFileName or DefaultAlternativeFileName)) + if (!PossibleConfigFileNames.Any(entry => entry.Equals(this.ConfigurationFile))) { workingConfigFile = PathHelper.Combine(workingDirectory, this.ConfigurationFile); projectRootConfigFile = PathHelper.Combine(projectRootDirectory, this.ConfigurationFile); diff --git a/src/GitVersion.Core.Tests/Core/GitVersionExecutorTests.cs b/src/GitVersion.Core.Tests/Core/GitVersionExecutorTests.cs index 2fea817d8f..f2dac1d3f8 100644 --- a/src/GitVersion.Core.Tests/Core/GitVersionExecutorTests.cs +++ b/src/GitVersion.Core.Tests/Core/GitVersionExecutorTests.cs @@ -243,6 +243,8 @@ public void CacheFileIsMissing() [TestCase(ConfigurationFileLocator.DefaultFileName)] [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] public void ConfigChangeInvalidatesCache(string configFileName) { const string versionCacheFileContent = """ From 53a6329a9cb843d93bd9f3897be22c72c27092f9 Mon Sep 17 00:00:00 2001 From: Bi0T1N Date: Wed, 26 Feb 2025 20:48:27 +0100 Subject: [PATCH 2/5] Rename PossibleConfigFileNames to SupportedConfigFileNames --- src/GitVersion.Configuration/ConfigurationFileLocator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GitVersion.Configuration/ConfigurationFileLocator.cs b/src/GitVersion.Configuration/ConfigurationFileLocator.cs index 14c8c69156..c05ceeb24b 100644 --- a/src/GitVersion.Configuration/ConfigurationFileLocator.cs +++ b/src/GitVersion.Configuration/ConfigurationFileLocator.cs @@ -15,7 +15,7 @@ internal class ConfigurationFileLocator( public const string DefaultAlternativeFileName = "GitVersion.yaml"; public const string DefaultFileNameDotted = $".{DefaultFileName}"; public const string DefaultAlternativeFileNameDotted = $".{DefaultAlternativeFileName}"; - public List PossibleConfigFileNames = [DefaultFileName, DefaultAlternativeFileName, DefaultFileNameDotted, DefaultAlternativeFileNameDotted]; + public List SupportedConfigFileNames = [DefaultFileName, DefaultAlternativeFileName, DefaultFileNameDotted, DefaultAlternativeFileNameDotted]; private readonly IFileSystem fileSystem = fileSystem.NotNull(); private readonly ILog log = log.NotNull(); @@ -33,7 +33,7 @@ public void Verify(string? workingDirectory, string? projectRootDirectory) public string? GetConfigurationFile(string? directory) { if (directory is null) return null; - var candidateList = new List(PossibleConfigFileNames); + var candidateList = new List(SupportedConfigFileNames); if (!this.ConfigurationFile.IsNullOrEmpty()) { // give configuration value the highest priority @@ -74,7 +74,7 @@ private void WarnAboutAmbiguousConfigFileSelection(string? workingDirectory, str if (!hasConfigInProjectRootDirectory && !hasConfigInWorkingDirectory) { - if (!PossibleConfigFileNames.Any(entry => entry.Equals(this.ConfigurationFile))) + if (!SupportedConfigFileNames.Any(entry => entry.Equals(this.ConfigurationFile))) { workingConfigFile = PathHelper.Combine(workingDirectory, this.ConfigurationFile); projectRootConfigFile = PathHelper.Combine(projectRootDirectory, this.ConfigurationFile); From 6d61b3dce0fc4362007f786e8350500e353aaadf Mon Sep 17 00:00:00 2001 From: Bi0T1N Date: Wed, 26 Feb 2025 20:50:06 +0100 Subject: [PATCH 3/5] Use case insensitive comparison for config filenames --- .../Configuration/ConfigurationFileLocatorTests.cs | 12 ++++++++++++ .../ConfigurationFileLocator.cs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs index 1f2db614d3..e89ac22636 100644 --- a/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs +++ b/src/GitVersion.Configuration.Tests/Configuration/ConfigurationFileLocatorTests.cs @@ -73,6 +73,18 @@ public void NoWarnOnGitVersionYmlFile(string configurationFile) Should.NotThrow(() => this.configurationProvider.ProvideForDirectory(this.repoPath)); } + [TestCase(ConfigurationFileLocator.DefaultFileName)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileName)] + [TestCase(ConfigurationFileLocator.DefaultFileNameDotted)] + [TestCase(ConfigurationFileLocator.DefaultAlternativeFileNameDotted)] + public void NoWarnOnLowercasedGitVersionYmlFile(string configurationFile) + { + var lowercasedConfigurationFile = configurationFile.ToLower(); + using var _ = this.fileSystem.SetupConfigFile(path: this.repoPath, fileName: lowercasedConfigurationFile); + + Should.NotThrow(() => this.configurationProvider.ProvideForDirectory(this.repoPath)); + } + [Test] public void NoWarnOnNoGitVersionYmlFile() => Should.NotThrow(() => this.configurationProvider.ProvideForDirectory(this.repoPath)); } diff --git a/src/GitVersion.Configuration/ConfigurationFileLocator.cs b/src/GitVersion.Configuration/ConfigurationFileLocator.cs index c05ceeb24b..3bd9556e80 100644 --- a/src/GitVersion.Configuration/ConfigurationFileLocator.cs +++ b/src/GitVersion.Configuration/ConfigurationFileLocator.cs @@ -74,7 +74,7 @@ private void WarnAboutAmbiguousConfigFileSelection(string? workingDirectory, str if (!hasConfigInProjectRootDirectory && !hasConfigInWorkingDirectory) { - if (!SupportedConfigFileNames.Any(entry => entry.Equals(this.ConfigurationFile))) + if (!SupportedConfigFileNames.Any(entry => entry.Equals(this.ConfigurationFile, StringComparison.OrdinalIgnoreCase))) { workingConfigFile = PathHelper.Combine(workingDirectory, this.ConfigurationFile); projectRootConfigFile = PathHelper.Combine(projectRootDirectory, this.ConfigurationFile); From ea037470fd46fa257a292216859b828b92c76c58 Mon Sep 17 00:00:00 2001 From: Bi0T1N Date: Wed, 26 Feb 2025 20:57:28 +0100 Subject: [PATCH 4/5] Change candidates section to use old code syntax --- .../ConfigurationFileLocator.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/GitVersion.Configuration/ConfigurationFileLocator.cs b/src/GitVersion.Configuration/ConfigurationFileLocator.cs index 3bd9556e80..6b7ce942c2 100644 --- a/src/GitVersion.Configuration/ConfigurationFileLocator.cs +++ b/src/GitVersion.Configuration/ConfigurationFileLocator.cs @@ -33,17 +33,12 @@ public void Verify(string? workingDirectory, string? projectRootDirectory) public string? GetConfigurationFile(string? directory) { if (directory is null) return null; - var candidateList = new List(SupportedConfigFileNames); - if (!this.ConfigurationFile.IsNullOrEmpty()) - { - // give configuration value the highest priority - candidateList.Insert(0, this.ConfigurationFile); - } - var candidatePaths = candidateList - .Where(candidate => !string.IsNullOrWhiteSpace(candidate)) - .Select(candidate => PathHelper.Combine(directory, candidate)) - .ToList(); + string?[] candidates = [this.ConfigurationFile, ..SupportedConfigFileNames]; + var candidatePaths = + from candidate in candidates + where !candidate.IsNullOrWhiteSpace() + select PathHelper.Combine(directory, candidate); foreach (var candidatePath in candidatePaths) { From 91af21378e890b07b2807e882890605ff3096048 Mon Sep 17 00:00:00 2001 From: Bi0T1N Date: Wed, 26 Feb 2025 21:12:24 +0100 Subject: [PATCH 5/5] Make dotnet format happy with syntax --- src/GitVersion.Configuration/ConfigurationFileLocator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitVersion.Configuration/ConfigurationFileLocator.cs b/src/GitVersion.Configuration/ConfigurationFileLocator.cs index 6b7ce942c2..0354d9a0c9 100644 --- a/src/GitVersion.Configuration/ConfigurationFileLocator.cs +++ b/src/GitVersion.Configuration/ConfigurationFileLocator.cs @@ -34,7 +34,7 @@ public void Verify(string? workingDirectory, string? projectRootDirectory) { if (directory is null) return null; - string?[] candidates = [this.ConfigurationFile, ..SupportedConfigFileNames]; + string?[] candidates = [this.ConfigurationFile, .. SupportedConfigFileNames]; var candidatePaths = from candidate in candidates where !candidate.IsNullOrWhiteSpace()