From f31647c3ae21a57dea98fca380c6dd0fe9cea19a Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 4 Jun 2016 19:10:06 +0300 Subject: [PATCH 01/20] checking ambigous and obsolete config files at workingDirectory and rootProjectDirectory --- src/GitVersionCore.Tests/TestFileSystem.cs | 5 ++ .../Configuration/ConfigurationProvider.cs | 54 +++++++++++++++++-- src/GitVersionCore/ExecuteCore.cs | 2 +- src/GitVersionCore/GitPreparer.cs | 5 ++ src/GitVersionCore/Helpers/FileSystem.cs | 15 ++++++ src/GitVersionCore/Helpers/IFileSystem.cs | 2 + src/GitVersionExe/Program.cs | 7 +++ 7 files changed, 85 insertions(+), 5 deletions(-) diff --git a/src/GitVersionCore.Tests/TestFileSystem.cs b/src/GitVersionCore.Tests/TestFileSystem.cs index 2828223d03..f78d9c890c 100644 --- a/src/GitVersionCore.Tests/TestFileSystem.cs +++ b/src/GitVersionCore.Tests/TestFileSystem.cs @@ -101,4 +101,9 @@ public long GetLastDirectoryWrite(string path) { return 1; } + + public bool PathsEqual(string path, string otherPath) + { + return path == otherPath; + } } \ No newline at end of file diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index dc6ecf4741..39c62be7a5 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -1,6 +1,7 @@ namespace GitVersion { using System.Collections.Generic; + using System.ComponentModel; using System.IO; using System.Linq; using System.Text; @@ -151,25 +152,70 @@ public static string GetEffectiveConfigAsString(string gitDirectory, IFileSystem return stringBuilder.ToString(); } + public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) + { + var workingDirectory = gitPreparer.WorkingDirectory; + var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); + + if(fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) + { + WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); + return; + } + + WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); + WarnAboutObsoleteConfigFile(projectRootDirectory, 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("Ambigous config file selection from '{0}' and '{1}'", workingConfigFile, projectRootConfigFile)); + } + } + + public static readonly string DefaultConfigFileName = "GitVersion.yml"; + public static readonly string ObsoleteConfigFileName = "GitVersionConfig.yaml"; + static string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) { - var ymlPath = Path.Combine(workingDirectory, "GitVersion.yml"); + var ymlPath = Path.Combine(workingDirectory, DefaultConfigFileName); if (fileSystem.Exists(ymlPath)) { return ymlPath; } - var deprecatedPath = Path.Combine(workingDirectory, "GitVersionConfig.yaml"); + var deprecatedPath = Path.Combine(workingDirectory, ObsoleteConfigFileName); if (fileSystem.Exists(deprecatedPath)) { - Logger.WriteWarning("'GitVersionConfig.yaml' is deprecated, use 'GitVersion.yml' instead."); - return deprecatedPath; } return ymlPath; } + static bool WarnAboutObsoleteConfigFile(string workingDirectory, IFileSystem fileSystem) + { + var deprecatedConfigFilePath = Path.Combine(workingDirectory, ObsoleteConfigFileName); + if (!fileSystem.Exists(deprecatedConfigFilePath)) + { + return false; + } + + var defaultConfigFilePath = Path.Combine(workingDirectory, DefaultConfigFileName); + if (fileSystem.Exists(defaultConfigFilePath)) + { + Logger.WriteWarning(string.Format("Ambigous config files at '{0}': '{1}' (deprecated) and '{2}'. Will be used '{2}'", workingDirectory, ObsoleteConfigFileName, DefaultConfigFileName)); + return true; + } + + Logger.WriteWarning(string.Format("'{0}' is deprecated, use '{1}' instead.", deprecatedConfigFilePath, DefaultConfigFileName)); + return true; + } + public static void Init(string workingDirectory, IFileSystem fileSystem, IConsole console) { var configFilePath = GetConfigFilePath(workingDirectory, fileSystem); diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index b0108faf6c..132d22c028 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -95,7 +95,7 @@ VersionVariables ExecuteInternal(string targetBranch, string commitId, IReposito gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository)); var versionFinder = new GitVersionFinder(); - var configuration = ConfigurationProvider.Provide(projectRoot, fileSystem, overrideConfig: overrideConfig); + var configuration = ConfigurationProvider.Provide(projectRoot, fileSystem, overrideConfig: overrideConfig); var gitVersionContext = new GitVersionContext(repo, configuration, commitId : commitId); var semanticVersion = versionFinder.FindVersion(gitVersionContext); diff --git a/src/GitVersionCore/GitPreparer.cs b/src/GitVersionCore/GitPreparer.cs index 5c9a7451f4..46d46db787 100644 --- a/src/GitVersionCore/GitPreparer.cs +++ b/src/GitVersionCore/GitPreparer.cs @@ -29,6 +29,11 @@ public GitPreparer(string targetUrl, string dynamicRepositoryLocation, Authentic this.targetPath = targetPath.TrimEnd('/', '\\'); } + public string WorkingDirectory + { + get { return targetPath; } + } + public bool IsDynamicGitRepository { get { return !string.IsNullOrWhiteSpace(DynamicGitRepositoryPath); } diff --git a/src/GitVersionCore/Helpers/FileSystem.cs b/src/GitVersionCore/Helpers/FileSystem.cs index 93b9cbbba6..9bc62b5cdf 100644 --- a/src/GitVersionCore/Helpers/FileSystem.cs +++ b/src/GitVersionCore/Helpers/FileSystem.cs @@ -1,11 +1,14 @@ namespace GitVersion.Helpers { + using System; using System.Collections.Generic; using System.IO; using System.Linq; public class FileSystem : IFileSystem { + private static readonly bool runningOnMono = Type.GetType("Mono.Runtime") != null; + public void Copy(string @from, string to, bool overwrite) { File.Copy(from, to, overwrite); @@ -70,5 +73,17 @@ public long GetLastDirectoryWrite(string path) .Max() .Ticks; } + + public bool PathsEqual(string path, string otherPath) + { + var comparison = runningOnMono + ? StringComparison.InvariantCulture + : StringComparison.InvariantCultureIgnoreCase; + + return string.Equals( + Path.GetFullPath(path).TrimEnd('\\').TrimEnd('/'), + Path.GetFullPath(otherPath).TrimEnd('\\').TrimEnd('/'), + comparison); + } } } \ No newline at end of file diff --git a/src/GitVersionCore/Helpers/IFileSystem.cs b/src/GitVersionCore/Helpers/IFileSystem.cs index ea4e7863b4..edd1dc78ce 100644 --- a/src/GitVersionCore/Helpers/IFileSystem.cs +++ b/src/GitVersionCore/Helpers/IFileSystem.cs @@ -17,5 +17,7 @@ public interface IFileSystem void CreateDirectory(string path); bool DirectoryExists(string path); long GetLastDirectoryWrite(string path); + + bool PathsEqual(string path, string otherPath); } } \ No newline at end of file diff --git a/src/GitVersionExe/Program.cs b/src/GitVersionExe/Program.cs index e9198d827f..3c97c6f537 100644 --- a/src/GitVersionExe/Program.cs +++ b/src/GitVersionExe/Program.cs @@ -70,6 +70,8 @@ static int VerifyArgumentsAndRun() } ConfigureLogging(arguments); + VerifyConfiguration(arguments, fileSystem); + if (arguments.Init) { ConfigurationProvider.Init(arguments.TargetPath, fileSystem, new ConsoleAdapter()); @@ -114,6 +116,11 @@ static int VerifyArgumentsAndRun() return 0; } + private 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); + } static void ConfigureLogging(Arguments arguments) { From e26c557511de657f06e93a3fa41047534357ac3c Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 4 Jun 2016 19:19:18 +0300 Subject: [PATCH 02/20] select config file from working directory first and only then use project root directory --- .../Configuration/ConfigurationProvider.cs | 36 +++++++++++++++++-- src/GitVersionCore/ExecuteCore.cs | 2 +- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 39c62be7a5..20499d01e2 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -12,6 +12,19 @@ public class ConfigurationProvider { internal const string DefaultTagPrefix = "[vV]"; + public static Config Provide(GitPreparer gitPreparer, IFileSystem fileSystem, bool applyDefaults = true, Config overrideConfig = null) + { + var workingDirectory = gitPreparer.WorkingDirectory; + var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); + + if (HasConfigFileAt(workingDirectory, fileSystem)) + { + return Provide(workingDirectory, fileSystem, applyDefaults, overrideConfig); + } + + return Provide(projectRootDirectory, fileSystem, applyDefaults, overrideConfig); + } + public static Config Provide(string workingDirectory, IFileSystem fileSystem, bool applyDefaults = true, Config overrideConfig = null) { var readConfig = ReadConfig(workingDirectory, fileSystem); @@ -140,9 +153,9 @@ static Config ReadConfig(string workingDirectory, IFileSystem fileSystem) return new Config(); } - public static string GetEffectiveConfigAsString(string gitDirectory, IFileSystem fileSystem) + public static string GetEffectiveConfigAsString(string workingDirectory, IFileSystem fileSystem) { - var config = Provide(gitDirectory, fileSystem); + var config = Provide(workingDirectory, fileSystem); var stringBuilder = new StringBuilder(); using (var stream = new StringWriter(stringBuilder)) { @@ -180,7 +193,7 @@ public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) public static readonly string DefaultConfigFileName = "GitVersion.yml"; public static readonly string ObsoleteConfigFileName = "GitVersionConfig.yaml"; - static string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) + public static string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) { var ymlPath = Path.Combine(workingDirectory, DefaultConfigFileName); if (fileSystem.Exists(ymlPath)) @@ -197,6 +210,23 @@ static string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) return ymlPath; } + public 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 bool WarnAboutObsoleteConfigFile(string workingDirectory, IFileSystem fileSystem) { var deprecatedConfigFilePath = Path.Combine(workingDirectory, ObsoleteConfigFileName); diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index 132d22c028..59f61c5171 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -95,7 +95,7 @@ VersionVariables ExecuteInternal(string targetBranch, string commitId, IReposito gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository)); var versionFinder = new GitVersionFinder(); - var configuration = ConfigurationProvider.Provide(projectRoot, fileSystem, overrideConfig: overrideConfig); + var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); var gitVersionContext = new GitVersionContext(repo, configuration, commitId : commitId); var semanticVersion = versionFinder.FindVersion(gitVersionContext); From c4d8a4de218081151990e2c6f60be7a133369022 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 4 Jun 2016 20:29:59 +0300 Subject: [PATCH 03/20] added tests for verification config files + a bit of refactoring --- .../ConfigProviderTests.cs | 68 +++++++++++++++---- .../Configuration/ConfigurationProvider.cs | 24 ++++++- src/GitVersionCore/ExecuteCore.cs | 28 ++++---- src/GitVersionCore/GitPreparer.cs | 9 +++ src/GitVersionCore/GitVersionCache.cs | 34 +++++++--- 5 files changed, 124 insertions(+), 39 deletions(-) diff --git a/src/GitVersionCore.Tests/ConfigProviderTests.cs b/src/GitVersionCore.Tests/ConfigProviderTests.cs index a9136a2bc7..312c15b4a7 100644 --- a/src/GitVersionCore.Tests/ConfigProviderTests.cs +++ b/src/GitVersionCore.Tests/ConfigProviderTests.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; @@ -12,14 +13,19 @@ [TestFixture] public class ConfigProviderTests { + private const string DefaultRepoPath = "c:\\MyGitRepo"; + private const string DefaultWorkingPath = "c:\\MyGitRepo\\Working"; + string repoPath; + string workingPath; IFileSystem fileSystem; [SetUp] public void Setup() { fileSystem = new TestFileSystem(); - repoPath = "c:\\MyGitRepo"; + repoPath = DefaultRepoPath; + workingPath = DefaultWorkingPath; } [Test] @@ -147,8 +153,8 @@ public void NextVersionCanHavePatch() } [Test] - [Category("NoMono")] - [Description("Won't run on Mono due to source information not being available for ShouldMatchApproved.")] + [NUnit.Framework.Category("NoMono")] + [NUnit.Framework.Description("Won't run on Mono due to source information not being available for ShouldMatchApproved.")] [MethodImpl(MethodImplOptions.NoInlining)] public void CanWriteOutEffectiveConfiguration() { @@ -228,18 +234,51 @@ public void VerifyAliases() propertiesMissingAlias.ShouldBeEmpty(); } - [Test] - public void WarnOnExistingGitVersionConfigYamlFile() + [TestCase(DefaultRepoPath)] + [TestCase(DefaultWorkingPath)] + public void WarnOnExistingGitVersionConfigYamlFile(string path) { - SetupConfigFileContent(string.Empty, "GitVersionConfig.yaml"); + SetupConfigFileContent(string.Empty, ConfigurationProvider.ObsoleteConfigFileName, path); - var s = string.Empty; - Action action = info => { s = info; }; + var logOutput = string.Empty; + Action action = info => { logOutput = info; }; Logger.SetLoggers(action, action, action); - ConfigurationProvider.Provide(repoPath, fileSystem); + ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); - s.Contains("'GitVersionConfig.yaml' is deprecated, use 'GitVersion.yml' instead.").ShouldBe(true); + 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 WarnOnAmbigousConfigFilesAtTheSameProjectRootDirectory(string path) + { + SetupConfigFileContent(string.Empty, ConfigurationProvider.ObsoleteConfigFileName, path); + SetupConfigFileContent(string.Empty, ConfigurationProvider.DefaultConfigFileName, path); + + var logOutput = string.Empty; + Action action = info => { logOutput = info; }; + Logger.SetLoggers(action, action, action); + + ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); + + var configFileDeprecatedWarning = string.Format("Ambigous 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 ThrowsExceptionOnAmbigousConfigFileLocation(string repoConfigFile, string workingConfigFile) + { + SetupConfigFileContent(string.Empty, repoConfigFile, repoPath); + SetupConfigFileContent(string.Empty, workingConfigFile, workingPath); + + Should.Throw(() => { + ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); + }); } [Test] @@ -256,8 +295,13 @@ public void NoWarnOnGitVersionYmlFile() s.Length.ShouldBe(0); } - void SetupConfigFileContent(string text, string fileName = "GitVersion.yml") + void SetupConfigFileContent(string text, string fileName = ConfigurationProvider.DefaultConfigFileName) + { + SetupConfigFileContent(text, fileName, repoPath); + } + + void SetupConfigFileContent(string text, string fileName, string path) { - fileSystem.WriteAllText(Path.Combine(repoPath, fileName), text); + fileSystem.WriteAllText(Path.Combine(path, fileName), text); } } \ No newline at end of file diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 20499d01e2..1e36c36245 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -12,6 +12,9 @@ public class ConfigurationProvider { internal const string DefaultTagPrefix = "[vV]"; + public const string DefaultConfigFileName = "GitVersion.yml"; + public const string ObsoleteConfigFileName = "GitVersionConfig.yaml"; + public static Config Provide(GitPreparer gitPreparer, IFileSystem fileSystem, bool applyDefaults = true, Config overrideConfig = null) { var workingDirectory = gitPreparer.WorkingDirectory; @@ -25,6 +28,19 @@ public static Config Provide(GitPreparer gitPreparer, IFileSystem fileSystem, bo return Provide(projectRootDirectory, fileSystem, applyDefaults, overrideConfig); } + public static 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 static Config Provide(string workingDirectory, IFileSystem fileSystem, bool applyDefaults = true, Config overrideConfig = null) { var readConfig = ReadConfig(workingDirectory, fileSystem); @@ -170,6 +186,11 @@ public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) 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); @@ -190,9 +211,6 @@ public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) } } - public static readonly string DefaultConfigFileName = "GitVersion.yml"; - public static readonly string ObsoleteConfigFileName = "GitVersionConfig.yaml"; - public static string GetConfigFilePath(string workingDirectory, IFileSystem fileSystem) { var ymlPath = Path.Combine(workingDirectory, DefaultConfigFileName); diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index 59f61c5171..b0aba1c7e6 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -48,18 +48,15 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi // TODO Link to wiki article throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory)); } - - using (var repo = GetRepository(dotGitDirectory)) - { - var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(repo, dotGitDirectory); - if (versionVariables == null) - { - versionVariables = ExecuteInternal(targetBranch, commitId, repo, gitPreparer, projectRoot, buildServer, overrideConfig: overrideConfig); - gitVersionCache.WriteVariablesToDiskCache(repo, dotGitDirectory, versionVariables); - } - return versionVariables; + var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer); + if (versionVariables == null) + { + versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); + gitVersionCache.WriteVariablesToDiskCache(gitPreparer, versionVariables); } + + return versionVariables; } public bool TryGetVersion(string directory, out VersionVariables versionVariables, bool noFetch, Authentication authentication) @@ -90,17 +87,20 @@ static string ResolveCurrentBranch(IBuildServer buildServer, string targetBranch return currentBranch; } - VersionVariables ExecuteInternal(string targetBranch, string commitId, IRepository repo, GitPreparer gitPreparer, string projectRoot, IBuildServer buildServer, Config overrideConfig = null) + VersionVariables ExecuteInternal(string targetBranch, string commitId, GitPreparer gitPreparer, IBuildServer buildServer, Config overrideConfig = null) { gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository)); var versionFinder = new GitVersionFinder(); var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); - var gitVersionContext = new GitVersionContext(repo, configuration, commitId : commitId); - var semanticVersion = versionFinder.FindVersion(gitVersionContext); + return gitPreparer.WithRepository(repo => + { + var gitVersionContext = new GitVersionContext(repo, configuration, commitId: commitId); + var semanticVersion = versionFinder.FindVersion(gitVersionContext); - return VariableProvider.GetVariablesFor(semanticVersion, gitVersionContext.Configuration, gitVersionContext.IsCurrentCommitTagged); + return VariableProvider.GetVariablesFor(semanticVersion, gitVersionContext.Configuration, gitVersionContext.IsCurrentCommitTagged); + }); } IRepository GetRepository(string gitDirectory) diff --git a/src/GitVersionCore/GitPreparer.cs b/src/GitVersionCore/GitPreparer.cs index 46d46db787..d54958139a 100644 --- a/src/GitVersionCore/GitPreparer.cs +++ b/src/GitVersionCore/GitPreparer.cs @@ -14,6 +14,7 @@ public class GitPreparer bool noFetch; string targetPath; + public GitPreparer(string targetPath) : this(null, null, null, false, targetPath) { } public GitPreparer(string targetUrl, string dynamicRepositoryLocation, Authentication authentication, bool noFetch, string targetPath) { this.targetUrl = targetUrl; @@ -57,6 +58,14 @@ public void Initialise(bool normaliseGitDirectory, string currentBranch) DynamicGitRepositoryPath = CreateDynamicRepository(tempRepositoryPath, authentication, targetUrl, currentBranch, noFetch); } + public TResult WithRepository(Func action) + { + using (IRepository repo = new Repository(GetDotGitDirectory())) + { + return action(repo); + } + } + static string CalculateTemporaryRepositoryPath(string targetUrl, string dynamicRepositoryLocation) { var userTemp = dynamicRepositoryLocation ?? Path.GetTempPath(); diff --git a/src/GitVersionCore/GitVersionCache.cs b/src/GitVersionCore/GitVersionCache.cs index a22623430d..95585633f1 100644 --- a/src/GitVersionCore/GitVersionCache.cs +++ b/src/GitVersionCore/GitVersionCache.cs @@ -19,9 +19,10 @@ public GitVersionCache(IFileSystem fileSystem) this.fileSystem = fileSystem; } - public void WriteVariablesToDiskCache(IRepository repo, string gitDir, VersionVariables variablesFromCache) + public void WriteVariablesToDiskCache(GitPreparer gitPreparer, VersionVariables variablesFromCache) { - var cacheFileName = GetCacheFileName(GetKey(repo, gitDir), GetCacheDir(gitDir)); + var cacheDir = PrepareCacheDirectory(gitPreparer); + var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); variablesFromCache.FileName = cacheFileName; using (var stream = fileSystem.OpenWrite(cacheFileName)) @@ -43,15 +44,24 @@ public void WriteVariablesToDiskCache(IRepository repo, string gitDir, VersionVa } } - public VersionVariables LoadVersionVariablesFromDiskCache(IRepository repo, string gitDir) + private string PrepareCacheDirectory(GitPreparer gitPreparer) + { + var gitDir = gitPreparer.GetDotGitDirectory(); + + // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu + var cacheDir = GetCacheDir(gitDir); + fileSystem.CreateDirectory(cacheDir); + + return cacheDir; + } + + public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPreparer) { using (Logger.IndentLog("Loading version variables from disk cache")) { - // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu + var cacheDir = PrepareCacheDirectory(gitPreparer); - var cacheDir = GetCacheDir(gitDir); - fileSystem.CreateDirectory(cacheDir); - var cacheFileName = GetCacheFileName(GetKey(repo, gitDir), cacheDir); + var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); VersionVariables vv = null; if (fileSystem.Exists(cacheFileName)) { @@ -85,14 +95,18 @@ public VersionVariables LoadVersionVariablesFromDiskCache(IRepository repo, stri } } - string GetKey(IRepository repo, string gitDir) + string GetKey(GitPreparer gitPreparer) { + var gitDir = gitPreparer.GetDotGitDirectory(); + // Maybe using timestamp in .git/refs directory is enough? var ticks = fileSystem.GetLastDirectoryWrite(Path.Combine(gitDir, "refs")); - var configPath = Path.Combine(repo.GetRepositoryDirectory(), "GitVersionConfig.yaml"); + + var configPath = ConfigurationProvider.SelectConfigFilePath(gitPreparer, fileSystem); var configText = fileSystem.Exists(configPath) ? fileSystem.ReadAllText(configPath) : null; var configHash = configText != null ? GetHash(configText) : null; - return string.Join(":", gitDir, repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks, configHash); + + return gitPreparer.WithRepository(repo => string.Join(":", gitDir, repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks, configHash)); } static string GetCacheFileName(string key, string cacheDir) From 9853c79c4bb14afce2805a9dc1caee0a071ab437 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 12:13:36 +0300 Subject: [PATCH 04/20] code style --- .../VersionFilters/MinDateVersionFilterTests.cs | 5 ++--- src/GitVersionCore/GitVersionContext.cs | 3 +-- src/GitVersionExe/Program.cs | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/GitVersionCore.Tests/VersionFilters/MinDateVersionFilterTests.cs b/src/GitVersionCore.Tests/VersionFilters/MinDateVersionFilterTests.cs index 8a5b7c9c7d..cbe3a8cce0 100644 --- a/src/GitVersionCore.Tests/VersionFilters/MinDateVersionFilterTests.cs +++ b/src/GitVersionCore.Tests/VersionFilters/MinDateVersionFilterTests.cs @@ -1,10 +1,10 @@ -using System; -using GitVersion; +using GitVersion; using GitVersion.VersionCalculation.BaseVersionCalculators; using GitVersion.VersionFilters; using LibGit2Sharp; using NUnit.Framework; using Shouldly; +using System; namespace GitVersionCore.Tests.VersionFilters { @@ -14,7 +14,6 @@ public class MinDateVersionFilterTests [Test] public void VerifyNullGuard() { - var commit = new MockCommit(); var dummy = DateTimeOffset.UtcNow.AddSeconds(1.0); var sut = new MinDateVersionFilter(dummy); diff --git a/src/GitVersionCore/GitVersionContext.cs b/src/GitVersionCore/GitVersionContext.cs index 1ede21235a..d9c7533c6a 100644 --- a/src/GitVersionCore/GitVersionContext.cs +++ b/src/GitVersionCore/GitVersionContext.cs @@ -1,8 +1,8 @@ namespace GitVersion { + using LibGit2Sharp; using System; using System.Linq; - using LibGit2Sharp; /// /// Contextual information about where GitVersion is being run @@ -111,7 +111,6 @@ void CalculateEffectiveConfiguration() var commitMessageVersionBump = currentBranchConfig.Value.CommitMessageIncrementing ?? configuration.CommitMessageIncrementing.Value; - var versionFilter = Configuration = new EffectiveConfiguration( assemblyVersioningScheme, assemblyInformationalFormat, versioningMode, gitTagPrefix, tag, nextVersion, incrementStrategy, currentBranchConfig.Key, diff --git a/src/GitVersionExe/Program.cs b/src/GitVersionExe/Program.cs index f741f0c0d7..0225272e66 100644 --- a/src/GitVersionExe/Program.cs +++ b/src/GitVersionExe/Program.cs @@ -1,5 +1,6 @@ namespace GitVersion { + using GitVersion.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; @@ -7,7 +8,6 @@ namespace GitVersion using System.IO; using System.Linq; using System.Text; - using GitVersion.Helpers; class Program { @@ -112,7 +112,7 @@ static int VerifyArgumentsAndRun() private static void VerifyConfiguration(Arguments arguments, IFileSystem fileSystem) { - var gitPreparer = new GitPreparer(arguments.TargetUrl, arguments.DynamicRepositoryLocation,arguments.Authentication,arguments.NoFetch,arguments.TargetPath); + var gitPreparer = new GitPreparer(arguments.TargetUrl, arguments.DynamicRepositoryLocation, arguments.Authentication, arguments.NoFetch, arguments.TargetPath); ConfigurationProvider.Verify(gitPreparer, fileSystem); } @@ -176,4 +176,4 @@ static List GetArgumentsWithoutExeName() .ToList(); } } -} \ No newline at end of file +} From 87771fe0bb1177519f2552cb2df77b45e0f983d5 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 12:26:59 +0300 Subject: [PATCH 05/20] Test ThrowsExceptionOnAmbigousConfigFileLocation verifies WarningException contains expected message --- .../ConfigProviderTests.cs | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/GitVersionCore.Tests/ConfigProviderTests.cs b/src/GitVersionCore.Tests/ConfigProviderTests.cs index 312c15b4a7..0e4d5d3fde 100644 --- a/src/GitVersionCore.Tests/ConfigProviderTests.cs +++ b/src/GitVersionCore.Tests/ConfigProviderTests.cs @@ -1,13 +1,13 @@ +using GitVersion; +using GitVersion.Helpers; +using NUnit.Framework; +using Shouldly; using System; using System.ComponentModel; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; -using GitVersion; -using GitVersion.Helpers; -using NUnit.Framework; -using Shouldly; using YamlDotNet.Serialization; [TestFixture] @@ -118,7 +118,7 @@ public void CanProvideConfigForNewBranch() tag: bugfix"; SetupConfigFileContent(text); var config = ConfigurationProvider.Provide(repoPath, fileSystem); - + config.Branches["bug[/-]"].Tag.ShouldBe("bugfix"); } @@ -151,7 +151,7 @@ public void NextVersionCanHavePatch() config.NextVersion.ShouldBe("2.12.654651698"); } - + [Test] [NUnit.Framework.Category("NoMono")] [NUnit.Framework.Description("Won't run on Mono due to source information not being available for ShouldMatchApproved.")] @@ -273,12 +273,13 @@ public void WarnOnAmbigousConfigFilesAtTheSameProjectRootDirectory(string path) [TestCase(ConfigurationProvider.ObsoleteConfigFileName, ConfigurationProvider.ObsoleteConfigFileName)] public void ThrowsExceptionOnAmbigousConfigFileLocation(string repoConfigFile, string workingConfigFile) { - SetupConfigFileContent(string.Empty, repoConfigFile, repoPath); - SetupConfigFileContent(string.Empty, workingConfigFile, workingPath); + var repositoryConfigFilePath = SetupConfigFileContent(string.Empty, repoConfigFile, repoPath); + var workingDirectoryConfigFilePath = SetupConfigFileContent(string.Empty, workingConfigFile, workingPath); + + WarningException exception = Should.Throw(() => { ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); }); - Should.Throw(() => { - ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); - }); + var expecedMessage = string.Format("Ambigous config file selection from '{0}' and '{1}'", workingDirectoryConfigFilePath, repositoryConfigFilePath); + exception.Message.ShouldBe(expecedMessage); } [Test] @@ -295,13 +296,16 @@ public void NoWarnOnGitVersionYmlFile() s.Length.ShouldBe(0); } - void SetupConfigFileContent(string text, string fileName = ConfigurationProvider.DefaultConfigFileName) + string SetupConfigFileContent(string text, string fileName = ConfigurationProvider.DefaultConfigFileName) { - SetupConfigFileContent(text, fileName, repoPath); + return SetupConfigFileContent(text, fileName, repoPath); } - void SetupConfigFileContent(string text, string fileName, string path) + string SetupConfigFileContent(string text, string fileName, string path) { - fileSystem.WriteAllText(Path.Combine(path, fileName), text); + var fullPath = Path.Combine(path, fileName); + fileSystem.WriteAllText(fullPath, text); + + return fullPath; } -} \ No newline at end of file +} From 7a2e309ab500f5dea21fbabab85088344a8e7cce Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 13:47:27 +0300 Subject: [PATCH 06/20] * ConfigurationProvider.cs clean code --- .../Configuration/ConfigurationProvider.cs | 40 +++++++++--- src/GitVersionCore/ExecuteCore.cs | 17 +++-- src/GitVersionCore/GitVersionCache.cs | 62 +++++++++---------- src/GitVersionExe/ArgumentParser.cs | 34 +++++++--- src/GitVersionExe/Arguments.cs | 3 +- src/GitVersionExe/HelpWriter.cs | 2 +- src/GitVersionExe/SpecifiedArgumentRunner.cs | 8 +-- 7 files changed, 106 insertions(+), 60 deletions(-) diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 1e36c36245..8693b2902c 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -1,12 +1,12 @@ namespace GitVersion { + using GitVersion.Configuration.Init.Wizard; + using GitVersion.Helpers; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; - using GitVersion.Configuration.Init.Wizard; - using GitVersion.Helpers; public class ConfigurationProvider { @@ -103,10 +103,27 @@ static void MigrateBranches(Config config) // Map of current names and previous names var dict = new Dictionary { - { "hotfix(es)?[/-]", new [] { "hotfix[/-]" }}, - { "features?[/-]", new [] { "feature[/-]", "feature(s)?[/-]" }}, - { "releases?[/-]", new [] { "release[/-]" }}, - { "dev(elop)?(ment)?$", new [] { "develop" }} + {"hotfix(es)?[/-]", new[] + { + "hotfix[/-]" + } + }, + {"features?[/-]", new[] + { + "feature[/-]", + "feature(s)?[/-]" + } + }, + {"releases?[/-]", new[] + { + "release[/-]" + } + }, + {"dev(elop)?(ment)?$", new[] + { + "develop" + } + } }; foreach (var mapping in dict) @@ -186,12 +203,12 @@ public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) var workingDirectory = gitPreparer.WorkingDirectory; var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); - Verify(workingDirectory,projectRootDirectory, fileSystem); + Verify(workingDirectory, projectRootDirectory, fileSystem); } public static void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) { - if(fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) + if (fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) { WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); return; @@ -200,6 +217,11 @@ public static void Verify(string workingDirectory, string projectRootDirectory, WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); WarnAboutObsoleteConfigFile(projectRootDirectory, fileSystem); + WarnAboutAmbigousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); + } + + private static void WarnAboutAmbigousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + { var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); @@ -280,4 +302,4 @@ public static void Init(string workingDirectory, IFileSystem fileSystem, IConsol } } } -} \ No newline at end of file +} diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index b0aba1c7e6..7d80c07837 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -1,11 +1,10 @@ namespace GitVersion { + using GitVersion.Helpers; + using LibGit2Sharp; using System; using System.ComponentModel; using System.Linq; - using GitVersion.Helpers; - - using LibGit2Sharp; public class ExecuteCore { @@ -15,7 +14,7 @@ public class ExecuteCore public ExecuteCore(IFileSystem fileSystem) { if (fileSystem == null) throw new ArgumentNullException("fileSystem"); - + this.fileSystem = fileSystem; gitVersionCache = new GitVersionCache(fileSystem); } @@ -49,10 +48,16 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory)); } + if (overrideConfig != null) + { + var overridenVersionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); + return overridenVersionVariables; + } + var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer); if (versionVariables == null) { - versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); + versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer); gitVersionCache.WriteVariablesToDiskCache(gitPreparer, versionVariables); } @@ -92,7 +97,7 @@ VersionVariables ExecuteInternal(string targetBranch, string commitId, GitPrepar gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository)); var versionFinder = new GitVersionFinder(); - var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); + var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); return gitPreparer.WithRepository(repo => { diff --git a/src/GitVersionCore/GitVersionCache.cs b/src/GitVersionCore/GitVersionCache.cs index 95585633f1..3c9b7a5a26 100644 --- a/src/GitVersionCore/GitVersionCache.cs +++ b/src/GitVersionCore/GitVersionCache.cs @@ -1,13 +1,12 @@ namespace GitVersion { + using GitVersion.Helpers; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; - using GitVersion.Helpers; - using LibGit2Sharp; using YamlDotNet.Serialization; public class GitVersionCache @@ -47,7 +46,7 @@ public void WriteVariablesToDiskCache(GitPreparer gitPreparer, VersionVariables private string PrepareCacheDirectory(GitPreparer gitPreparer) { var gitDir = gitPreparer.GetDotGitDirectory(); - + // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu var cacheDir = GetCacheDir(gitDir); fileSystem.CreateDirectory(cacheDir); @@ -62,51 +61,52 @@ public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPrepare var cacheDir = PrepareCacheDirectory(gitPreparer); var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); - VersionVariables vv = null; - if (fileSystem.Exists(cacheFileName)) + if (!fileSystem.Exists(cacheFileName)) + { + Logger.WriteInfo("Cache file " + cacheFileName + " not found."); + return null; + } + + using (Logger.IndentLog("Deserializing version variables from cache file " + cacheFileName)) { - using (Logger.IndentLog("Deserializing version variables from cache file " + cacheFileName)) + try { + var loadedVariables = VersionVariables.FromFile(cacheFileName, fileSystem); + return loadedVariables; + } + catch (Exception ex) + { + Logger.WriteWarning("Unable to read cache file " + cacheFileName + ", deleting it."); + Logger.WriteInfo(ex.ToString()); try { - vv = VersionVariables.FromFile(cacheFileName, fileSystem); + fileSystem.Delete(cacheFileName); } - catch (Exception ex) + catch (Exception deleteEx) { - Logger.WriteWarning("Unable to read cache file " + cacheFileName + ", deleting it."); - Logger.WriteInfo(ex.ToString()); - try - { - fileSystem.Delete(cacheFileName); - } - catch (Exception deleteEx) - { - Logger.WriteWarning(string.Format("Unable to delete corrupted version cache file {0}. Got {1} exception.", cacheFileName, deleteEx.GetType().FullName)); - } + Logger.WriteWarning(string.Format("Unable to delete corrupted version cache file {0}. Got {1} exception.", cacheFileName, deleteEx.GetType().FullName)); } + + return null; } } - else - { - Logger.WriteInfo("Cache file " + cacheFileName + " not found."); - } - - return vv; } } string GetKey(GitPreparer gitPreparer) { - var gitDir = gitPreparer.GetDotGitDirectory(); + var dotGitDirectory = gitPreparer.GetDotGitDirectory(); // Maybe using timestamp in .git/refs directory is enough? - var ticks = fileSystem.GetLastDirectoryWrite(Path.Combine(gitDir, "refs")); + var lastGitRefsChangedTicks = fileSystem.GetLastDirectoryWrite(Path.Combine(dotGitDirectory, "refs")); - var configPath = ConfigurationProvider.SelectConfigFilePath(gitPreparer, fileSystem); - var configText = fileSystem.Exists(configPath) ? fileSystem.ReadAllText(configPath) : null; - var configHash = configText != null ? GetHash(configText) : null; + // 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 configFileContent = fileSystem.Exists(configFilePath) ? fileSystem.ReadAllText(configFilePath) : null; + var configFileHash = configFileContent != null ? GetHash(configFileContent) : null; - return gitPreparer.WithRepository(repo => string.Join(":", gitDir, repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks, configHash)); + return gitPreparer.WithRepository(repo => string.Join(":", dotGitDirectory, repo.Head.CanonicalName, repo.Head.Tip.Sha, lastGitRefsChangedTicks, configFileHash)); } static string GetCacheFileName(string key, string cacheDir) @@ -131,4 +131,4 @@ static string GetHash(string textToHash) } } } -} \ No newline at end of file +} diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 2f00922a4a..ce6bc47ae5 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -263,25 +263,43 @@ public static Arguments ParseArguments(List commandLineArguments) 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"); + 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"); } continue; } if (name.IsSwitch("overrideconfig")) { - foreach (var item in value.Split(';')) + var keyValueOptions = value.Split(';'); + if (keyValueOptions.Length == 0) + { + continue; + } + + arguments.HasOverrideConfig = true; + + if (keyValueOptions.Length > 1) { - var configOverride = item.Split('='); + throw new WarningException("Can't specify multiple /overrideconfig options: currently supported only 'tag-prefix' option"); + } + + // key=value + foreach (var keyValueOption in keyValueOptions) + { + var keyAndValue = keyValueOption.Split('='); + if (keyAndValue.Length > 1) + { + throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Ensure it is in format 'key=value'", keyValueOption)); + } - switch (configOverride[0]) + var optionKey = keyAndValue[0].ToLowerInvariant(); + switch (optionKey) { case "tag-prefix": - if (1 < configOverride.Length) - { - arguments.OverrideConfig.TagPrefix = configOverride[1]; - } + arguments.OverrideConfig.TagPrefix = keyAndValue[1]; break; + default: + throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Currently supported only 'tag-prefix' option", optionKey)); } } diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 605f7ab413..97ba34ece9 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -15,6 +15,7 @@ public Arguments() public Authentication Authentication; public Config OverrideConfig; + public bool HasOverrideConfig { get; set; } public string TargetPath; @@ -30,7 +31,7 @@ public Arguments() public string ShowVariable; public OutputType Output; - + public string Proj; public string ProjArgs; public string Exec; diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 0f54351b57..b6de7f7e6e 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -24,7 +24,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. - /showconfig Outputs the effective GitVersion config (defaults + custom from GitVersion.yaml) in yaml format + /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/SpecifiedArgumentRunner.cs b/src/GitVersionExe/SpecifiedArgumentRunner.cs index ce966a56fb..a2f2fcde19 100644 --- a/src/GitVersionExe/SpecifiedArgumentRunner.cs +++ b/src/GitVersionExe/SpecifiedArgumentRunner.cs @@ -1,16 +1,16 @@ namespace GitVersion { + using GitTools; + using GitVersion.Helpers; using System; using System.Collections.Generic; using System.Linq; - using GitTools; - using GitVersion.Helpers; using WarningException = System.ComponentModel.WarningException; class SpecifiedArgumentRunner { private static readonly bool runningOnMono = Type.GetType("Mono.Runtime") != null; - public static readonly string BuildTool = runningOnMono? "xbuild" : @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"; + public static readonly string BuildTool = runningOnMono ? "xbuild" : @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"; public static void Run(Arguments arguments, IFileSystem fileSystem) { @@ -23,7 +23,7 @@ public static void Run(Arguments arguments, IFileSystem fileSystem) var dynamicRepositoryLocation = arguments.DynamicRepositoryLocation; var targetBranch = arguments.TargetBranch; var commitId = arguments.CommitId; - var overrideConfig = arguments.OverrideConfig; + var overrideConfig = arguments.HasOverrideConfig ? arguments.OverrideConfig : null; var executeCore = new ExecuteCore(fileSystem); var variables = executeCore.ExecuteGitVersion(targetUrl, dynamicRepositoryLocation, authentication, targetBranch, noFetch, targetPath, commitId, overrideConfig: overrideConfig); From 9d592abba6faf7a8612b9e628020c7516a0fa8f9 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 13:48:16 +0300 Subject: [PATCH 07/20] Revert "* ConfigurationProvider.cs clean code" This reverts commit 7a2e309ab500f5dea21fbabab85088344a8e7cce. --- .../Configuration/ConfigurationProvider.cs | 40 +++--------- src/GitVersionCore/ExecuteCore.cs | 17 ++--- src/GitVersionCore/GitVersionCache.cs | 62 +++++++++---------- src/GitVersionExe/ArgumentParser.cs | 34 +++------- src/GitVersionExe/Arguments.cs | 3 +- src/GitVersionExe/HelpWriter.cs | 2 +- src/GitVersionExe/SpecifiedArgumentRunner.cs | 8 +-- 7 files changed, 60 insertions(+), 106 deletions(-) diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 8693b2902c..1e36c36245 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -1,12 +1,12 @@ namespace GitVersion { - using GitVersion.Configuration.Init.Wizard; - using GitVersion.Helpers; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; + using GitVersion.Configuration.Init.Wizard; + using GitVersion.Helpers; public class ConfigurationProvider { @@ -103,27 +103,10 @@ static void MigrateBranches(Config config) // Map of current names and previous names var dict = new Dictionary { - {"hotfix(es)?[/-]", new[] - { - "hotfix[/-]" - } - }, - {"features?[/-]", new[] - { - "feature[/-]", - "feature(s)?[/-]" - } - }, - {"releases?[/-]", new[] - { - "release[/-]" - } - }, - {"dev(elop)?(ment)?$", new[] - { - "develop" - } - } + { "hotfix(es)?[/-]", new [] { "hotfix[/-]" }}, + { "features?[/-]", new [] { "feature[/-]", "feature(s)?[/-]" }}, + { "releases?[/-]", new [] { "release[/-]" }}, + { "dev(elop)?(ment)?$", new [] { "develop" }} }; foreach (var mapping in dict) @@ -203,12 +186,12 @@ public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) var workingDirectory = gitPreparer.WorkingDirectory; var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); - Verify(workingDirectory, projectRootDirectory, fileSystem); + Verify(workingDirectory,projectRootDirectory, fileSystem); } public static void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) { - if (fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) + if(fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) { WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); return; @@ -217,11 +200,6 @@ public static void Verify(string workingDirectory, string projectRootDirectory, WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); WarnAboutObsoleteConfigFile(projectRootDirectory, fileSystem); - WarnAboutAmbigousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); - } - - private static void WarnAboutAmbigousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) - { var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); @@ -302,4 +280,4 @@ public static void Init(string workingDirectory, IFileSystem fileSystem, IConsol } } } -} +} \ No newline at end of file diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index 7d80c07837..b0aba1c7e6 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -1,10 +1,11 @@ namespace GitVersion { - using GitVersion.Helpers; - using LibGit2Sharp; using System; using System.ComponentModel; using System.Linq; + using GitVersion.Helpers; + + using LibGit2Sharp; public class ExecuteCore { @@ -14,7 +15,7 @@ public class ExecuteCore public ExecuteCore(IFileSystem fileSystem) { if (fileSystem == null) throw new ArgumentNullException("fileSystem"); - + this.fileSystem = fileSystem; gitVersionCache = new GitVersionCache(fileSystem); } @@ -48,16 +49,10 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory)); } - if (overrideConfig != null) - { - var overridenVersionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); - return overridenVersionVariables; - } - var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer); if (versionVariables == null) { - versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer); + versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); gitVersionCache.WriteVariablesToDiskCache(gitPreparer, versionVariables); } @@ -97,7 +92,7 @@ VersionVariables ExecuteInternal(string targetBranch, string commitId, GitPrepar gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository)); var versionFinder = new GitVersionFinder(); - var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); + var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); return gitPreparer.WithRepository(repo => { diff --git a/src/GitVersionCore/GitVersionCache.cs b/src/GitVersionCore/GitVersionCache.cs index 3c9b7a5a26..95585633f1 100644 --- a/src/GitVersionCore/GitVersionCache.cs +++ b/src/GitVersionCore/GitVersionCache.cs @@ -1,12 +1,13 @@ namespace GitVersion { - using GitVersion.Helpers; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; + using GitVersion.Helpers; + using LibGit2Sharp; using YamlDotNet.Serialization; public class GitVersionCache @@ -46,7 +47,7 @@ public void WriteVariablesToDiskCache(GitPreparer gitPreparer, VersionVariables private string PrepareCacheDirectory(GitPreparer gitPreparer) { var gitDir = gitPreparer.GetDotGitDirectory(); - + // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu var cacheDir = GetCacheDir(gitDir); fileSystem.CreateDirectory(cacheDir); @@ -61,52 +62,51 @@ public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPrepare var cacheDir = PrepareCacheDirectory(gitPreparer); var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); - if (!fileSystem.Exists(cacheFileName)) - { - Logger.WriteInfo("Cache file " + cacheFileName + " not found."); - return null; - } - - using (Logger.IndentLog("Deserializing version variables from cache file " + cacheFileName)) + VersionVariables vv = null; + if (fileSystem.Exists(cacheFileName)) { - try + using (Logger.IndentLog("Deserializing version variables from cache file " + cacheFileName)) { - var loadedVariables = VersionVariables.FromFile(cacheFileName, fileSystem); - return loadedVariables; - } - catch (Exception ex) - { - Logger.WriteWarning("Unable to read cache file " + cacheFileName + ", deleting it."); - Logger.WriteInfo(ex.ToString()); try { - fileSystem.Delete(cacheFileName); + vv = VersionVariables.FromFile(cacheFileName, fileSystem); } - catch (Exception deleteEx) + catch (Exception ex) { - Logger.WriteWarning(string.Format("Unable to delete corrupted version cache file {0}. Got {1} exception.", cacheFileName, deleteEx.GetType().FullName)); + Logger.WriteWarning("Unable to read cache file " + cacheFileName + ", deleting it."); + Logger.WriteInfo(ex.ToString()); + try + { + fileSystem.Delete(cacheFileName); + } + catch (Exception deleteEx) + { + Logger.WriteWarning(string.Format("Unable to delete corrupted version cache file {0}. Got {1} exception.", cacheFileName, deleteEx.GetType().FullName)); + } } - - return null; } } + else + { + Logger.WriteInfo("Cache file " + cacheFileName + " not found."); + } + + return vv; } } string GetKey(GitPreparer gitPreparer) { - var dotGitDirectory = gitPreparer.GetDotGitDirectory(); + var gitDir = gitPreparer.GetDotGitDirectory(); // Maybe using timestamp in .git/refs directory is enough? - var lastGitRefsChangedTicks = fileSystem.GetLastDirectoryWrite(Path.Combine(dotGitDirectory, "refs")); + var ticks = fileSystem.GetLastDirectoryWrite(Path.Combine(gitDir, "refs")); - // 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 configFileContent = fileSystem.Exists(configFilePath) ? fileSystem.ReadAllText(configFilePath) : null; - var configFileHash = configFileContent != null ? GetHash(configFileContent) : null; + var configPath = ConfigurationProvider.SelectConfigFilePath(gitPreparer, fileSystem); + var configText = fileSystem.Exists(configPath) ? fileSystem.ReadAllText(configPath) : null; + var configHash = configText != null ? GetHash(configText) : null; - return gitPreparer.WithRepository(repo => string.Join(":", dotGitDirectory, repo.Head.CanonicalName, repo.Head.Tip.Sha, lastGitRefsChangedTicks, configFileHash)); + return gitPreparer.WithRepository(repo => string.Join(":", gitDir, repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks, configHash)); } static string GetCacheFileName(string key, string cacheDir) @@ -131,4 +131,4 @@ static string GetHash(string textToHash) } } } -} +} \ No newline at end of file diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index ce6bc47ae5..2f00922a4a 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -263,43 +263,25 @@ public static Arguments ParseArguments(List commandLineArguments) 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"); + 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"); } continue; } if (name.IsSwitch("overrideconfig")) { - var keyValueOptions = value.Split(';'); - if (keyValueOptions.Length == 0) - { - continue; - } - - arguments.HasOverrideConfig = true; - - if (keyValueOptions.Length > 1) + foreach (var item in value.Split(';')) { - throw new WarningException("Can't specify multiple /overrideconfig options: currently supported only 'tag-prefix' option"); - } - - // key=value - foreach (var keyValueOption in keyValueOptions) - { - var keyAndValue = keyValueOption.Split('='); - if (keyAndValue.Length > 1) - { - throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Ensure it is in format 'key=value'", keyValueOption)); - } + var configOverride = item.Split('='); - var optionKey = keyAndValue[0].ToLowerInvariant(); - switch (optionKey) + switch (configOverride[0]) { case "tag-prefix": - arguments.OverrideConfig.TagPrefix = keyAndValue[1]; + if (1 < configOverride.Length) + { + arguments.OverrideConfig.TagPrefix = configOverride[1]; + } break; - default: - throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Currently supported only 'tag-prefix' option", optionKey)); } } diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 97ba34ece9..605f7ab413 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -15,7 +15,6 @@ public Arguments() public Authentication Authentication; public Config OverrideConfig; - public bool HasOverrideConfig { get; set; } public string TargetPath; @@ -31,7 +30,7 @@ public Arguments() public string ShowVariable; public OutputType Output; - + public string Proj; public string ProjArgs; public string Exec; diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index b6de7f7e6e..0f54351b57 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -24,7 +24,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. - /showconfig Outputs the effective GitVersion config (defaults + custom from GitVersion.yml) in yaml format + /showconfig Outputs the effective GitVersion config (defaults + custom from GitVersion.yaml) 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/SpecifiedArgumentRunner.cs b/src/GitVersionExe/SpecifiedArgumentRunner.cs index a2f2fcde19..ce966a56fb 100644 --- a/src/GitVersionExe/SpecifiedArgumentRunner.cs +++ b/src/GitVersionExe/SpecifiedArgumentRunner.cs @@ -1,16 +1,16 @@ namespace GitVersion { - using GitTools; - using GitVersion.Helpers; using System; using System.Collections.Generic; using System.Linq; + using GitTools; + using GitVersion.Helpers; using WarningException = System.ComponentModel.WarningException; class SpecifiedArgumentRunner { private static readonly bool runningOnMono = Type.GetType("Mono.Runtime") != null; - public static readonly string BuildTool = runningOnMono ? "xbuild" : @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"; + public static readonly string BuildTool = runningOnMono? "xbuild" : @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"; public static void Run(Arguments arguments, IFileSystem fileSystem) { @@ -23,7 +23,7 @@ public static void Run(Arguments arguments, IFileSystem fileSystem) var dynamicRepositoryLocation = arguments.DynamicRepositoryLocation; var targetBranch = arguments.TargetBranch; var commitId = arguments.CommitId; - var overrideConfig = arguments.HasOverrideConfig ? arguments.OverrideConfig : null; + var overrideConfig = arguments.OverrideConfig; var executeCore = new ExecuteCore(fileSystem); var variables = executeCore.ExecuteGitVersion(targetUrl, dynamicRepositoryLocation, authentication, targetBranch, noFetch, targetPath, commitId, overrideConfig: overrideConfig); From fa260781cd048f2179c93395b47b9c34afa33b07 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 13:53:23 +0300 Subject: [PATCH 08/20] * ConfigurationProvider.cs refactoring: extracted WarnAboutAmbigousConfigFileSelection --- .../Configuration/ConfigurationProvider.cs | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 1e36c36245..8693b2902c 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -1,12 +1,12 @@ namespace GitVersion { + using GitVersion.Configuration.Init.Wizard; + using GitVersion.Helpers; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; using System.Text; - using GitVersion.Configuration.Init.Wizard; - using GitVersion.Helpers; public class ConfigurationProvider { @@ -103,10 +103,27 @@ static void MigrateBranches(Config config) // Map of current names and previous names var dict = new Dictionary { - { "hotfix(es)?[/-]", new [] { "hotfix[/-]" }}, - { "features?[/-]", new [] { "feature[/-]", "feature(s)?[/-]" }}, - { "releases?[/-]", new [] { "release[/-]" }}, - { "dev(elop)?(ment)?$", new [] { "develop" }} + {"hotfix(es)?[/-]", new[] + { + "hotfix[/-]" + } + }, + {"features?[/-]", new[] + { + "feature[/-]", + "feature(s)?[/-]" + } + }, + {"releases?[/-]", new[] + { + "release[/-]" + } + }, + {"dev(elop)?(ment)?$", new[] + { + "develop" + } + } }; foreach (var mapping in dict) @@ -186,12 +203,12 @@ public static void Verify(GitPreparer gitPreparer, IFileSystem fileSystem) var workingDirectory = gitPreparer.WorkingDirectory; var projectRootDirectory = gitPreparer.GetProjectRootDirectory(); - Verify(workingDirectory,projectRootDirectory, fileSystem); + Verify(workingDirectory, projectRootDirectory, fileSystem); } public static void Verify(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) { - if(fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) + if (fileSystem.PathsEqual(workingDirectory, projectRootDirectory)) { WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); return; @@ -200,6 +217,11 @@ public static void Verify(string workingDirectory, string projectRootDirectory, WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); WarnAboutObsoleteConfigFile(projectRootDirectory, fileSystem); + WarnAboutAmbigousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); + } + + private static void WarnAboutAmbigousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + { var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); @@ -280,4 +302,4 @@ public static void Init(string workingDirectory, IFileSystem fileSystem, IConsol } } } -} \ No newline at end of file +} From ddaff32cff2ddd0e7a4267dffb96324ccafbeb68 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 13:54:28 +0300 Subject: [PATCH 09/20] * HelpWriter.cs fixed default config file name: GitVersion.yaml -> GitVersion.yml --- src/GitVersionExe/HelpWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index 0f54351b57..b6de7f7e6e 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -24,7 +24,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. - /showconfig Outputs the effective GitVersion config (defaults + custom from GitVersion.yaml) in yaml format + /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 From 02036f9fdf2f5b43d723e02976f89bcfb4eb5f39 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 13:56:58 +0300 Subject: [PATCH 10/20] * GitVersionCache.cs refactoring: improved readibility --- src/GitVersionCore/GitVersionCache.cs | 62 +++++++++++++-------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/GitVersionCore/GitVersionCache.cs b/src/GitVersionCore/GitVersionCache.cs index 95585633f1..3c9b7a5a26 100644 --- a/src/GitVersionCore/GitVersionCache.cs +++ b/src/GitVersionCore/GitVersionCache.cs @@ -1,13 +1,12 @@ namespace GitVersion { + using GitVersion.Helpers; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; - using GitVersion.Helpers; - using LibGit2Sharp; using YamlDotNet.Serialization; public class GitVersionCache @@ -47,7 +46,7 @@ public void WriteVariablesToDiskCache(GitPreparer gitPreparer, VersionVariables private string PrepareCacheDirectory(GitPreparer gitPreparer) { var gitDir = gitPreparer.GetDotGitDirectory(); - + // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu var cacheDir = GetCacheDir(gitDir); fileSystem.CreateDirectory(cacheDir); @@ -62,51 +61,52 @@ public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPrepare var cacheDir = PrepareCacheDirectory(gitPreparer); var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); - VersionVariables vv = null; - if (fileSystem.Exists(cacheFileName)) + if (!fileSystem.Exists(cacheFileName)) + { + Logger.WriteInfo("Cache file " + cacheFileName + " not found."); + return null; + } + + using (Logger.IndentLog("Deserializing version variables from cache file " + cacheFileName)) { - using (Logger.IndentLog("Deserializing version variables from cache file " + cacheFileName)) + try { + var loadedVariables = VersionVariables.FromFile(cacheFileName, fileSystem); + return loadedVariables; + } + catch (Exception ex) + { + Logger.WriteWarning("Unable to read cache file " + cacheFileName + ", deleting it."); + Logger.WriteInfo(ex.ToString()); try { - vv = VersionVariables.FromFile(cacheFileName, fileSystem); + fileSystem.Delete(cacheFileName); } - catch (Exception ex) + catch (Exception deleteEx) { - Logger.WriteWarning("Unable to read cache file " + cacheFileName + ", deleting it."); - Logger.WriteInfo(ex.ToString()); - try - { - fileSystem.Delete(cacheFileName); - } - catch (Exception deleteEx) - { - Logger.WriteWarning(string.Format("Unable to delete corrupted version cache file {0}. Got {1} exception.", cacheFileName, deleteEx.GetType().FullName)); - } + Logger.WriteWarning(string.Format("Unable to delete corrupted version cache file {0}. Got {1} exception.", cacheFileName, deleteEx.GetType().FullName)); } + + return null; } } - else - { - Logger.WriteInfo("Cache file " + cacheFileName + " not found."); - } - - return vv; } } string GetKey(GitPreparer gitPreparer) { - var gitDir = gitPreparer.GetDotGitDirectory(); + var dotGitDirectory = gitPreparer.GetDotGitDirectory(); // Maybe using timestamp in .git/refs directory is enough? - var ticks = fileSystem.GetLastDirectoryWrite(Path.Combine(gitDir, "refs")); + var lastGitRefsChangedTicks = fileSystem.GetLastDirectoryWrite(Path.Combine(dotGitDirectory, "refs")); - var configPath = ConfigurationProvider.SelectConfigFilePath(gitPreparer, fileSystem); - var configText = fileSystem.Exists(configPath) ? fileSystem.ReadAllText(configPath) : null; - var configHash = configText != null ? GetHash(configText) : null; + // 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 configFileContent = fileSystem.Exists(configFilePath) ? fileSystem.ReadAllText(configFilePath) : null; + var configFileHash = configFileContent != null ? GetHash(configFileContent) : null; - return gitPreparer.WithRepository(repo => string.Join(":", gitDir, repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks, configHash)); + return gitPreparer.WithRepository(repo => string.Join(":", dotGitDirectory, repo.Head.CanonicalName, repo.Head.Tip.Sha, lastGitRefsChangedTicks, configFileHash)); } static string GetCacheFileName(string key, string cacheDir) @@ -131,4 +131,4 @@ static string GetHash(string textToHash) } } } -} \ No newline at end of file +} From 764ee798a08879b5ec4cf42639f53eb41dd88111 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 14:00:20 +0300 Subject: [PATCH 11/20] fixed bug: /overrideconfig was ignored in caching results When /overrideconfig presents version must be calculated explicitly without saving in cache. --- src/GitVersionCore/ExecuteCore.cs | 17 ++++++---- src/GitVersionExe/ArgumentParser.cs | 34 +++++++++++++++----- src/GitVersionExe/Arguments.cs | 3 +- src/GitVersionExe/SpecifiedArgumentRunner.cs | 8 ++--- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index b0aba1c7e6..7d80c07837 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -1,11 +1,10 @@ namespace GitVersion { + using GitVersion.Helpers; + using LibGit2Sharp; using System; using System.ComponentModel; using System.Linq; - using GitVersion.Helpers; - - using LibGit2Sharp; public class ExecuteCore { @@ -15,7 +14,7 @@ public class ExecuteCore public ExecuteCore(IFileSystem fileSystem) { if (fileSystem == null) throw new ArgumentNullException("fileSystem"); - + this.fileSystem = fileSystem; gitVersionCache = new GitVersionCache(fileSystem); } @@ -49,10 +48,16 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory)); } + if (overrideConfig != null) + { + var overridenVersionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); + return overridenVersionVariables; + } + var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer); if (versionVariables == null) { - versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); + versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer); gitVersionCache.WriteVariablesToDiskCache(gitPreparer, versionVariables); } @@ -92,7 +97,7 @@ VersionVariables ExecuteInternal(string targetBranch, string commitId, GitPrepar gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository)); var versionFinder = new GitVersionFinder(); - var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); + var configuration = ConfigurationProvider.Provide(gitPreparer, fileSystem, overrideConfig: overrideConfig); return gitPreparer.WithRepository(repo => { diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index 2f00922a4a..ce6bc47ae5 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -263,25 +263,43 @@ public static Arguments ParseArguments(List commandLineArguments) 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"); + 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"); } continue; } if (name.IsSwitch("overrideconfig")) { - foreach (var item in value.Split(';')) + var keyValueOptions = value.Split(';'); + if (keyValueOptions.Length == 0) + { + continue; + } + + arguments.HasOverrideConfig = true; + + if (keyValueOptions.Length > 1) { - var configOverride = item.Split('='); + throw new WarningException("Can't specify multiple /overrideconfig options: currently supported only 'tag-prefix' option"); + } + + // key=value + foreach (var keyValueOption in keyValueOptions) + { + var keyAndValue = keyValueOption.Split('='); + if (keyAndValue.Length > 1) + { + throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Ensure it is in format 'key=value'", keyValueOption)); + } - switch (configOverride[0]) + var optionKey = keyAndValue[0].ToLowerInvariant(); + switch (optionKey) { case "tag-prefix": - if (1 < configOverride.Length) - { - arguments.OverrideConfig.TagPrefix = configOverride[1]; - } + arguments.OverrideConfig.TagPrefix = keyAndValue[1]; break; + default: + throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Currently supported only 'tag-prefix' option", optionKey)); } } diff --git a/src/GitVersionExe/Arguments.cs b/src/GitVersionExe/Arguments.cs index 605f7ab413..97ba34ece9 100644 --- a/src/GitVersionExe/Arguments.cs +++ b/src/GitVersionExe/Arguments.cs @@ -15,6 +15,7 @@ public Arguments() public Authentication Authentication; public Config OverrideConfig; + public bool HasOverrideConfig { get; set; } public string TargetPath; @@ -30,7 +31,7 @@ public Arguments() public string ShowVariable; public OutputType Output; - + public string Proj; public string ProjArgs; public string Exec; diff --git a/src/GitVersionExe/SpecifiedArgumentRunner.cs b/src/GitVersionExe/SpecifiedArgumentRunner.cs index ce966a56fb..a2f2fcde19 100644 --- a/src/GitVersionExe/SpecifiedArgumentRunner.cs +++ b/src/GitVersionExe/SpecifiedArgumentRunner.cs @@ -1,16 +1,16 @@ namespace GitVersion { + using GitTools; + using GitVersion.Helpers; using System; using System.Collections.Generic; using System.Linq; - using GitTools; - using GitVersion.Helpers; using WarningException = System.ComponentModel.WarningException; class SpecifiedArgumentRunner { private static readonly bool runningOnMono = Type.GetType("Mono.Runtime") != null; - public static readonly string BuildTool = runningOnMono? "xbuild" : @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"; + public static readonly string BuildTool = runningOnMono ? "xbuild" : @"c:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"; public static void Run(Arguments arguments, IFileSystem fileSystem) { @@ -23,7 +23,7 @@ public static void Run(Arguments arguments, IFileSystem fileSystem) var dynamicRepositoryLocation = arguments.DynamicRepositoryLocation; var targetBranch = arguments.TargetBranch; var commitId = arguments.CommitId; - var overrideConfig = arguments.OverrideConfig; + var overrideConfig = arguments.HasOverrideConfig ? arguments.OverrideConfig : null; var executeCore = new ExecuteCore(fileSystem); var variables = executeCore.ExecuteGitVersion(targetUrl, dynamicRepositoryLocation, authentication, targetBranch, noFetch, targetPath, commitId, overrideConfig: overrideConfig); From ca604a1fc715186f1437294bb8762a2b0fc4b00b Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 16:10:28 +0300 Subject: [PATCH 12/20] Tests for parsing option /overrideconfig --- .../ArgumentParserTests.cs | 41 ++++++++++++++++--- src/GitVersionExe/ArgumentParser.cs | 6 +-- src/GitVersionExe/HelpWriter.cs | 2 +- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/GitVersionExe.Tests/ArgumentParserTests.cs b/src/GitVersionExe.Tests/ArgumentParserTests.cs index bc0d23eada..e84714450d 100644 --- a/src/GitVersionExe.Tests/ArgumentParserTests.cs +++ b/src/GitVersionExe.Tests/ArgumentParserTests.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; using GitVersion; using NUnit.Framework; using Shouldly; +using System; +using System.Collections.Generic; +using System.ComponentModel; [TestFixture] public class ArgumentParserTests @@ -199,7 +199,7 @@ public void update_assembly_info_false(string command) public void create_mulitple_assembly_info_protected(string command) { var exception = Assert.Throws(() => ArgumentParser.ParseArguments(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"); + 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"); } [Test] @@ -220,6 +220,37 @@ public void update_assembly_info_with_multiple_filenames() arguments.UpdateAssemblyInfoFileName.ShouldContain("VersionAssemblyInfo.cs"); } + [Test] + public void overrideconfig_with_no_options() + { + var arguments = ArgumentParser.ParseArguments("/overrideconfig"); + arguments.HasOverrideConfig.ShouldBe(false); + arguments.OverrideConfig.ShouldNotBeNull(); + } + + [Test] + public void overrideconfig_with_single_tagprefix_option() + { + var arguments = ArgumentParser.ParseArguments("/overrideconfig tag-prefix=sample"); + arguments.HasOverrideConfig.ShouldBe(true); + arguments.OverrideConfig.TagPrefix.ShouldBe("sample"); + } + + [TestCase("tag-prefix=sample;tag-prefix=other")] + [TestCase("tag-prefix=sample;param2=other")] + public void overrideconfig_with_several_options(string options) + { + var exception = Assert.Throws(() => ArgumentParser.ParseArguments(string.Format("/overrideconfig {0}", options))); + exception.Message.ShouldContain("Can't specify multiple /overrideconfig options"); + } + + [TestCase("tag-prefix=sample=asdf")] + public void overrideconfig_with_invalid_option(string options) + { + var exception = Assert.Throws(() => ArgumentParser.ParseArguments(string.Format("/overrideconfig {0}", options))); + exception.Message.ShouldContain("Could not parse /overrideconfig option"); + } + [Test] public void update_assembly_info_with_relative_filename() { @@ -248,7 +279,7 @@ public void ensure_assembly_info_false() var arguments = ArgumentParser.ParseArguments("-ensureAssemblyInfo false"); arguments.EnsureAssemblyInfo.ShouldBe(false); } - + [Test] public void dynamicRepoLocation() { diff --git a/src/GitVersionExe/ArgumentParser.cs b/src/GitVersionExe/ArgumentParser.cs index ce6bc47ae5..133f03009d 100644 --- a/src/GitVersionExe/ArgumentParser.cs +++ b/src/GitVersionExe/ArgumentParser.cs @@ -270,7 +270,7 @@ public static Arguments ParseArguments(List commandLineArguments) if (name.IsSwitch("overrideconfig")) { - var keyValueOptions = value.Split(';'); + var keyValueOptions = (value ?? "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (keyValueOptions.Length == 0) { continue; @@ -286,8 +286,8 @@ public static Arguments ParseArguments(List commandLineArguments) // key=value foreach (var keyValueOption in keyValueOptions) { - var keyAndValue = keyValueOption.Split('='); - if (keyAndValue.Length > 1) + var keyAndValue = keyValueOption.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries); + if (keyAndValue.Length != 2) { throw new WarningException(string.Format("Could not parse /overrideconfig option: {0}. Ensure it is in format 'key=value'", keyValueOption)); } diff --git a/src/GitVersionExe/HelpWriter.cs b/src/GitVersionExe/HelpWriter.cs index b6de7f7e6e..299f0a0557 100644 --- a/src/GitVersionExe/HelpWriter.cs +++ b/src/GitVersionExe/HelpWriter.cs @@ -25,7 +25,7 @@ path The directory containing .git. If not defined current directory eg /output json /showvariable SemVer - will output `1.2.3+beta.4` /l Path to logfile. /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) + /overrideconfig Overrides GitVersion config values inline (semicolon-separated key value pairs e.g. /overrideconfig tag-prefix=Foo) Currently supported config overrides: tag-prefix # AssemblyInfo updating From 0366f6927edbc8a0c248e312c03b256c25a86918 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Tue, 14 Jun 2016 16:49:21 +0300 Subject: [PATCH 13/20] added test for applying /overrideconfig option from command line Ensures that overriden config will be applied whenever there cached version exists and willn't save results in cache --- src/GitVersionCore.Tests/ExecuteCoreTests.cs | 61 ++++++++++++++++++-- src/GitVersionCore/ExecuteCore.cs | 7 ++- src/GitVersionCore/GitVersionCache.cs | 15 ++--- 3 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/GitVersionCore.Tests/ExecuteCoreTests.cs b/src/GitVersionCore.Tests/ExecuteCoreTests.cs index e96c62d084..5086d654a9 100644 --- a/src/GitVersionCore.Tests/ExecuteCoreTests.cs +++ b/src/GitVersionCore.Tests/ExecuteCoreTests.cs @@ -1,11 +1,11 @@ -using System; -using System.IO; -using System.Text; -using GitTools.Testing; +using GitTools.Testing; using GitVersion; using GitVersion.Helpers; using NUnit.Framework; using Shouldly; +using System; +using System.IO; +using System.Text; [TestFixture] public class ExecuteCoreTests @@ -60,6 +60,59 @@ public void CacheFileExistsOnDisk() info.ShouldContain("Deserializing version variables from cache file", () => info); } + + [Test] + public void CacheFileExistsOnDiskWhenOverrideConfigIsSpecifiedVersionShouldBeDynamicallyCalculatedWithoutSavingInCache() + { + const string versionCacheFileContent = @" +Major: 4 +Minor: 10 +Patch: 3 +PreReleaseTag: test.19 +PreReleaseTagWithDash: -test.19 +PreReleaseLabel: test +PreReleaseNumber: 19 +BuildMetaData: +BuildMetaDataPadded: +FullBuildMetaData: Branch.feature/test.Sha.dd2a29aff0c948e1bdf3dabbe13e1576e70d5f9f +MajorMinorPatch: 4.10.3 +SemVer: 4.10.3-test.19 +LegacySemVer: 4.10.3-test19 +LegacySemVerPadded: 4.10.3-test0019 +AssemblySemVer: 4.10.3.0 +FullSemVer: 4.10.3-test.19 +InformationalVersion: 4.10.3-test.19+Branch.feature/test.Sha.dd2a29aff0c948e1bdf3dabbe13e1576e70d5f9f +BranchName: feature/test +Sha: dd2a29aff0c948e1bdf3dabbe13e1576e70d5f9f +NuGetVersionV2: 4.10.3-test0019 +NuGetVersion: 4.10.3-test0019 +CommitsSinceVersionSource: 19 +CommitsSinceVersionSourcePadded: 0019 +CommitDate: 2015-11-10 +"; + + var versionAndBranchFinder = new ExecuteCore(fileSystem); + + var info = RepositoryScope(versionAndBranchFinder, (fixture, vv) => + { + fileSystem.WriteAllText(vv.FileName, versionCacheFileContent); + + var gitPreparer = new GitPreparer(null, null, null, false, fixture.RepositoryPath); + var cacheDirectory = GitVersionCache.GetCacheDirectory(gitPreparer); + + var cacheDirectoryTimestamp = fileSystem.GetLastDirectoryWrite(cacheDirectory); + + vv = versionAndBranchFinder.ExecuteGitVersion(null, null, null, null, false, fixture.RepositoryPath, null, new Config() { TagPrefix = "prefix" }); + + vv.AssemblySemVer.ShouldBe("0.1.0.0"); + + var cachedDirectoryTimestampAfter = fileSystem.GetLastDirectoryWrite(cacheDirectory); + cachedDirectoryTimestampAfter.ShouldBe(cacheDirectoryTimestamp, () => "Cache was updated when override config was set"); + }); + + info.ShouldContain("Override config from command line", () => info); + } + [Test] public void CacheFileIsMissing() { diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index 7d80c07837..f580c76619 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -50,8 +50,11 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi if (overrideConfig != null) { - var overridenVersionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); - return overridenVersionVariables; + using (Logger.IndentLog("Override config from command line")) + { + var overridenVersionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); + return overridenVersionVariables; + } } var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer); diff --git a/src/GitVersionCore/GitVersionCache.cs b/src/GitVersionCore/GitVersionCache.cs index 3c9b7a5a26..589bbcdd63 100644 --- a/src/GitVersionCore/GitVersionCache.cs +++ b/src/GitVersionCore/GitVersionCache.cs @@ -43,12 +43,18 @@ public void WriteVariablesToDiskCache(GitPreparer gitPreparer, VersionVariables } } - private string PrepareCacheDirectory(GitPreparer gitPreparer) + public static string GetCacheDirectory(GitPreparer gitPreparer) { var gitDir = gitPreparer.GetDotGitDirectory(); + var cacheDir = Path.Combine(gitDir, "gitversion_cache"); + return cacheDir; + } + + private string PrepareCacheDirectory(GitPreparer gitPreparer) + { + var cacheDir = GetCacheDirectory(gitPreparer); // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu - var cacheDir = GetCacheDir(gitDir); fileSystem.CreateDirectory(cacheDir); return cacheDir; @@ -115,11 +121,6 @@ static string GetCacheFileName(string key, string cacheDir) return string.Concat(Path.Combine(cacheDir, cacheKey), ".yml"); } - static string GetCacheDir(string gitDir) - { - return Path.Combine(gitDir, "gitversion_cache"); - } - static string GetHash(string textToHash) { using (var sha1 = SHA1.Create()) From 0eb743f0323d6a032b3d000a9ebcbc5efc38dcc4 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sun, 19 Jun 2016 17:58:02 +0300 Subject: [PATCH 14/20] fixed typo in warning exception messages: ambigous -> ambiguous --- src/GitVersionCore.Tests/ConfigProviderTests.cs | 8 ++++---- src/GitVersionCore/Configuration/ConfigurationProvider.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/GitVersionCore.Tests/ConfigProviderTests.cs b/src/GitVersionCore.Tests/ConfigProviderTests.cs index 0e4d5d3fde..643c505c67 100644 --- a/src/GitVersionCore.Tests/ConfigProviderTests.cs +++ b/src/GitVersionCore.Tests/ConfigProviderTests.cs @@ -252,7 +252,7 @@ public void WarnOnExistingGitVersionConfigYamlFile(string path) [TestCase(DefaultRepoPath)] [TestCase(DefaultWorkingPath)] - public void WarnOnAmbigousConfigFilesAtTheSameProjectRootDirectory(string path) + public void WarnOnAmbiguousConfigFilesAtTheSameProjectRootDirectory(string path) { SetupConfigFileContent(string.Empty, ConfigurationProvider.ObsoleteConfigFileName, path); SetupConfigFileContent(string.Empty, ConfigurationProvider.DefaultConfigFileName, path); @@ -263,7 +263,7 @@ public void WarnOnAmbigousConfigFilesAtTheSameProjectRootDirectory(string path) ConfigurationProvider.Verify(workingPath, repoPath, fileSystem); - var configFileDeprecatedWarning = string.Format("Ambigous config files at '{0}'", path); + var configFileDeprecatedWarning = string.Format("Ambiguous config files at '{0}'", path); logOutput.Contains(configFileDeprecatedWarning).ShouldBe(true); } @@ -271,14 +271,14 @@ public void WarnOnAmbigousConfigFilesAtTheSameProjectRootDirectory(string path) [TestCase(ConfigurationProvider.DefaultConfigFileName, ConfigurationProvider.ObsoleteConfigFileName)] [TestCase(ConfigurationProvider.ObsoleteConfigFileName, ConfigurationProvider.DefaultConfigFileName)] [TestCase(ConfigurationProvider.ObsoleteConfigFileName, ConfigurationProvider.ObsoleteConfigFileName)] - public void ThrowsExceptionOnAmbigousConfigFileLocation(string repoConfigFile, string workingConfigFile) + 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("Ambigous config file selection from '{0}' and '{1}'", workingDirectoryConfigFilePath, repositoryConfigFilePath); + var expecedMessage = string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingDirectoryConfigFilePath, repositoryConfigFilePath); exception.Message.ShouldBe(expecedMessage); } diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 8693b2902c..981b3e1baf 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -217,10 +217,10 @@ public static void Verify(string workingDirectory, string projectRootDirectory, WarnAboutObsoleteConfigFile(workingDirectory, fileSystem); WarnAboutObsoleteConfigFile(projectRootDirectory, fileSystem); - WarnAboutAmbigousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); + WarnAboutAmbiguousConfigFileSelection(workingDirectory, projectRootDirectory, fileSystem); } - private static void WarnAboutAmbigousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) + private static void WarnAboutAmbiguousConfigFileSelection(string workingDirectory, string projectRootDirectory, IFileSystem fileSystem) { var workingConfigFile = GetConfigFilePath(workingDirectory, fileSystem); var projectRootConfigFile = GetConfigFilePath(projectRootDirectory, fileSystem); @@ -229,7 +229,7 @@ private static void WarnAboutAmbigousConfigFileSelection(string workingDirectory bool hasConfigInProjectRootDirectory = fileSystem.Exists(projectRootConfigFile); if (hasConfigInProjectRootDirectory && hasConfigInWorkingDirectory) { - throw new WarningException(string.Format("Ambigous config file selection from '{0}' and '{1}'", workingConfigFile, projectRootConfigFile)); + throw new WarningException(string.Format("Ambiguous config file selection from '{0}' and '{1}'", workingConfigFile, projectRootConfigFile)); } } @@ -278,7 +278,7 @@ static bool WarnAboutObsoleteConfigFile(string workingDirectory, IFileSystem fil var defaultConfigFilePath = Path.Combine(workingDirectory, DefaultConfigFileName); if (fileSystem.Exists(defaultConfigFilePath)) { - Logger.WriteWarning(string.Format("Ambigous config files at '{0}': '{1}' (deprecated) and '{2}'. Will be used '{2}'", workingDirectory, ObsoleteConfigFileName, DefaultConfigFileName)); + Logger.WriteWarning(string.Format("Ambiguous config files at '{0}': '{1}' (deprecated) and '{2}'. Will be used '{2}'", workingDirectory, ObsoleteConfigFileName, DefaultConfigFileName)); return true; } From cfd90da47b3860533f26d3cb64ae46020594e1ec Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sun, 19 Jun 2016 18:04:44 +0300 Subject: [PATCH 15/20] * ConfigurationProvider.cs reverted back rules formatting for MigrateBranches Will be eventually corrupted back after applying Resharper's clean code. Will need to do smth with it. --- .../Configuration/ConfigurationProvider.cs | 26 +++---------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index 981b3e1baf..bbea62bec6 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -103,27 +103,10 @@ static void MigrateBranches(Config config) // Map of current names and previous names var dict = new Dictionary { - {"hotfix(es)?[/-]", new[] - { - "hotfix[/-]" - } - }, - {"features?[/-]", new[] - { - "feature[/-]", - "feature(s)?[/-]" - } - }, - {"releases?[/-]", new[] - { - "release[/-]" - } - }, - {"dev(elop)?(ment)?$", new[] - { - "develop" - } - } + {"hotfix(es)?[/-]", new[] { "hotfix[/-]" }}, + {"features?[/-]", new[] { "feature[/-]", "feature(s)?[/-]" }}, + {"releases?[/-]", new[] { "release[/-]" }}, + {"dev(elop)?(ment)?$", new[] { "develop" }} }; foreach (var mapping in dict) @@ -141,7 +124,6 @@ static void MigrateBranches(Config config) } } - static BranchConfig GetOrCreateBranchDefaults(Config config, string branch) { if (!config.Branches.ContainsKey(branch)) From f2db2a486144ab2192044d37c942e22c2f8c14d1 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sun, 19 Jun 2016 18:58:46 +0300 Subject: [PATCH 16/20] * docs\configuration.md added comment about generation GitVersion.yml --- docs/configuration.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 7d1bf22672..dea58114c3 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,6 +4,8 @@ GitVersion 3.0 is mainly powered by configuration and no longer has branching st ## Configuration tool If you run `GitVersion init` you will be launched into a configuration tool, it can help you configure GitVersion the way you want it. +It will create file 'GitVersion.yml' in directory where you launched initialization. It can be root repository directory or any subdirectory in case when you have single repository for more then one project or restricted to commit into subdirectory. + **Note:** GitVersion ships with internal default configuration which works with GitHubFlow and GitFlow, probably with others too. The *develop* branch is set to `ContinuousDeployment` mode by default as we have found that is generally what is needed when using GitFlow. From dbc988be419694fcd1144f5370e81ebc689c151a Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 16 Jul 2016 22:49:51 +0300 Subject: [PATCH 17/20] added overrideConfig to cache key Extracted cache key calculation to GitVersionCacheKeyFactory --- src/GitVersionCore/ExecuteCore.cs | 16 +--- src/GitVersionCore/GitVersionCache.cs | 43 ++------- src/GitVersionCore/GitVersionCacheKey.cs | 19 ++++ .../GitVersionCacheKeyFactory.cs | 94 +++++++++++++++++++ src/GitVersionCore/GitVersionCore.csproj | 2 + src/GitVersionExe/SpecifiedArgumentRunner.cs | 2 +- 6 files changed, 127 insertions(+), 49 deletions(-) create mode 100644 src/GitVersionCore/GitVersionCacheKey.cs create mode 100644 src/GitVersionCore/GitVersionCacheKeyFactory.cs diff --git a/src/GitVersionCore/ExecuteCore.cs b/src/GitVersionCore/ExecuteCore.cs index f580c76619..74ec7457a9 100644 --- a/src/GitVersionCore/ExecuteCore.cs +++ b/src/GitVersionCore/ExecuteCore.cs @@ -48,20 +48,12 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory)); } - if (overrideConfig != null) - { - using (Logger.IndentLog("Override config from command line")) - { - var overridenVersionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig: overrideConfig); - return overridenVersionVariables; - } - } - - var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer); + var cacheKey = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, overrideConfig); + var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(gitPreparer, cacheKey); if (versionVariables == null) { - versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer); - gitVersionCache.WriteVariablesToDiskCache(gitPreparer, versionVariables); + versionVariables = ExecuteInternal(targetBranch, commitId, gitPreparer, buildServer, overrideConfig); + gitVersionCache.WriteVariablesToDiskCache(gitPreparer, cacheKey, versionVariables); } return versionVariables; diff --git a/src/GitVersionCore/GitVersionCache.cs b/src/GitVersionCore/GitVersionCache.cs index 589bbcdd63..b3cb90ca45 100644 --- a/src/GitVersionCore/GitVersionCache.cs +++ b/src/GitVersionCore/GitVersionCache.cs @@ -5,8 +5,6 @@ namespace GitVersion using System.Collections.Generic; using System.IO; using System.Linq; - using System.Security.Cryptography; - using System.Text; using YamlDotNet.Serialization; public class GitVersionCache @@ -18,10 +16,11 @@ public GitVersionCache(IFileSystem fileSystem) this.fileSystem = fileSystem; } - public void WriteVariablesToDiskCache(GitPreparer gitPreparer, VersionVariables variablesFromCache) + public void WriteVariablesToDiskCache(GitPreparer gitPreparer, GitVersionCacheKey cacheKey, VersionVariables variablesFromCache) { var cacheDir = PrepareCacheDirectory(gitPreparer); - var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); + var cacheFileName = GetCacheFileName(cacheKey, cacheDir); + variablesFromCache.FileName = cacheFileName; using (var stream = fileSystem.OpenWrite(cacheFileName)) @@ -60,13 +59,13 @@ private string PrepareCacheDirectory(GitPreparer gitPreparer) return cacheDir; } - public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPreparer) + public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPreparer, GitVersionCacheKey key) { using (Logger.IndentLog("Loading version variables from disk cache")) { var cacheDir = PrepareCacheDirectory(gitPreparer); - var cacheFileName = GetCacheFileName(GetKey(gitPreparer), cacheDir); + var cacheFileName = GetCacheFileName(key, cacheDir); if (!fileSystem.Exists(cacheFileName)) { Logger.WriteInfo("Cache file " + cacheFileName + " not found."); @@ -99,37 +98,9 @@ public VersionVariables LoadVersionVariablesFromDiskCache(GitPreparer gitPrepare } } - string GetKey(GitPreparer gitPreparer) - { - var dotGitDirectory = gitPreparer.GetDotGitDirectory(); - - // Maybe using timestamp in .git/refs directory is enough? - var lastGitRefsChangedTicks = fileSystem.GetLastDirectoryWrite(Path.Combine(dotGitDirectory, "refs")); - - // 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 configFileContent = fileSystem.Exists(configFilePath) ? fileSystem.ReadAllText(configFilePath) : null; - var configFileHash = configFileContent != null ? GetHash(configFileContent) : null; - - return gitPreparer.WithRepository(repo => string.Join(":", dotGitDirectory, repo.Head.CanonicalName, repo.Head.Tip.Sha, lastGitRefsChangedTicks, configFileHash)); - } - - static string GetCacheFileName(string key, string cacheDir) - { - var cacheKey = GetHash(key); - return string.Concat(Path.Combine(cacheDir, cacheKey), ".yml"); - } - - static string GetHash(string textToHash) + static string GetCacheFileName(GitVersionCacheKey key, string cacheDir) { - using (var sha1 = SHA1.Create()) - { - var bytes = Encoding.UTF8.GetBytes(textToHash); - var hashedBytes = sha1.ComputeHash(bytes); - var hashedString = BitConverter.ToString(hashedBytes); - return hashedString.Replace("-", ""); - } + return Path.Combine(cacheDir, string.Concat(key.Value, ".yml")); } } } diff --git a/src/GitVersionCore/GitVersionCacheKey.cs b/src/GitVersionCore/GitVersionCacheKey.cs new file mode 100644 index 0000000000..00239ff271 --- /dev/null +++ b/src/GitVersionCore/GitVersionCacheKey.cs @@ -0,0 +1,19 @@ +namespace GitVersion +{ + using System; + + public class GitVersionCacheKey + { + public GitVersionCacheKey(string value) + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentNullException("value"); + } + + Value = value; + } + + public string Value { get; private set; } + } +} \ No newline at end of file diff --git a/src/GitVersionCore/GitVersionCacheKeyFactory.cs b/src/GitVersionCore/GitVersionCacheKeyFactory.cs new file mode 100644 index 0000000000..5ab9de84a6 --- /dev/null +++ b/src/GitVersionCore/GitVersionCacheKeyFactory.cs @@ -0,0 +1,94 @@ +namespace GitVersion +{ + using GitVersion.Helpers; + using System; + using System.IO; + using System.Security.Cryptography; + using System.Text; + + public class GitVersionCacheKeyFactory + { + public static GitVersionCacheKey Create(IFileSystem fileSystem, GitPreparer gitPreparer, Config overrideConfig) + { + var gitSystemHash = GetGitSystemHash(gitPreparer, fileSystem); + var configFileHash = GetConfigFileHash(fileSystem, gitPreparer); + var repositorySnapshotHash = GetRepositorySnapshotHash(gitPreparer); + var overrideConfigHash = GetOverrideConfigHash(overrideConfig); + + var compositeHash = GetHash(gitSystemHash, configFileHash, repositorySnapshotHash, overrideConfigHash); + return new GitVersionCacheKey(compositeHash); + } + + private static string GetGitSystemHash(GitPreparer gitPreparer, IFileSystem fileSystem) + { + var dotGitDirectory = gitPreparer.GetDotGitDirectory(); + + // Maybe using timestamp in .git/refs directory is enough? + var lastGitRefsChangedTicks = fileSystem.GetLastDirectoryWrite(Path.Combine(dotGitDirectory, "refs")); + + return GetHash(dotGitDirectory, lastGitRefsChangedTicks.ToString()); + } + + private static string GetRepositorySnapshotHash(GitPreparer gitPreparer) + { + var repositorySnapshot = gitPreparer.WithRepository(repo => string.Join(":", repo.Head.CanonicalName, repo.Head.Tip.Sha)); + return GetHash(repositorySnapshot); + } + + private static string GetOverrideConfigHash(Config overrideConfig) + { + if (overrideConfig == null) + { + return string.Empty; + } + + // Doesn't depend on command line representation and + // includes possible changes in default values of Config per se. + var stringBuilder = new StringBuilder(); + using (var stream = new StringWriter(stringBuilder)) + { + ConfigSerialiser.Write(overrideConfig, stream); + stream.Flush(); + } + var configContent = stringBuilder.ToString(); + + return GetHash(configContent); + } + + private static string GetConfigFileHash(IFileSystem fileSystem, GitPreparer gitPreparer) + { + // 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); + if (!fileSystem.Exists(configFilePath)) + { + return string.Empty; + } + + var configFileContent = fileSystem.ReadAllText(configFilePath); + return GetHash(configFileContent); + } + + static string GetHash(params string[] textsToHash) + { + var textToHash = string.Join(":", textsToHash); + return GetHash(textToHash); + } + + static string GetHash(string textToHash) + { + if (string.IsNullOrEmpty(textToHash)) + { + return string.Empty; + } + + using (var sha1 = SHA1.Create()) + { + var bytes = Encoding.UTF8.GetBytes(textToHash); + var hashedBytes = sha1.ComputeHash(bytes); + var hashedString = BitConverter.ToString(hashedBytes); + return hashedString.Replace("-", ""); + } + } + } +} diff --git a/src/GitVersionCore/GitVersionCore.csproj b/src/GitVersionCore/GitVersionCore.csproj index 8cec6326d9..dacd8f847b 100644 --- a/src/GitVersionCore/GitVersionCore.csproj +++ b/src/GitVersionCore/GitVersionCore.csproj @@ -118,6 +118,8 @@ + + diff --git a/src/GitVersionExe/SpecifiedArgumentRunner.cs b/src/GitVersionExe/SpecifiedArgumentRunner.cs index a2f2fcde19..55f3909679 100644 --- a/src/GitVersionExe/SpecifiedArgumentRunner.cs +++ b/src/GitVersionExe/SpecifiedArgumentRunner.cs @@ -26,7 +26,7 @@ public static void Run(Arguments arguments, IFileSystem fileSystem) var overrideConfig = arguments.HasOverrideConfig ? arguments.OverrideConfig : null; var executeCore = new ExecuteCore(fileSystem); - var variables = executeCore.ExecuteGitVersion(targetUrl, dynamicRepositoryLocation, authentication, targetBranch, noFetch, targetPath, commitId, overrideConfig: overrideConfig); + var variables = executeCore.ExecuteGitVersion(targetUrl, dynamicRepositoryLocation, authentication, targetBranch, noFetch, targetPath, commitId, overrideConfig); if (arguments.Output == OutputType.BuildServer) { From c9ce4d8d9f30d07e51040659ccbac59c89038a14 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 16 Jul 2016 23:01:29 +0300 Subject: [PATCH 18/20] * ConfigurationProvider.cs refactored MigrateBranches - clean&readable code that doesn't fear Reshaper --- .../Configuration/ConfigurationProvider.cs | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/GitVersionCore/Configuration/ConfigurationProvider.cs b/src/GitVersionCore/Configuration/ConfigurationProvider.cs index bbea62bec6..2241308c4b 100644 --- a/src/GitVersionCore/Configuration/ConfigurationProvider.cs +++ b/src/GitVersionCore/Configuration/ConfigurationProvider.cs @@ -2,7 +2,6 @@ namespace GitVersion { using GitVersion.Configuration.Init.Wizard; using GitVersion.Helpers; - using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; @@ -100,27 +99,25 @@ public static void ApplyOverridesTo(Config config, Config overrideConfig) static void MigrateBranches(Config config) { - // Map of current names and previous names - var dict = new Dictionary - { - {"hotfix(es)?[/-]", new[] { "hotfix[/-]" }}, - {"features?[/-]", new[] { "feature[/-]", "feature(s)?[/-]" }}, - {"releases?[/-]", new[] { "release[/-]" }}, - {"dev(elop)?(ment)?$", new[] { "develop" }} - }; + MigrateObsoleteBranches(config, "hotfix(es)?[/-]", "hotfix[/-]"); + MigrateObsoleteBranches(config, "features?[/-]", "feature[/-]", "feature(s)?[/-]"); + MigrateObsoleteBranches(config, "releases?[/-]", "release[/-]"); + MigrateObsoleteBranches(config, "dev(elop)?(ment)?$", "develop"); + } - foreach (var mapping in dict) + static void MigrateObsoleteBranches(Config config, string newBranch, params string[] obsoleteBranches) + { + foreach (var obsoleteBranch in obsoleteBranches) { - foreach (var source in mapping.Value) + if (!config.Branches.ContainsKey(obsoleteBranch)) { - if (config.Branches.ContainsKey(source)) - { - // found one, rename - var bc = config.Branches[source]; - config.Branches.Remove(source); - config.Branches[mapping.Key] = bc; // re-add with new name - } + continue; } + + // found one, rename + var bc = config.Branches[obsoleteBranch]; + config.Branches.Remove(obsoleteBranch); + config.Branches[newBranch] = bc; // re-add with new name } } From c2a7d2eb2bd065ef9aeb869ea15cf13b7b9dcd82 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 16 Jul 2016 23:30:17 +0300 Subject: [PATCH 19/20] added /ovverideconfig option to command line docs --- docs/usage/command-line.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/usage/command-line.md b/docs/usage/command-line.md index 01e7636731..d29b18ec18 100644 --- a/docs/usage/command-line.md +++ b/docs/usage/command-line.md @@ -54,4 +54,14 @@ Will result in command line argument error ### Example: When AssemblyInfo.cs and AssemblyVersionInfo.cs already exist `GitVersion.exe /updateassemblyinfo AssemblyInfo.cs AssemblyVersionInfo.cs` -Will iterate through each file and update known attributes (`AssemblyVersion`, `AssemblyFileVersion`, `AssemblyInformationalVersion`). \ No newline at end of file +Will iterate through each file and update known attributes (`AssemblyVersion`, `AssemblyFileVersion`, `AssemblyInformationalVersion`). + +## Override config +`/overrideconfig [key=value]` will override appropriate key from 'GitVersion.yml'. + +At the moment only `tag-prefix` option is supported. Read more about [Configuration](/configuration/). + +It will not change config file 'GitVersion.yml'. + +### Example: How to override configuration option 'tag-prefix' to use prefix 'custom' +`GitVersion.exe /output json /overrideconfig tag-prefix=custom` \ No newline at end of file From 96e41c7fe548cc986dd8b9d79adc71704af09ec4 Mon Sep 17 00:00:00 2001 From: Sergio Rykov Date: Sat, 16 Jul 2016 23:38:30 +0300 Subject: [PATCH 20/20] * docs\configuration.md corrected text about location of config file after init --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index dea58114c3..1b558655ef 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,7 +4,7 @@ GitVersion 3.0 is mainly powered by configuration and no longer has branching st ## Configuration tool If you run `GitVersion init` you will be launched into a configuration tool, it can help you configure GitVersion the way you want it. -It will create file 'GitVersion.yml' in directory where you launched initialization. It can be root repository directory or any subdirectory in case when you have single repository for more then one project or restricted to commit into subdirectory. +Once complete, the `init` command will create a `GitVersion.yml` file in the working directory. It can be the root repository directory or any subdirectory in case you have a single repository for more than one project or are restricted to commit into a subdirectory. **Note:** GitVersion ships with internal default configuration which works with GitHubFlow and GitFlow, probably with others too.