From ca56757a48399ab7c7cccc2eddf4fd65b2ad9ca4 Mon Sep 17 00:00:00 2001 From: Chris Huseman Date: Sun, 30 Jun 2019 14:10:17 -0500 Subject: [PATCH] Allow overriding of the config file path This adds a new abstract ConfigFileLocator class, which has two implementations: * DefaultConfigFileLocator, which is the current logic (GitVersion.yml and GitVersionConfig.yaml in working and project root directories). * NamedConfigFileLocator that will only look for a specific file path (it can be a relative or absolute path). GitVersionExe has a new optional /config argument which takes a path. GitVersionTask has a new ConfigFilePath property on all inputs and is exposed via the MSBuild GitVersionConfig property. GitVersionTfsTask has a new configFilePath input. --- .../ConfigProviderTests.cs | 124 +++------------ .../DefaultConfigFileLocatorTests.cs | 125 +++++++++++++++ src/GitVersionCore.Tests/ExecuteCoreTests.cs | 5 +- .../Init/InitScenarios.cs | 5 +- .../NamedConfigFileLocatorTests.cs | 80 ++++++++++ .../Configuration/ConfigFileLocator.cs | 62 ++++++++ .../Configuration/ConfigurationProvider.cs | 150 ++---------------- .../Configuration/DefaultConfigFileLocator.cs | 94 +++++++++++ .../Configuration/NamedConfigFileLocator.cs | 47 ++++++ src/GitVersionCore/ExecuteCore.cs | 12 +- .../GitVersionCacheKeyFactory.cs | 10 +- src/GitVersionExe/ArgumentParser.cs | 7 + src/GitVersionExe/Arguments.cs | 1 + src/GitVersionExe/HelpWriter.cs | 1 + src/GitVersionExe/Program.cs | 6 +- src/GitVersionExe/SpecifiedArgumentRunner.cs | 2 +- .../GitVersionTaskBase.cs | 4 +- src/GitVersionTask/GitVersionTasks.cs | 2 +- .../build/GitVersionTask.targets | 6 +- .../GitVersionTask.targets | 4 +- src/GitVersionTfsTask/GitVersion.ts | 6 + .../GitVersionTask/task.json | 7 + 22 files changed, 499 insertions(+), 261 deletions(-) create mode 100644 src/GitVersionCore.Tests/DefaultConfigFileLocatorTests.cs create mode 100644 src/GitVersionCore.Tests/NamedConfigFileLocatorTests.cs create mode 100644 src/GitVersionCore/Configuration/ConfigFileLocator.cs create mode 100644 src/GitVersionCore/Configuration/DefaultConfigFileLocator.cs create mode 100644 src/GitVersionCore/Configuration/NamedConfigFileLocator.cs diff --git a/src/GitVersionCore.Tests/ConfigProviderTests.cs b/src/GitVersionCore.Tests/ConfigProviderTests.cs index 2f1ee43ad3..ab8cd15209 100644 --- a/src/GitVersionCore.Tests/ConfigProviderTests.cs +++ b/src/GitVersionCore.Tests/ConfigProviderTests.cs @@ -14,19 +14,18 @@ [TestFixture] public class ConfigProviderTests : TestBase { - private const string DefaultRepoPath = "c:\\MyGitRepo"; - private const string DefaultWorkingPath = "c:\\MyGitRepo\\Working"; + private const string DefaultRepoPath = @"c:\MyGitRepo"; string repoPath; - string workingPath; IFileSystem fileSystem; + ConfigFileLocator configFileLocator; [SetUp] public void Setup() { fileSystem = new TestFileSystem(); + configFileLocator = new DefaultConfigFileLocator(); repoPath = DefaultRepoPath; - workingPath = DefaultWorkingPath; ShouldlyConfiguration.ShouldMatchApprovedDefaults.LocateTestMethodUsingAttribute(); } @@ -49,7 +48,7 @@ public void CanReadOldDocument() tag: rc "; SetupConfigFileContent(text); - var error = Should.Throw(() => ConfigurationProvider.Provide(repoPath, fileSystem)); + var error = Should.Throw(() => ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator)); error.Message.ShouldContainWithoutWhitespace(@"GitVersion configuration file contains old configuration, please fix the following errors: GitVersion branch configs no longer are keyed by regexes, update: dev(elop)?(ment)?$ -> develop @@ -62,7 +61,7 @@ assemblyVersioningScheme has been replaced by assembly-versioning-scheme [Test] public void OverwritesDefaultsWithProvidedConfig() { - var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem); + var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); const string text = @" next-version: 2.0.0 branches: @@ -70,7 +69,7 @@ public void OverwritesDefaultsWithProvidedConfig() mode: ContinuousDeployment tag: dev"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.NextVersion.ShouldBe("2.0.0"); config.Branches["develop"].Increment.ShouldBe(defaultConfig.Branches["develop"].Increment); @@ -81,10 +80,9 @@ public void OverwritesDefaultsWithProvidedConfig() [Test] public void AllBranchesModeWhenUsingMainline() { - var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem); const string text = @"mode: Mainline"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); var branches = config.Branches.Select(x => x.Value); branches.All(branch => branch.VersioningMode == VersioningMode.Mainline).ShouldBe(true); } @@ -98,7 +96,7 @@ public void CanRemoveTag() release: tag: """""; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.NextVersion.ShouldBe("2.0.0"); config.Branches["release"].Tag.ShouldBe(string.Empty); @@ -113,7 +111,7 @@ public void RegexIsRequired() bug: tag: bugfix"; SetupConfigFileContent(text); - var ex = Should.Throw(() => ConfigurationProvider.Provide(repoPath, fileSystem)); + var ex = Should.Throw(() => ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator)); ex.Message.ShouldBe("Branch configuration 'bug' is missing required configuration 'regex'\n\n" + "See http://gitversion.readthedocs.io/en/latest/configuration/ for more info"); } @@ -128,7 +126,7 @@ public void SourceBranchIsRequired() regex: 'bug[/-]' tag: bugfix"; SetupConfigFileContent(text); - var ex = Should.Throw(() => ConfigurationProvider.Provide(repoPath, fileSystem)); + var ex = Should.Throw(() => ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator)); ex.Message.ShouldBe("Branch configuration 'bug' is missing required configuration 'source-branches'\n\n" + "See http://gitversion.readthedocs.io/en/latest/configuration/ for more info"); } @@ -144,7 +142,7 @@ public void CanProvideConfigForNewBranch() tag: bugfix source-branches: []"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.Branches["bug"].Regex.ShouldBe("bug[/-]"); config.Branches["bug"].Tag.ShouldBe("bugfix"); @@ -155,7 +153,7 @@ public void NextVersionCanBeInteger() { const string text = "next-version: 2"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.NextVersion.ShouldBe("2.0"); } @@ -165,7 +163,7 @@ public void NextVersionCanHaveEnormousMinorVersion() { const string text = "next-version: 2.118998723"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.NextVersion.ShouldBe("2.118998723"); } @@ -175,7 +173,7 @@ public void NextVersionCanHavePatch() { const string text = "next-version: 2.12.654651698"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.NextVersion.ShouldBe("2.12.654651698"); } @@ -186,7 +184,7 @@ public void NextVersionCanHavePatch() [MethodImpl(MethodImplOptions.NoInlining)] public void CanWriteOutEffectiveConfiguration() { - var config = ConfigurationProvider.GetEffectiveConfigAsString(repoPath, fileSystem); + var config = ConfigurationProvider.GetEffectiveConfigAsString(repoPath, fileSystem, configFileLocator); config.ShouldMatchApproved(); } @@ -201,7 +199,7 @@ public void CanUpdateAssemblyInformationalVersioningScheme() SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.AssemblyVersioningScheme.ShouldBe(AssemblyVersioningScheme.MajorMinor); config.AssemblyFileVersioningScheme.ShouldBe(AssemblyFileVersioningScheme.MajorMinorPatch); config.AssemblyInformationalFormat.ShouldBe("{NugetVersion}"); @@ -217,7 +215,7 @@ public void CanUpdateAssemblyInformationalVersioningSchemeWithMultipleVariables( SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.AssemblyVersioningScheme.ShouldBe(AssemblyVersioningScheme.MajorMinor); config.AssemblyFileVersioningScheme.ShouldBe(AssemblyFileVersioningScheme.MajorMinorPatch); config.AssemblyInformationalFormat.ShouldBe("{Major}.{Minor}.{Patch}"); @@ -236,7 +234,7 @@ public void CanUpdateAssemblyInformationalVersioningSchemeWithFullSemVer() SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.AssemblyVersioningScheme.ShouldBe(AssemblyVersioningScheme.MajorMinorPatch); config.AssemblyFileVersioningScheme.ShouldBe(AssemblyFileVersioningScheme.MajorMinorPatch); config.AssemblyInformationalFormat.ShouldBe("{FullSemVer}"); @@ -247,7 +245,7 @@ public void CanReadDefaultDocument() { const string text = ""; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.AssemblyVersioningScheme.ShouldBe(AssemblyVersioningScheme.MajorMinorPatch); config.AssemblyFileVersioningScheme.ShouldBe(AssemblyFileVersioningScheme.MajorMinorPatch); config.AssemblyInformationalFormat.ShouldBe(null); @@ -269,55 +267,6 @@ public void VerifyAliases() propertiesMissingAlias.ShouldBeEmpty(); } - [TestCase(DefaultRepoPath)] - [TestCase(DefaultWorkingPath)] - public void WarnOnExistingGitVersionConfigYamlFile(string path) - { - SetupConfigFileContent(string.Empty, ConfigurationProvider.ObsoleteConfigFileName, path); - - var logOutput = string.Empty; - Action action = info => { logOutput = info; }; - using (Logger.AddLoggersTemporarily(action, action, action, action)) - { - ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); - } - var configFileDeprecatedWarning = string.Format("{0}' is deprecated, use '{1}' instead", ConfigurationProvider.ObsoleteConfigFileName, ConfigurationProvider.DefaultConfigFileName); - logOutput.Contains(configFileDeprecatedWarning).ShouldBe(true); - } - - [TestCase(DefaultRepoPath)] - [TestCase(DefaultWorkingPath)] - public void WarnOnAmbiguousConfigFilesAtTheSameProjectRootDirectory(string path) - { - SetupConfigFileContent(string.Empty, ConfigurationProvider.ObsoleteConfigFileName, path); - SetupConfigFileContent(string.Empty, ConfigurationProvider.DefaultConfigFileName, path); - - var logOutput = string.Empty; - Action action = info => { logOutput = info; }; - using (Logger.AddLoggersTemporarily(action, action, action, action)) - { - ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); - } - - var configFileDeprecatedWarning = string.Format("Ambiguous config files at '{0}'", path); - logOutput.Contains(configFileDeprecatedWarning).ShouldBe(true); - } - - [TestCase(ConfigurationProvider.DefaultConfigFileName, ConfigurationProvider.DefaultConfigFileName)] - [TestCase(ConfigurationProvider.DefaultConfigFileName, ConfigurationProvider.ObsoleteConfigFileName)] - [TestCase(ConfigurationProvider.ObsoleteConfigFileName, ConfigurationProvider.DefaultConfigFileName)] - [TestCase(ConfigurationProvider.ObsoleteConfigFileName, ConfigurationProvider.ObsoleteConfigFileName)] - public void ThrowsExceptionOnAmbiguousConfigFileLocation(string repoConfigFile, string workingConfigFile) - { - var repositoryConfigFilePath = SetupConfigFileContent(string.Empty, repoConfigFile, repoPath); - var workingDirectoryConfigFilePath = SetupConfigFileContent(string.Empty, workingConfigFile, workingPath); - - WarningException exception = Should.Throw(() => { ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); }); - - var expecedMessage = string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingDirectoryConfigFilePath, repositoryConfigFilePath); - exception.Message.ShouldBe(expecedMessage); - } - [Test] public void NoWarnOnGitVersionYmlFile() { @@ -327,12 +276,12 @@ public void NoWarnOnGitVersionYmlFile() Action action = info => { s = info; }; using (Logger.AddLoggersTemporarily(action, action, action, action)) { - ConfigurationProvider.Provide(repoPath, fileSystem); + ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); } s.Length.ShouldBe(0); } - string SetupConfigFileContent(string text, string fileName = ConfigurationProvider.DefaultConfigFileName) + string SetupConfigFileContent(string text, string fileName = DefaultConfigFileLocator.DefaultFileName) { return SetupConfigFileContent(text, fileName, repoPath); } @@ -345,29 +294,9 @@ string SetupConfigFileContent(string text, string fileName, string path) return fullPath; } - [Test] - public void WarnOnObsoleteIsDevelopBranchConfigurationSetting() - { - const string text = @" -assembly-versioning-scheme: MajorMinorPatch -branches: - master: - tag: beta - is-develop: true"; - - OldConfigurationException exception = Should.Throw(() => - { - LegacyConfigNotifier.Notify(new StringReader(text)); - }); - - const string expectedMessage = @"'is-develop' is deprecated, use 'tracks-release-branches' instead."; - exception.Message.ShouldContain(expectedMessage); - } - [Test] public void ShouldUseSpecifiedSourceBranchesForDevelop() { - var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem); const string text = @" next-version: 2.0.0 branches: @@ -376,7 +305,7 @@ public void ShouldUseSpecifiedSourceBranchesForDevelop() source-branches: ['develop'] tag: dev"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.Branches["develop"].SourceBranches.ShouldBe(new List { "develop" }); } @@ -384,7 +313,6 @@ public void ShouldUseSpecifiedSourceBranchesForDevelop() [Test] public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForDevelop() { - var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem); const string text = @" next-version: 2.0.0 branches: @@ -392,7 +320,7 @@ public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForDevelop() mode: ContinuousDeployment tag: dev"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.Branches["develop"].SourceBranches.ShouldBe(new List()); } @@ -400,7 +328,6 @@ public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForDevelop() [Test] public void ShouldUseSpecifiedSourceBranchesForFeature() { - var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem); const string text = @" next-version: 2.0.0 branches: @@ -409,7 +336,7 @@ public void ShouldUseSpecifiedSourceBranchesForFeature() source-branches: ['develop', 'release'] tag: dev"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.Branches["feature"].SourceBranches.ShouldBe(new List { "develop", "release" }); } @@ -417,7 +344,6 @@ public void ShouldUseSpecifiedSourceBranchesForFeature() [Test] public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForFeature() { - var defaultConfig = ConfigurationProvider.Provide(repoPath, fileSystem); const string text = @" next-version: 2.0.0 branches: @@ -425,7 +351,7 @@ public void ShouldUseDefaultSourceBranchesWhenNotSpecifiedForFeature() mode: ContinuousDeployment tag: dev"; SetupConfigFileContent(text); - var config = ConfigurationProvider.Provide(repoPath, fileSystem); + var config = ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); config.Branches["feature"].SourceBranches.ShouldBe( new List { "develop", "master", "release", "feature", "support", "hotfix" }); diff --git a/src/GitVersionCore.Tests/DefaultConfigFileLocatorTests.cs b/src/GitVersionCore.Tests/DefaultConfigFileLocatorTests.cs new file mode 100644 index 0000000000..a905e120df --- /dev/null +++ b/src/GitVersionCore.Tests/DefaultConfigFileLocatorTests.cs @@ -0,0 +1,125 @@ +using GitVersion; +using GitVersion.Helpers; +using GitVersionCore.Tests; +using NUnit.Framework; +using Shouldly; +using System; +using System.IO; + +[TestFixture] +public class DefaultConfigFileLocatorTests : TestBase +{ + private const string DefaultRepoPath = @"c:\MyGitRepo"; + private const string DefaultWorkingPath = @"c:\MyGitRepo\Working"; + + string repoPath; + string workingPath; + IFileSystem fileSystem; + DefaultConfigFileLocator configFileLocator; + + [SetUp] + public void Setup() + { + fileSystem = new TestFileSystem(); + configFileLocator = new DefaultConfigFileLocator(); + repoPath = DefaultRepoPath; + workingPath = DefaultWorkingPath; + + ShouldlyConfiguration.ShouldMatchApprovedDefaults.LocateTestMethodUsingAttribute(); + } + + [TestCase(DefaultRepoPath)] + [TestCase(DefaultWorkingPath)] + public void WarnOnExistingGitVersionConfigYamlFile(string path) + { + SetupConfigFileContent(string.Empty, DefaultConfigFileLocator.ObsoleteFileName, path); + + var logOutput = string.Empty; + Action action = info => { logOutput = info; }; + using (Logger.AddLoggersTemporarily(action, action, action, action)) + { + configFileLocator.Verify(workingPath, repoPath, fileSystem); + } + var configFileDeprecatedWarning = string.Format("{0}' is deprecated, use '{1}' instead", DefaultConfigFileLocator.ObsoleteFileName, DefaultConfigFileLocator.DefaultFileName); + logOutput.Contains(configFileDeprecatedWarning).ShouldBe(true); + } + + [TestCase(DefaultRepoPath)] + [TestCase(DefaultWorkingPath)] + public void WarnOnAmbiguousConfigFilesAtTheSameProjectRootDirectory(string path) + { + SetupConfigFileContent(string.Empty, DefaultConfigFileLocator.ObsoleteFileName, path); + SetupConfigFileContent(string.Empty, DefaultConfigFileLocator.DefaultFileName, path); + + var logOutput = string.Empty; + Action action = info => { logOutput = info; }; + using (Logger.AddLoggersTemporarily(action, action, action, action)) + { + configFileLocator.Verify(workingPath, repoPath, fileSystem); + } + + var configFileDeprecatedWarning = string.Format("Ambiguous config files at '{0}'", path); + logOutput.Contains(configFileDeprecatedWarning).ShouldBe(true); + } + + [TestCase(DefaultConfigFileLocator.DefaultFileName, DefaultConfigFileLocator.DefaultFileName)] + [TestCase(DefaultConfigFileLocator.DefaultFileName, DefaultConfigFileLocator.ObsoleteFileName)] + [TestCase(DefaultConfigFileLocator.ObsoleteFileName, DefaultConfigFileLocator.DefaultFileName)] + [TestCase(DefaultConfigFileLocator.ObsoleteFileName, DefaultConfigFileLocator.ObsoleteFileName)] + public void ThrowsExceptionOnAmbiguousConfigFileLocation(string repoConfigFile, string workingConfigFile) + { + var repositoryConfigFilePath = SetupConfigFileContent(string.Empty, repoConfigFile, repoPath); + var workingDirectoryConfigFilePath = SetupConfigFileContent(string.Empty, workingConfigFile, workingPath); + + WarningException exception = Should.Throw(() => { configFileLocator.Verify(workingPath, repoPath, fileSystem); }); + + var expecedMessage = string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingDirectoryConfigFilePath, repositoryConfigFilePath); + exception.Message.ShouldBe(expecedMessage); + } + + [Test] + public void NoWarnOnGitVersionYmlFile() + { + SetupConfigFileContent(string.Empty); + + var s = string.Empty; + Action action = info => { s = info; }; + using (Logger.AddLoggersTemporarily(action, action, action, action)) + { + ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); + } + s.Length.ShouldBe(0); + } + + string SetupConfigFileContent(string text, string fileName = DefaultConfigFileLocator.DefaultFileName) + { + return SetupConfigFileContent(text, fileName, repoPath); + } + + string SetupConfigFileContent(string text, string fileName, string path) + { + var fullPath = Path.Combine(path, fileName); + fileSystem.WriteAllText(fullPath, text); + + return fullPath; + } + + [Test] + public void WarnOnObsoleteIsDevelopBranchConfigurationSetting() + { + const string text = @" +assembly-versioning-scheme: MajorMinorPatch +branches: + master: + tag: beta + is-develop: true"; + + OldConfigurationException exception = Should.Throw(() => + { + LegacyConfigNotifier.Notify(new StringReader(text)); + }); + + const string expectedMessage = @"'is-develop' is deprecated, use 'tracks-release-branches' instead."; + exception.Message.ShouldContain(expectedMessage); + } +} diff --git a/src/GitVersionCore.Tests/ExecuteCoreTests.cs b/src/GitVersionCore.Tests/ExecuteCoreTests.cs index c097a35f4b..04ad8fc674 100644 --- a/src/GitVersionCore.Tests/ExecuteCoreTests.cs +++ b/src/GitVersionCore.Tests/ExecuteCoreTests.cs @@ -30,10 +30,11 @@ public void CacheKeySameAfterReNormalizing() var targetUrl = "https://github.com/GitTools/GitVersion.git"; var targetBranch = "refs/head/master"; var gitPreparer = new GitPreparer(targetUrl, null, new Authentication(), false, fixture.RepositoryPath); + var configFileLocator = new DefaultConfigFileLocator(); gitPreparer.Initialise(true, targetBranch); - var cacheKey1 = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, null); + var cacheKey1 = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, null, configFileLocator); gitPreparer.Initialise(true, targetBranch); - var cacheKey2 = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, null); + var cacheKey2 = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, null, configFileLocator); cacheKey2.Value.ShouldBe(cacheKey1.Value); }); diff --git a/src/GitVersionCore.Tests/Init/InitScenarios.cs b/src/GitVersionCore.Tests/Init/InitScenarios.cs index 4978a81425..4e1bcc480a 100644 --- a/src/GitVersionCore.Tests/Init/InitScenarios.cs +++ b/src/GitVersionCore.Tests/Init/InitScenarios.cs @@ -1,4 +1,4 @@ -namespace GitVersionCore.Tests.Init +namespace GitVersionCore.Tests.Init { using GitVersion; using GitVersion.Configuration.Init; @@ -24,7 +24,8 @@ public void CanSetNextVersion() { var testFileSystem = new TestFileSystem(); var testConsole = new TestConsole("3", "2.0.0", "0"); - ConfigurationProvider.Init("c:\\proj", testFileSystem, testConsole); + var configFileLocator = new DefaultConfigFileLocator(); + ConfigurationProvider.Init("c:\\proj", testFileSystem, testConsole, configFileLocator); testFileSystem.ReadAllText("c:\\proj\\GitVersion.yml").ShouldMatchApproved(); } diff --git a/src/GitVersionCore.Tests/NamedConfigFileLocatorTests.cs b/src/GitVersionCore.Tests/NamedConfigFileLocatorTests.cs new file mode 100644 index 0000000000..0232f3befe --- /dev/null +++ b/src/GitVersionCore.Tests/NamedConfigFileLocatorTests.cs @@ -0,0 +1,80 @@ +using GitVersion; +using GitVersion.Helpers; +using GitVersionCore.Tests; +using NUnit.Framework; +using Shouldly; +using System; +using System.IO; + +[TestFixture] +public class NamedConfigFileLocatorTests : TestBase +{ + private const string DefaultRepoPath = @"c:\MyGitRepo"; + private const string DefaultWorkingPath = @"c:\MyGitRepo\Working"; + + string repoPath; + string workingPath; + IFileSystem fileSystem; + NamedConfigFileLocator configFileLocator; + + [SetUp] + public void Setup() + { + fileSystem = new TestFileSystem(); + configFileLocator = new NamedConfigFileLocator("my-config.yaml"); + repoPath = DefaultRepoPath; + workingPath = DefaultWorkingPath; + + ShouldlyConfiguration.ShouldMatchApprovedDefaults.LocateTestMethodUsingAttribute(); + } + + [Test] + public void ThrowsExceptionOnAmbiguousConfigFileLocation() + { + var repositoryConfigFilePath = SetupConfigFileContent(string.Empty, path: repoPath); + var workingDirectoryConfigFilePath = SetupConfigFileContent(string.Empty, path: workingPath); + + var exception = Should.Throw(() => { configFileLocator.Verify(workingPath, repoPath, fileSystem); }); + + var expectedMessage = $"Ambiguous config file selection from '{workingDirectoryConfigFilePath}' and '{repositoryConfigFilePath}'"; + exception.Message.ShouldBe(expectedMessage); + } + + [Test] + public void NoWarnOnCustomYmlFile() + { + SetupConfigFileContent(string.Empty); + + var s = string.Empty; + Action action = info => { s = info; }; + using (Logger.AddLoggersTemporarily(action, action, action, action)) + { + ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); + } + s.Length.ShouldBe(0); + } + + [Test] + public void NoWarnOnCustomYmlFileOutsideRepoPath() + { + SetupConfigFileContent(string.Empty, path: @"c:\\Unrelated\\path"); + + var s = string.Empty; + Action action = info => { s = info; }; + using (Logger.AddLoggersTemporarily(action, action, action, action)) + { + ConfigurationProvider.Provide(repoPath, fileSystem, configFileLocator); + } + s.Length.ShouldBe(0); + } + + string SetupConfigFileContent(string text, string fileName = null, string path = null) + { + if (string.IsNullOrEmpty(fileName)) fileName = configFileLocator.FilePath; + var filePath = fileName; + if (!string.IsNullOrEmpty(path)) + filePath = Path.Combine(path, filePath); + fileSystem.WriteAllText(filePath, text); + return filePath; + } +} diff --git a/src/GitVersionCore/Configuration/ConfigFileLocator.cs b/src/GitVersionCore/Configuration/ConfigFileLocator.cs new file mode 100644 index 0000000000..bfd7206bef --- /dev/null +++ b/src/GitVersionCore/Configuration/ConfigFileLocator.cs @@ -0,0 +1,62 @@ +namespace GitVersion +{ + using GitVersion.Helpers; + using System.IO; + + public abstract class ConfigFileLocator + { + + public static readonly ConfigFileLocator Default = new DefaultConfigFileLocator(); + + public static ConfigFileLocator GetLocator(string filePath = null) => + !string.IsNullOrEmpty(filePath) ? new NamedConfigFileLocator(filePath) : Default; + + public abstract bool HasConfigFileAt(string workingDirectory, IFileSystem fileSystem); + + public abstract string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem); + + public abstract void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem); + + public string SelectConfigFilePath(GitPreparer gitPreparer, IFileSystem fileSystem) + { + var workingDirectory = gitPreparer.WorkingDirectory; + var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); + + if (HasConfigFileAt(workingDirectory, fileSystem)) + { + return GetConfigFilePath(workingDirectory, fileSystem); + } + + return GetConfigFilePath(projectRootDirectory, fileSystem); + } + + public Config ReadConfig(string workingDirectory, IFileSystem fileSystem) + { + var configFilePath = GetConfigFilePath(workingDirectory, fileSystem); + + if (fileSystem.Exists(configFilePath)) + { + var readAllText = fileSystem.ReadAllText(configFilePath); + LegacyConfigNotifier.Notify(new StringReader(readAllText)); + return ConfigSerialiser.Read(new StringReader(readAllText)); + } + + return new Config(); + } + + public void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) + { + if (!string.IsNullOrWhiteSpace(gitPreparer.TargetUrl)) + { + // Assuming this is a dynamic repository. At this stage it's unsure whether we have + // any .git info so we need to skip verification + return; + } + + var workingDirectory = gitPreparer.WorkingDirectory; + var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); + + Verify(workingDirectory, projectRootDirectory, fileSystem); + } + } +} diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index e9457ed364..a14147e73c 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -11,9 +11,6 @@ public class ConfigurationProvider { internal const string DefaultTagPrefix = "[vV]"; - public const string DefaultConfigFileName = "GitVersion.yml"; - public const string ObsoleteConfigFileName = "GitVersionConfig.yaml"; - public const string ReleaseBranchRegex = "^releases?[/-]"; public const string FeatureBranchRegex = "^features?[/-]"; public const string PullRequestRegex = @"^(pull|pull\-requests|pr)[/-]"; @@ -42,35 +39,22 @@ public class ConfigurationProvider private const IncrementStrategy DefaultIncrementStrategy = IncrementStrategy.Inherit; - public static Config Provide(GitPreparer gitPreparer, IFileSystem fileSystem, bool applyDefaults = true, Config overrideConfig = null) + public static Config Provide(GitPreparer gitPreparer, IFileSystem fileSystem, ConfigFileLocator configFileLocator, bool applyDefaults = true, Config overrideConfig = null, string configFilePath = null) { var workingDirectory = gitPreparer.WorkingDirectory; var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); - if (HasConfigFileAt(workingDirectory, fileSystem)) + if (configFileLocator.HasConfigFileAt(workingDirectory, fileSystem)) { - return Provide(workingDirectory, fileSystem, applyDefaults, overrideConfig); + return Provide(workingDirectory, fileSystem, configFileLocator, applyDefaults, overrideConfig); } - return Provide(projectRootDirectory, fileSystem, applyDefaults, overrideConfig); + return Provide(projectRootDirectory, fileSystem, configFileLocator, applyDefaults, overrideConfig); } - public static string SelectConfigFilePath(GitPreparer gitPreparer, IFileSystem fileSystem) + public static Config Provide(string workingDirectory, IFileSystem fileSystem, ConfigFileLocator configFileLocator, bool applyDefaults = true, Config overrideConfig = null) { - var workingDirectory = gitPreparer.WorkingDirectory; - var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); - - if (HasConfigFileAt(workingDirectory, fileSystem)) - { - return GetConfigFilePath(workingDirectory, fileSystem); - } - - return GetConfigFilePath(projectRootDirectory, fileSystem); - } - - public static Config Provide(string workingDirectory, IFileSystem fileSystem, bool applyDefaults = true, Config overrideConfig = null) - { - var readConfig = ReadConfig(workingDirectory, fileSystem); + var readConfig = configFileLocator.ReadConfig(workingDirectory, fileSystem); VerifyConfiguration(readConfig); if (applyDefaults) @@ -121,7 +105,7 @@ public static void ApplyDefaultsTo(Config config) new List(), defaultTag: "alpha", defaultIncrementStrategy: IncrementStrategy.Minor, - defaultVersioningMode: config.VersioningMode == VersioningMode.Mainline? VersioningMode.Mainline : VersioningMode.ContinuousDeployment, + defaultVersioningMode: config.VersioningMode == VersioningMode.Mainline ? VersioningMode.Mainline : VersioningMode.ContinuousDeployment, defaultTrackMergeTarget: true, tracksReleaseBranches: true); ApplyBranchDefaults(config, @@ -208,7 +192,7 @@ static BranchConfig GetOrCreateBranchDefaults(Config config, string branchKey) { if (!config.Branches.ContainsKey(branchKey)) { - var branchConfig = new BranchConfig {Name = branchKey}; + var branchConfig = new BranchConfig { Name = branchKey }; config.Branches.Add(branchKey, branchConfig); return branchConfig; } @@ -247,23 +231,9 @@ public static void ApplyBranchDefaults(Config config, branchConfig.PreReleaseWeight = branchConfig.PreReleaseWeight ?? defaultPreReleaseNumber; } - static Config ReadConfig(string workingDirectory, IFileSystem fileSystem) - { - var configFilePath = GetConfigFilePath(workingDirectory, fileSystem); - - if (fileSystem.Exists(configFilePath)) - { - var readAllText = fileSystem.ReadAllText(configFilePath); - LegacyConfigNotifier.Notify(new StringReader(readAllText)); - return ConfigSerialiser.Read(new StringReader(readAllText)); - } - - return new Config(); - } - - public static string GetEffectiveConfigAsString(string workingDirectory, IFileSystem fileSystem) + public static string GetEffectiveConfigAsString(string workingDirectory, IFileSystem fileSystem, ConfigFileLocator configFileLocator) { - var config = Provide(workingDirectory, fileSystem); + var config = Provide(workingDirectory, fileSystem, configFileLocator); var stringBuilder = new StringBuilder(); using (var stream = new StringWriter(stringBuilder)) { @@ -273,104 +243,10 @@ public static string GetEffectiveConfigAsString(string workingDirectory, IFileSy return stringBuilder.ToString(); } - public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) - { - if (!string.IsNullOrWhiteSpace(gitPreparer.TargetUrl)) - { - // Assuming this is a dynamic repository. At this stage it's unsure whether we have - // any .git info so we need to skip verification - return; - } - - var workingDirectory = gitPreparer.WorkingDirectory; - var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); - - Verify(workingDirectory, projectRootDirectory, fileSystem); - } - - public static void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) - { - if (fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) - { - WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); - return; - } - - WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); - WarnAboutObsoleteConfigFile(projectRootDirectory, fileSystem); - - WarnAboutAmbiguousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); - } - - static void WarnAboutAmbiguousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) - { - var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); - var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); - - bool hasConfigInWorkingDirectory = fileSystem.Exists(workingConfigFile); - bool hasConfigInProjectRootDirectory = fileSystem.Exists(projectRootConfigFile); - if (hasConfigInProjectRootDirectory && hasConfigInWorkingDirectory) - { - throw new WarningException(string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingConfigFile, projectRootConfigFile)); - } - } - - static string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) - { - var ymlPath = Path.Combine(workingDirectory, DefaultConfigFileName); - if (fileSystem.Exists(ymlPath)) - { - return ymlPath; - } - - var deprecatedPath = Path.Combine(workingDirectory, ObsoleteConfigFileName); - if (fileSystem.Exists(deprecatedPath)) - { - return deprecatedPath; - } - - return ymlPath; - } - - static bool HasConfigFileAt(string workingDirectory, IFileSystem fileSystem) - { - var defaultConfigFilePath = Path.Combine(workingDirectory, DefaultConfigFileName); - if (fileSystem.Exists(defaultConfigFilePath)) - { - return true; - } - - var deprecatedConfigFilePath = Path.Combine(workingDirectory, ObsoleteConfigFileName); - if (fileSystem.Exists(deprecatedConfigFilePath)) - { - return true; - } - - return false; - } - - static void WarnAboutObsoleteConfigFile(string workingDirectory, IFileSystem fileSystem) - { - var deprecatedConfigFilePath = Path.Combine(workingDirectory, ObsoleteConfigFileName); - if (!fileSystem.Exists(deprecatedConfigFilePath)) - { - return; - } - - var defaultConfigFilePath = Path.Combine(workingDirectory, DefaultConfigFileName); - if (fileSystem.Exists(defaultConfigFilePath)) - { - Logger.WriteWarning(string.Format("Ambiguous config files at '{0}': '{1}' (deprecated) and '{2}'. Will be used '{2}'", workingDirectory, ObsoleteConfigFileName, DefaultConfigFileName)); - return; - } - - Logger.WriteWarning(string.Format("'{0}' is deprecated, use '{1}' instead.", deprecatedConfigFilePath, DefaultConfigFileName)); - } - - public static void Init(string workingDirectory, IFileSystem fileSystem, IConsole console) + public static void Init(string workingDirectory, IFileSystem fileSystem, IConsole console, ConfigFileLocator configFileLocator) { - var configFilePath = GetConfigFilePath(workingDirectory, fileSystem); - var currentConfiguration = Provide(workingDirectory, fileSystem, applyDefaults: false); + var configFilePath = configFileLocator.GetConfigFilePath(workingDirectory, fileSystem); + var currentConfiguration = Provide(workingDirectory, fileSystem, applyDefaults: false, configFileLocator: configFileLocator); var config = new ConfigInitWizard(console, fileSystem).Run(currentConfiguration, workingDirectory); if (config == null) return; diff --git a/src/GitVersionCore/Configuration/DefaultConfigFileLocator.cs b/src/GitVersionCore/Configuration/DefaultConfigFileLocator.cs new file mode 100644 index 0000000000..e63e34965e --- /dev/null +++ b/src/GitVersionCore/Configuration/DefaultConfigFileLocator.cs @@ -0,0 +1,94 @@ +namespace GitVersion +{ + using GitVersion.Helpers; + using System.IO; + + public class DefaultConfigFileLocator : ConfigFileLocator + { + + public const string DefaultFileName = "GitVersion.yml"; + + public const string ObsoleteFileName = "GitVersionConfig.yaml"; + + public override bool HasConfigFileAt(string workingDirectory, IFileSystem fileSystem) + { + var defaultConfigFilePath = Path.Combine(workingDirectory, DefaultFileName); + if (fileSystem.Exists(defaultConfigFilePath)) + { + return true; + } + + var deprecatedConfigFilePath = Path.Combine(workingDirectory, ObsoleteFileName); + if (fileSystem.Exists(deprecatedConfigFilePath)) + { + return true; + } + + return false; + } + + public override string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) + { + var ymlPath = Path.Combine(workingDirectory, DefaultFileName); + if (fileSystem.Exists(ymlPath)) + { + return ymlPath; + } + + var deprecatedPath = Path.Combine(workingDirectory, ObsoleteFileName); + if (fileSystem.Exists(deprecatedPath)) + { + return deprecatedPath; + } + + return ymlPath; + } + + public override void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + { + if (fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) + { + WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); + return; + } + + WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); + WarnAboutObsoleteConfigFile(projectRootDirectory, fileSystem); + + WarnAboutAmbiguousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); + } + + private void WarnAboutAmbiguousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + { + var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); + var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); + + bool hasConfigInWorkingDirectory = fileSystem.Exists(workingConfigFile); + bool hasConfigInProjectRootDirectory = fileSystem.Exists(projectRootConfigFile); + if (hasConfigInProjectRootDirectory && hasConfigInWorkingDirectory) + { + throw new WarningException(string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingConfigFile, projectRootConfigFile)); + } + } + + private void WarnAboutObsoleteConfigFile(string workingDirectory, IFileSystem fileSystem) + { + var deprecatedConfigFilePath = Path.Combine(workingDirectory, ObsoleteFileName); + if (!fileSystem.Exists(deprecatedConfigFilePath)) + { + return; + } + + var defaultConfigFilePath = Path.Combine(workingDirectory, DefaultFileName); + if (fileSystem.Exists(defaultConfigFilePath)) + { + Logger.WriteWarning(string.Format("Ambiguous config files at '{0}': '{1}' (deprecated) and '{2}'. Will be used '{2}'", workingDirectory, ObsoleteFileName, DefaultFileName)); + return; + } + + Logger.WriteWarning(string.Format("'{0}' is deprecated, use '{1}' instead.", deprecatedConfigFilePath, DefaultFileName)); + } + + } + +} diff --git a/src/GitVersionCore/Configuration/NamedConfigFileLocator.cs b/src/GitVersionCore/Configuration/NamedConfigFileLocator.cs new file mode 100644 index 0000000000..5a5deb0010 --- /dev/null +++ b/src/GitVersionCore/Configuration/NamedConfigFileLocator.cs @@ -0,0 +1,47 @@ +namespace GitVersion +{ + + using System; + + using GitVersion.Helpers; + using System.IO; + + public class NamedConfigFileLocator : ConfigFileLocator + { + + public NamedConfigFileLocator(string filePath) + { + if (string.IsNullOrEmpty(filePath)) throw new ArgumentNullException(nameof(filePath), "Empty file path provided!"); + FilePath = filePath; + } + + public string FilePath { get; } + + public override bool HasConfigFileAt(string workingDirectory, IFileSystem fileSystem) => + fileSystem.Exists(Path.Combine(workingDirectory, FilePath)); + + public override string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) => + Path.Combine(workingDirectory, FilePath); + + public override void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + { + if (!Path.IsPathRooted(FilePath)) + { + WarnAboutAmbiguousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); + } + } + + private void WarnAboutAmbiguousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + { + var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); + var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); + + var hasConfigInWorkingDirectory = fileSystem.Exists(workingConfigFile); + var hasConfigInProjectRootDirectory = fileSystem.Exists(projectRootConfigFile); + if (hasConfigInProjectRootDirectory && hasConfigInWorkingDirectory) + { + throw new WarningException(string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingConfigFile, projectRootConfigFile)); + } + } + } +} diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index 9610798196..844c0a84f5 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -8,13 +8,13 @@ namespace GitVersion public class ExecuteCore { readonly IFileSystem fileSystem; + readonly ConfigFileLocator configFileLocator; readonly GitVersionCache gitVersionCache; - public ExecuteCore(IFileSystem fileSystem) + public ExecuteCore(IFileSystem fileSystem, ConfigFileLocator configFileLocator = null) { - if (fileSystem == null) throw new ArgumentNullException("fileSystem"); - - this.fileSystem = fileSystem; + this.fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + this.configFileLocator = configFileLocator ?? ConfigFileLocator.Default; gitVersionCache = new GitVersionCache(fileSystem); } @@ -50,7 +50,7 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory)); } - var cacheKey = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, overrideConfig); + var cacheKey = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, overrideConfig, configFileLocator); var versionVariables = noCache ? default(VersionVariables) : gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer, cacheKey); if (versionVariables == null) { @@ -103,7 +103,7 @@ static string ResolveCurrentBranch(IBuildServer buildServer, string targetBranch VersionVariables ExecuteInternal(string targetBranch, string commitId, GitPreparer gitPreparer, IBuildServer buildServer, Config overrideConfig = null) { var versionFinder = new GitVersionFinder(); - var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); + var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig, configFileLocator: configFileLocator); return gitPreparer.WithRepository(repo => { diff --git a/src/GitVersionCore/GitVersionCacheKeyFactory.cs b/src/GitVersionCore/GitVersionCacheKeyFactory.cs index a918d67001..dfd917ac2d 100644 --- a/src/GitVersionCore/GitVersionCacheKeyFactory.cs +++ b/src/GitVersionCore/GitVersionCacheKeyFactory.cs @@ -1,4 +1,4 @@ -namespace GitVersion +namespace GitVersion { using Helpers; using System; @@ -10,10 +10,10 @@ class GitVersionCacheKeyFactory { - public static GitVersionCacheKey Create(IFileSystem fileSystem, GitPreparer gitPreparer, Config overrideConfig) + public static GitVersionCacheKey Create(IFileSystem fileSystem, GitPreparer gitPreparer, Config overrideConfig, ConfigFileLocator configFileLocator) { var gitSystemHash = GetGitSystemHash(gitPreparer); - var configFileHash = GetConfigFileHash(fileSystem, gitPreparer); + var configFileHash = GetConfigFileHash(fileSystem, gitPreparer, configFileLocator); var repositorySnapshotHash = GetRepositorySnapshotHash(gitPreparer); var overrideConfigHash = GetOverrideConfigHash(overrideConfig); @@ -155,11 +155,11 @@ private static string GetOverrideConfigHash(Config overrideConfig) return GetHash(configContent); } - private static string GetConfigFileHash(IFileSystem fileSystem, GitPreparer gitPreparer) + private static string GetConfigFileHash(IFileSystem fileSystem, GitPreparer gitPreparer, ConfigFileLocator configFileLocator) { // will return the same hash even when config file will be moved // from workingDirectory to rootProjectDirectory. It's OK. Config essentially is the same. - var configFilePath = ConfigurationProvider.SelectConfigFilePath(gitPreparer, fileSystem); + var configFilePath = configFileLocator.SelectConfigFilePath(gitPreparer, fileSystem); if (!fileSystem.Exists(configFilePath)) { return string.Empty; diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 9fe03d7217..f16fb1faba 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -78,6 +78,13 @@ public static Arguments ParseArguments(List commandLineArguments) continue; } + if (name.IsSwitch("config")) + { + EnsureArgumentValueCount(values); + arguments.ConfigFileLocator = new NamedConfigFileLocator(value); + continue; + } + if (name.IsSwitch("targetpath")) { EnsureArgumentValueCount(values); diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 04689a4438..62834e2154 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -17,6 +17,7 @@ public Arguments() public Config OverrideConfig; public bool HasOverrideConfig { get; set; } + public ConfigFileLocator ConfigFileLocator { get; set; } = ConfigFileLocator.GetLocator(); public string TargetPath; diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 3a5bda3b97..5cd663cfcd 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -33,6 +33,7 @@ path The directory containing .git. If not defined current directory /showvariable Used in conjuntion with /output json, will output just a particular variable. eg /output json /showvariable SemVer - will output `1.2.3+beta.4` /l Path to logfile. + /config Path to config file (defaults to GitVersion.yml) /showconfig Outputs the effective GitVersion config (defaults + custom from GitVersion.yml) in yaml format /overrideconfig Overrides GitVersion config values inline (semicolon-separated key value pairs e.g. /overrideconfig tag-prefix=Foo) Currently supported config overrides: tag-prefix diff --git a/src/GitVersionExe/Program.cs b/src/GitVersionExe/Program.cs index e605eb3dd7..4b37bb0f2c 100644 --- a/src/GitVersionExe/Program.cs +++ b/src/GitVersionExe/Program.cs @@ -96,12 +96,12 @@ static int VerifyArgumentsAndRun() if (arguments.Init) { - ConfigurationProvider.Init(arguments.TargetPath, fileSystem, new ConsoleAdapter()); + ConfigurationProvider.Init(arguments.TargetPath, fileSystem, new ConsoleAdapter(), arguments.ConfigFileLocator); return 0; } if (arguments.ShowConfig) { - Console.WriteLine(ConfigurationProvider.GetEffectiveConfigAsString(arguments.TargetPath, fileSystem)); + Console.WriteLine(ConfigurationProvider.GetEffectiveConfigAsString(arguments.TargetPath, fileSystem, arguments.ConfigFileLocator)); return 0; } @@ -149,7 +149,7 @@ static int VerifyArgumentsAndRun() static void VerifyConfiguration(Arguments arguments, IFileSystem fileSystem) { var gitPreparer = new GitPreparer(arguments.TargetUrl, arguments.DynamicRepositoryLocation, arguments.Authentication, arguments.NoFetch, arguments.TargetPath); - ConfigurationProvider.Verify(gitPreparer, fileSystem); + arguments.ConfigFileLocator.Verify(gitPreparer, fileSystem); } static void ConfigureLogging(Arguments arguments) diff --git a/src/GitVersionExe/SpecifiedArgumentRunner.cs b/src/GitVersionExe/SpecifiedArgumentRunner.cs index f8f7ed5b80..31d99c0a0c 100644 --- a/src/GitVersionExe/SpecifiedArgumentRunner.cs +++ b/src/GitVersionExe/SpecifiedArgumentRunner.cs @@ -24,7 +24,7 @@ public static void Run(Arguments arguments, IFileSystem fileSystem) var overrideConfig = arguments.HasOverrideConfig ? arguments.OverrideConfig : null; var noCache = arguments.NoCache; - var executeCore = new ExecuteCore(fileSystem); + var executeCore = new ExecuteCore(fileSystem, arguments.ConfigFileLocator); var variables = executeCore.ExecuteGitVersion(targetUrl, dynamicRepositoryLocation, authentication, targetBranch, noFetch, targetPath, commitId, overrideConfig, noCache); if (arguments.Output == OutputType.BuildServer) diff --git a/src/GitVersionTask.MsBuild/GitVersionTaskBase.cs b/src/GitVersionTask.MsBuild/GitVersionTaskBase.cs index 76a6ef68c0..c174a1f714 100644 --- a/src/GitVersionTask.MsBuild/GitVersionTaskBase.cs +++ b/src/GitVersionTask.MsBuild/GitVersionTaskBase.cs @@ -8,6 +8,8 @@ public abstract class GitVersionTaskBase : Task [Required] public string SolutionDirectory { get; set; } + public string ConfigFilePath { get; set; } + public bool NoFetch { get; set; } } -} \ No newline at end of file +} diff --git a/src/GitVersionTask/GitVersionTasks.cs b/src/GitVersionTask/GitVersionTasks.cs index e8b9c9ada2..7bdc1b289f 100644 --- a/src/GitVersionTask/GitVersionTasks.cs +++ b/src/GitVersionTask/GitVersionTasks.cs @@ -108,6 +108,6 @@ private static bool ExecuteGitVersionTask(T task, Action action) } private static bool GetVersionVariables(GitVersionTaskBase task, out VersionVariables versionVariables) - => new ExecuteCore(new FileSystem()).TryGetVersion(task.SolutionDirectory, out versionVariables, task.NoFetch, new Authentication()); + => new ExecuteCore(new FileSystem(), ConfigFileLocator.GetLocator(task.ConfigFilePath)).TryGetVersion(task.SolutionDirectory, out versionVariables, task.NoFetch, new Authentication()); } } diff --git a/src/GitVersionTask/build/GitVersionTask.targets b/src/GitVersionTask/build/GitVersionTask.targets index a0cbe5896a..5ca53bfe64 100644 --- a/src/GitVersionTask/build/GitVersionTask.targets +++ b/src/GitVersionTask/build/GitVersionTask.targets @@ -7,7 +7,7 @@ - + @@ -15,6 +15,7 @@ - + diff --git a/src/GitVersionTask/buildMultiTargeting/GitVersionTask.targets b/src/GitVersionTask/buildMultiTargeting/GitVersionTask.targets index a31cac6368..2448f12d00 100644 --- a/src/GitVersionTask/buildMultiTargeting/GitVersionTask.targets +++ b/src/GitVersionTask/buildMultiTargeting/GitVersionTask.targets @@ -4,7 +4,7 @@ - + @@ -22,7 +22,7 @@ - + diff --git a/src/GitVersionTfsTask/GitVersion.ts b/src/GitVersionTfsTask/GitVersion.ts index b5e3510991..91a2975716 100644 --- a/src/GitVersionTfsTask/GitVersion.ts +++ b/src/GitVersionTfsTask/GitVersion.ts @@ -7,6 +7,7 @@ export class GitVersionTask { execOptions: tr.IExecOptions; preferBundledVersion: boolean; + configFilePath: string; updateAssemblyInfo: boolean; updateAssemblyInfoFilename: string; @@ -20,6 +21,7 @@ export class GitVersionTask { constructor() { this.preferBundledVersion = tl.getBoolInput('preferBundledVersion') || true; + this.configFilePath = tl.getPathInput('configFilePath'); this.updateAssemblyInfo = tl.getBoolInput('updateAssemblyInfo'); this.updateAssemblyInfoFilename = tl.getInput('updateAssemblyInfoFilename'); @@ -56,6 +58,10 @@ export class GitVersionTask { "buildserver", "/nofetch"]); + if (this.configFilePath) { + exe.arg(["/config", this.configFilePath]); + } + if (this.updateAssemblyInfo) { exe.arg("/updateassemblyinfo"); if (this.updateAssemblyInfoFilename) { diff --git a/src/GitVersionTfsTask/GitVersionTask/task.json b/src/GitVersionTfsTask/GitVersionTask/task.json index d1bdbf6c6e..3fa32246cc 100644 --- a/src/GitVersionTfsTask/GitVersionTask/task.json +++ b/src/GitVersionTfsTask/GitVersionTask/task.json @@ -42,6 +42,13 @@ "defaultValue": "true", "required": false, "helpMarkDown": "If checked it will prefer the bundled version over a version found in path" + }, { + "name": "configFilePath", + "type": "filePath", + "label": "Config file", + "defaultValue": "", + "required": false, + "helpMarkDown": "Optional path to config file (defaults to GitVersion.yml)" }, { "name": "updateAssemblyInfo", "type": "boolean",