From 173518b55fd9c9466edfbad37661a4d39409b9f4 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Mon, 17 Mar 2014 12:27:28 +0100 Subject: [PATCH 01/11] Added support for remote repositories (with and without authentication) --- GitVersion/ArgumentParser.cs | 36 +++++++++++--- GitVersion/Arguments.cs | 7 +++ GitVersion/GitPreparer.cs | 77 ++++++++++++++++++++++++++++++ GitVersion/GitVersion.csproj | 2 + GitVersion/HelpWriter.cs | 8 +++- GitVersion/Helpers/DeleteHelper.cs | 27 +++++++++++ GitVersion/Program.cs | 62 +++++++++++++++++++----- Tests/ArgumentParserTests.cs | 34 ++++++++++--- 8 files changed, 226 insertions(+), 27 deletions(-) create mode 100644 GitVersion/GitPreparer.cs create mode 100644 GitVersion/Helpers/DeleteHelper.cs diff --git a/GitVersion/ArgumentParser.cs b/GitVersion/ArgumentParser.cs index 250a891455..a946b36232 100644 --- a/GitVersion/ArgumentParser.cs +++ b/GitVersion/ArgumentParser.cs @@ -16,9 +16,9 @@ public static Arguments ParseArguments(List commandLineArguments) if (commandLineArguments.Count == 0) { return new Arguments - { - TargetPath = Environment.CurrentDirectory - }; + { + TargetPath = Environment.CurrentDirectory + }; } var firstArgument = commandLineArguments.First(); @@ -33,9 +33,9 @@ public static Arguments ParseArguments(List commandLineArguments) if (commandLineArguments.Count == 1) { return new Arguments - { - TargetPath = firstArgument - }; + { + TargetPath = firstArgument + }; } List namedArguments; @@ -64,6 +64,30 @@ public static Arguments ParseArguments(List commandLineArguments) continue; } + if (IsSwitch("url", name)) + { + arguments.TargetUrl = value; + continue; + } + + if (IsSwitch("b", name)) + { + arguments.TargetBranch = value; + continue; + } + + if (IsSwitch("u", name)) + { + arguments.Username = value; + continue; + } + + if (IsSwitch("p", name)) + { + arguments.Password = value; + continue; + } + if ((IsSwitch("v", name)) && VersionParts.Contains(value.ToLower())) { arguments.VersionPart = value.ToLower(); diff --git a/GitVersion/Arguments.cs b/GitVersion/Arguments.cs index 2b7bb3de1e..6a3c1d374e 100644 --- a/GitVersion/Arguments.cs +++ b/GitVersion/Arguments.cs @@ -3,6 +3,13 @@ namespace GitVersion class Arguments { public string TargetPath; + + public string TargetUrl; + public string TargetBranch; + + public string Username; + public string Password; + public bool IsHelp; public string LogFilePath; public string VersionPart; diff --git a/GitVersion/GitPreparer.cs b/GitVersion/GitPreparer.cs new file mode 100644 index 0000000000..2ba513fadf --- /dev/null +++ b/GitVersion/GitPreparer.cs @@ -0,0 +1,77 @@ +namespace GitVersion +{ + using System.IO; + using LibGit2Sharp; + + public class GitPreparer + { + public GitPreparer(string targetPath, string url, string branchName, string username, string password) + { + TargetPath = targetPath; + Url = url; + BranchName = branchName; + Username = username; + Password = password; + } + + public string TargetPath { get; private set; } + + public string Url { get; private set; } + + public string BranchName { get; private set; } + + public string Username { get; private set; } + + public string Password { get; private set; } + + public bool IsDynamicGitRepository + { + get { return !string.IsNullOrWhiteSpace(DynamicGitRepositoryPath); } + } + + public string DynamicGitRepositoryPath { get; private set; } + + public string Prepare() + { + var gitPath = TargetPath; + + if (!string.IsNullOrWhiteSpace(Url)) + { + gitPath = GetGitInfoFromUrl(); + } + + return GitDirFinder.TreeWalkForGitDir(gitPath); + } + + private string GetGitInfoFromUrl() + { + var gitDirectory = Path.Combine(TargetPath, "_dynamicrepository", ".git"); + if (Directory.Exists(gitDirectory)) + { + Logger.WriteInfo(string.Format("Deleting existing .git folder from '{0}' to force new checkout from url", gitDirectory)); + + DeleteHelper.DeleteGitRepository(gitDirectory); + } + + Credentials credentials = null; + if (!string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password)) + { + Logger.WriteInfo(string.Format("Setting up credentials using name '{0}'", Username)); + + credentials = new Credentials() + { + Username = Username, + Password = Password + }; + } + + Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", Url)); + + Repository.Clone(Url, gitDirectory, checkout: false, credentials: credentials); + + DynamicGitRepositoryPath = gitDirectory; + + return gitDirectory; + } + } +} \ No newline at end of file diff --git a/GitVersion/GitVersion.csproj b/GitVersion/GitVersion.csproj index d7bcdca3b2..16e8d6e92f 100644 --- a/GitVersion/GitVersion.csproj +++ b/GitVersion/GitVersion.csproj @@ -68,6 +68,8 @@ + + diff --git a/GitVersion/HelpWriter.cs b/GitVersion/HelpWriter.cs index b3ebf8518f..4fc20795a6 100644 --- a/GitVersion/HelpWriter.cs +++ b/GitVersion/HelpWriter.cs @@ -11,8 +11,12 @@ public static void Write() GitVersion [path] [/l logFilePath] - path The directory containing .git. If not defined current directory is used. - /l Path to logfile. + path The directory containing .git. If not defined current directory is used. + /url Url to remote git repository. + /b Name of the branch to use on the remote repository, must be used in combination with /url. + /u Username in case authentication is required. + /p Password in case authentication is required. + /l Path to logfile. "; Console.Write(message); } diff --git a/GitVersion/Helpers/DeleteHelper.cs b/GitVersion/Helpers/DeleteHelper.cs new file mode 100644 index 0000000000..37888943d4 --- /dev/null +++ b/GitVersion/Helpers/DeleteHelper.cs @@ -0,0 +1,27 @@ +namespace GitVersion +{ + using System.IO; + + public static class DeleteHelper + { + public static void DeleteGitRepository(string directory) + { + if (string.IsNullOrEmpty(directory)) + { + return; + } + + foreach (var fileName in Directory.GetFiles(directory, "*.*", SearchOption.AllDirectories)) + { + var fileInfo = new FileInfo(fileName) + { + IsReadOnly = false + }; + + fileInfo.Delete(); + } + + Directory.Delete(directory, true); + } + } +} \ No newline at end of file diff --git a/GitVersion/Program.cs b/GitVersion/Program.cs index 747a578e0e..89f1a9c2b1 100644 --- a/GitVersion/Program.cs +++ b/GitVersion/Program.cs @@ -2,6 +2,7 @@ namespace GitVersion { using System; using System.Collections.Generic; + using System.Diagnostics; using System.IO; using System.Linq; @@ -9,21 +10,25 @@ class Program { static void Main() { + int? exitCode = null; + try { var arguments = ArgumentParser.ParseArguments(GetArgumentsWithoutExeName()); - if (arguments.IsHelp) { HelpWriter.Write(); return; } + ConfigureLogging(arguments); - var gitDirectory = GitDirFinder.TreeWalkForGitDir(arguments.TargetPath); + var gitPreparer = new GitPreparer(arguments.TargetPath, arguments.TargetUrl, + arguments.TargetBranch, arguments.Username, arguments.Password); + var gitDirectory = gitPreparer.Prepare(); if (string.IsNullOrEmpty(gitDirectory)) { - Console.Error.WriteLine("Could not find .git directory"); + Console.Error.WriteLine("Failed to prepare or find the .git directory in path '{0}'", arguments.TargetPath); Environment.Exit(1); } @@ -40,8 +45,9 @@ static void Main() switch (arguments.VersionPart) { case null: - Console.WriteLine(JsonOutputFormatter.ToJson(versionAsKeyValue)); + Console.WriteLine(JsonOutputFormatter.ToJson(versionAsKeyValue)); break; + default: string part; if (!versionAsKeyValue.TryGetValue(arguments.VersionPart, out part)) @@ -51,18 +57,38 @@ static void Main() Console.WriteLine(part); break; } - + + if (gitPreparer.IsDynamicGitRepository) + { + DeleteHelper.DeleteGitRepository(gitPreparer.DynamicGitRepositoryPath); + } } catch (ErrorException exception) { - Console.Error.Write("An error occurred:\r\n{0}", exception.Message); - Environment.Exit(1); + var error = string.Format("An error occurred:\r\n{0}", exception.Message); + Logger.WriteWarning(error); + + exitCode = 1; } catch (Exception exception) { - Console.Error.Write("An unexpected error occurred:\r\n{0}", exception); - Environment.Exit(1); + var error = string.Format("An unexpected error occurred:\r\n{0}", exception); + Logger.WriteWarning(error); + + exitCode = 1; + } + + if (Debugger.IsAttached) + { + Console.ReadKey(); + } + + if (!exitCode.HasValue) + { + exitCode = 0; } + + Environment.Exit(exitCode.Value); } static IEnumerable GetApplicableBuildServers() @@ -72,20 +98,32 @@ static IEnumerable GetApplicableBuildServers() static void ConfigureLogging(Arguments arguments) { + Action writeAction; + if (arguments.LogFilePath == null) { - Logger.WriteInfo = s =>{}; + writeAction = x => + { + Console.WriteLine(x); + }; } else { Directory.CreateDirectory(Path.GetDirectoryName(arguments.LogFilePath)); if (File.Exists(arguments.LogFilePath)) { - using (File.CreateText(arguments.LogFilePath)) { } + using (File.CreateText(arguments.LogFilePath)) { } } - Logger.WriteInfo = s => WriteLogEntry(arguments, s); + writeAction = x => + { + Console.WriteLine(x); + WriteLogEntry(arguments, x); + }; } + + Logger.WriteInfo = writeAction; + Logger.WriteWarning = writeAction; } static void WriteLogEntry(Arguments arguments, string s) diff --git a/Tests/ArgumentParserTests.cs b/Tests/ArgumentParserTests.cs index c4af924154..292c626c84 100644 --- a/Tests/ArgumentParserTests.cs +++ b/Tests/ArgumentParserTests.cs @@ -10,7 +10,7 @@ public class ArgumentParserTests public void Empty_means_use_current_directory() { var arguments = ArgumentParser.ParseArguments(""); - Assert.AreEqual(Environment.CurrentDirectory,arguments.TargetPath); + Assert.AreEqual(Environment.CurrentDirectory, arguments.TargetPath); Assert.IsNull(arguments.LogFilePath); Assert.IsFalse(arguments.IsHelp); } @@ -19,7 +19,7 @@ public void Empty_means_use_current_directory() public void Single_means_use_as_target_directory() { var arguments = ArgumentParser.ParseArguments("path"); - Assert.AreEqual("path",arguments.TargetPath); + Assert.AreEqual("path", arguments.TargetPath); Assert.IsNull(arguments.LogFilePath); Assert.IsFalse(arguments.IsHelp); } @@ -28,8 +28,8 @@ public void Single_means_use_as_target_directory() public void No_path_and_logfile_should_use_current_directory_TargetDirectory() { var arguments = ArgumentParser.ParseArguments("-l logFilePath"); - Assert.AreEqual(Environment.CurrentDirectory,arguments.TargetPath); - Assert.AreEqual("logFilePath",arguments.LogFilePath); + Assert.AreEqual(Environment.CurrentDirectory, arguments.TargetPath); + Assert.AreEqual("logFilePath", arguments.LogFilePath); Assert.IsFalse(arguments.IsHelp); } @@ -47,21 +47,41 @@ public void TargetDirectory_and_LogFilePath_can_be_parsed() { var arguments = ArgumentParser.ParseArguments("targetDirectoryPath -l logFilePath"); Assert.AreEqual("targetDirectoryPath", arguments.TargetPath); - Assert.AreEqual("logFilePath",arguments.LogFilePath); + Assert.AreEqual("logFilePath", arguments.LogFilePath); + Assert.IsFalse(arguments.IsHelp); + } + + [Test] + public void Username_and_Password_can_be_parsed() + { + var arguments = ArgumentParser.ParseArguments("targetDirectoryPath -u [username] -p [password]"); + Assert.AreEqual("targetDirectoryPath", arguments.TargetPath); + Assert.AreEqual("[username]", arguments.Username); + Assert.AreEqual("[password]", arguments.Password); + Assert.IsFalse(arguments.IsHelp); + } + + [Test] + public void Url_and_BranchName_can_be_parsed() + { + var arguments = ArgumentParser.ParseArguments("targetDirectoryPath -url http://github.com/Particular/GitVersion.git -b somebranch"); + Assert.AreEqual("targetDirectoryPath", arguments.TargetPath); + Assert.AreEqual("http://github.com/Particular/GitVersion.git", arguments.TargetUrl); + Assert.AreEqual("somebranch", arguments.TargetBranch); Assert.IsFalse(arguments.IsHelp); } [Test] public void Wrong_number_of_arguments_should_throw() { - var exception = Assert.Throws(()=> ArgumentParser.ParseArguments("targetDirectoryPath -l logFilePath extraArg")); + var exception = Assert.Throws(() => ArgumentParser.ParseArguments("targetDirectoryPath -l logFilePath extraArg")); Assert.AreEqual("Could not parse arguments: 'targetDirectoryPath -l logFilePath extraArg'.", exception.Message); } [Test] public void Unknown_argument_should_throw() { - var exception = Assert.Throws(()=> ArgumentParser.ParseArguments("targetDirectoryPath -x logFilePath")); + var exception = Assert.Throws(() => ArgumentParser.ParseArguments("targetDirectoryPath -x logFilePath")); Assert.AreEqual("Could not parse command line parameter '-x'.", exception.Message); } } \ No newline at end of file From 81fb3ec00ef62fac48b733967af6cfae2af1dfa5 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Mon, 17 Mar 2014 15:10:18 +0100 Subject: [PATCH 02/11] GitVersion now actually uses the specified target branch when using a remote repository --- GitVersion/BuildServers/GitHelper.cs | 1 + GitVersion/GitFlow/BranchClassifier.cs | 4 +-- ...OptionallyTaggedBranchVersionFinderBase.cs | 3 +-- GitVersion/GitPreparer.cs | 26 +++++++++++++++++++ GitVersion/LibGitExtensions.cs | 7 ++--- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/GitVersion/BuildServers/GitHelper.cs b/GitVersion/BuildServers/GitHelper.cs index af965ba04b..0074132f01 100644 --- a/GitVersion/BuildServers/GitHelper.cs +++ b/GitVersion/BuildServers/GitHelper.cs @@ -34,6 +34,7 @@ public static void NormalizeGitDirectory(string gitDirectory) static FetchOptions BuildFetchOptions() { + // TODO: Respect username/password of arguments? var username = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_USERNAME"); var password = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_PASSWORD"); diff --git a/GitVersion/GitFlow/BranchClassifier.cs b/GitVersion/GitFlow/BranchClassifier.cs index 2944a00390..aa3ad5e890 100644 --- a/GitVersion/GitFlow/BranchClassifier.cs +++ b/GitVersion/GitFlow/BranchClassifier.cs @@ -43,12 +43,12 @@ public static string GetSuffix(this Branch branch, BranchType branchType) public static bool IsDevelop(this Branch branch) { - return branch.Name == "develop"; + return branch.Name.EndsWith("develop"); } public static bool IsMaster(this Branch branch) { - return branch.Name == "master"; + return branch.Name.EndsWith("master"); } public static bool IsPullRequest(this Branch branch) diff --git a/GitVersion/GitFlow/BranchFinders/OptionallyTaggedBranchVersionFinderBase.cs b/GitVersion/GitFlow/BranchFinders/OptionallyTaggedBranchVersionFinderBase.cs index b6e26225a8..69daeb0bc7 100644 --- a/GitVersion/GitFlow/BranchFinders/OptionallyTaggedBranchVersionFinderBase.cs +++ b/GitVersion/GitFlow/BranchFinders/OptionallyTaggedBranchVersionFinderBase.cs @@ -142,8 +142,7 @@ int NumberOfCommitsInBranchNotKnownFromBaseBranch( BranchType branchType, string baseBranchName) { - var baseTip = repo.Branches[baseBranchName].Tip; - + var baseTip = repo.FindBranch(baseBranchName).Tip; if (branch.Tip == baseTip) { // The branch bears no additional commit diff --git a/GitVersion/GitPreparer.cs b/GitVersion/GitPreparer.cs index 2ba513fadf..01a9f41606 100644 --- a/GitVersion/GitPreparer.cs +++ b/GitVersion/GitPreparer.cs @@ -69,6 +69,32 @@ private string GetGitInfoFromUrl() Repository.Clone(Url, gitDirectory, checkout: false, credentials: credentials); + if (!string.IsNullOrWhiteSpace(BranchName)) + { + // Normalize (download branches) before using the branch + GitHelper.NormalizeGitDirectory(gitDirectory); + + using (var repository = new Repository(gitDirectory)) + { + var targetBranchName = string.Format("refs/heads/{0}", BranchName); + if (!string.Equals(repository.Head.CanonicalName, targetBranchName)) + { + Logger.WriteInfo(string.Format("Switching to branch '{0}'", BranchName)); + + var branch = repository.FindBranch(BranchName); + if ((branch != null) && !branch.IsCurrentRepositoryHead) + { + var finalName = string.Format("refs/heads/{0}", BranchName); + //repository.Refs.Add("HEAD", branch.UpstreamBranchCanonicalName, true); + + repository.Refs.Add("HEAD", finalName, true); + + //var symRef = repository.Refs.Create("HEAD", string.Format("refs/heads/{0}", BranchName)); + } + } + } + } + DynamicGitRepositoryPath = gitDirectory; return gitDirectory; diff --git a/GitVersion/LibGitExtensions.cs b/GitVersion/LibGitExtensions.cs index 5ea575415b..18f2bb5394 100644 --- a/GitVersion/LibGitExtensions.cs +++ b/GitVersion/LibGitExtensions.cs @@ -30,8 +30,8 @@ public static Branch FindBranch(this IRepository repository, string branchName) return exact; } - return repository.Branches.FirstOrDefault(x => x.Name == "origin/"+branchName); - } + return repository.Branches.FirstOrDefault(x => x.Name == "origin/" + branchName); + } public static SemanticVersion NewestSemVerTag(this IRepository repository, Commit commit) { @@ -43,6 +43,7 @@ public static SemanticVersion NewestSemVerTag(this IRepository repository, Commi return version; } } + return null; } @@ -67,7 +68,7 @@ public static GitObject PeeledTarget(this Tag tag) while (target is TagAnnotation) { - target = ((TagAnnotation) (target)).Target; + target = ((TagAnnotation)(target)).Target; } return target; From 314cf17521ecc198c8633e7c03b30d4c6ad9c59f Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Mon, 17 Mar 2014 15:20:01 +0100 Subject: [PATCH 03/11] Changed tabs to spaces in HelpWriter --- GitVersion/HelpWriter.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/GitVersion/HelpWriter.cs b/GitVersion/HelpWriter.cs index 4fc20795a6..93bc315e3a 100644 --- a/GitVersion/HelpWriter.cs +++ b/GitVersion/HelpWriter.cs @@ -11,12 +11,12 @@ public static void Write() GitVersion [path] [/l logFilePath] - path The directory containing .git. If not defined current directory is used. + path The directory containing .git. If not defined current directory is used. /url Url to remote git repository. - /b Name of the branch to use on the remote repository, must be used in combination with /url. - /u Username in case authentication is required. - /p Password in case authentication is required. - /l Path to logfile. + /b Name of the branch to use on the remote repository, must be used in combination with /url. + /u Username in case authentication is required. + /p Password in case authentication is required. + /l Path to logfile. "; Console.Write(message); } From d56fde9630ea3fd3737d9a70bab4ba29e68cca27 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Mon, 17 Mar 2014 15:22:15 +0100 Subject: [PATCH 04/11] Revert changes in BranchClassifier to make sure it always picks the right branch --- GitVersion/GitFlow/BranchClassifier.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GitVersion/GitFlow/BranchClassifier.cs b/GitVersion/GitFlow/BranchClassifier.cs index aa3ad5e890..2944a00390 100644 --- a/GitVersion/GitFlow/BranchClassifier.cs +++ b/GitVersion/GitFlow/BranchClassifier.cs @@ -43,12 +43,12 @@ public static string GetSuffix(this Branch branch, BranchType branchType) public static bool IsDevelop(this Branch branch) { - return branch.Name.EndsWith("develop"); + return branch.Name == "develop"; } public static bool IsMaster(this Branch branch) { - return branch.Name.EndsWith("master"); + return branch.Name == "master"; } public static bool IsPullRequest(this Branch branch) From 20c935dc69410df6a8e9afcb5ac7e30ebaed65f9 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Mon, 17 Mar 2014 15:57:43 +0100 Subject: [PATCH 05/11] Using repo.Refs.UpdateTarget instead of adding a new ref for remote repositories --- GitVersion/GitPreparer.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/GitVersion/GitPreparer.cs b/GitVersion/GitPreparer.cs index 01a9f41606..68355f7412 100644 --- a/GitVersion/GitPreparer.cs +++ b/GitVersion/GitPreparer.cs @@ -84,12 +84,15 @@ private string GetGitInfoFromUrl() var branch = repository.FindBranch(BranchName); if ((branch != null) && !branch.IsCurrentRepositoryHead) { - var finalName = string.Format("refs/heads/{0}", BranchName); - //repository.Refs.Add("HEAD", branch.UpstreamBranchCanonicalName, true); + // Option 1: checkout (slow) + //repository.Checkout(branch, CheckoutModifiers.Force, null, null); - repository.Refs.Add("HEAD", finalName, true); + // Option 2: add head refs + //var finalName = string.Format("refs/heads/{0}", BranchName); + //repository.Refs.Add("HEAD", finalName, true); - //var symRef = repository.Refs.Create("HEAD", string.Format("refs/heads/{0}", BranchName)); + // Option 3: replace head + repository.Refs.UpdateTarget("HEAD", branch.CanonicalName); } } } From 981c4f69c72d1973b6ed3c43ac89b6ff37ead413 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Mon, 17 Mar 2014 16:11:01 +0100 Subject: [PATCH 06/11] Removed not required code from GitPreparer --- GitVersion/GitPreparer.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/GitVersion/GitPreparer.cs b/GitVersion/GitPreparer.cs index 68355f7412..356ea356c8 100644 --- a/GitVersion/GitPreparer.cs +++ b/GitVersion/GitPreparer.cs @@ -81,19 +81,7 @@ private string GetGitInfoFromUrl() { Logger.WriteInfo(string.Format("Switching to branch '{0}'", BranchName)); - var branch = repository.FindBranch(BranchName); - if ((branch != null) && !branch.IsCurrentRepositoryHead) - { - // Option 1: checkout (slow) - //repository.Checkout(branch, CheckoutModifiers.Force, null, null); - - // Option 2: add head refs - //var finalName = string.Format("refs/heads/{0}", BranchName); - //repository.Refs.Add("HEAD", finalName, true); - - // Option 3: replace head - repository.Refs.UpdateTarget("HEAD", branch.CanonicalName); - } + repository.Refs.UpdateTarget("HEAD", targetBranchName); } } } From f3bde9cdd22fae39173df24a1ecb69fff4e8efe1 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Tue, 18 Mar 2014 16:02:47 +0100 Subject: [PATCH 07/11] Parameters are now being passed around to ensure that the username / password are first read from the environment variables, but can be overridden by command line arguments --- GitVersion/Arguments.cs | 10 ++++- GitVersion/BuildServers/BuildServerList.cs | 23 ++++++---- GitVersion/BuildServers/ContinuaCi.cs | 9 +++- GitVersion/BuildServers/GitHelper.cs | 17 ++++---- GitVersion/BuildServers/TeamCity.cs | 10 ++++- GitVersion/GitPreparer.cs | 46 ++++++++------------ GitVersion/Program.cs | 9 ++-- GitVersionTask/VersionAndBranchFinder.cs | 3 +- GitVersionTask/WriteVersionInfoToBuildLog.cs | 3 +- Tests/BuildServers/ContinuaCiTests.cs | 3 +- Tests/BuildServers/TeamCityTests.cs | 6 ++- Tests/GitHelperTests.cs | 12 +++-- Tests/UpdateAssemblyInfoTests.cs | 2 +- 13 files changed, 88 insertions(+), 65 deletions(-) diff --git a/GitVersion/Arguments.cs b/GitVersion/Arguments.cs index 6a3c1d374e..b36d8bcfa8 100644 --- a/GitVersion/Arguments.cs +++ b/GitVersion/Arguments.cs @@ -1,7 +1,15 @@ namespace GitVersion { - class Arguments + using System; + + public class Arguments { + public Arguments() + { + Username = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_USERNAME"); + Password = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_PASSWORD"); + } + public string TargetPath; public string TargetUrl; diff --git a/GitVersion/BuildServers/BuildServerList.cs b/GitVersion/BuildServers/BuildServerList.cs index a5a6407846..3de8528a15 100644 --- a/GitVersion/BuildServers/BuildServerList.cs +++ b/GitVersion/BuildServers/BuildServerList.cs @@ -5,26 +5,31 @@ public static class BuildServerList { - public static List BuildServers = new List - { - new ContinuaCi(), - new TeamCity() - }; + static List BuildServers; - public static Func> Selector = () => DefaultSelector(); + public static Func> Selector = arguments => DefaultSelector(arguments); public static void ResetSelector() { Selector = DefaultSelector; } - public static IEnumerable GetApplicableBuildServers() + public static IEnumerable GetApplicableBuildServers(Arguments arguments) { - return Selector(); + return Selector(arguments); } - static IEnumerable DefaultSelector() + static IEnumerable DefaultSelector(Arguments arguments) { + if (BuildServers == null) + { + BuildServers = new List + { + new ContinuaCi(arguments), + new TeamCity(arguments) + }; + } + foreach (var buildServer in BuildServers) { if (buildServer.CanApplyToCurrentContext()) diff --git a/GitVersion/BuildServers/ContinuaCi.cs b/GitVersion/BuildServers/ContinuaCi.cs index 040cf33d17..4154cabc63 100644 --- a/GitVersion/BuildServers/ContinuaCi.cs +++ b/GitVersion/BuildServers/ContinuaCi.cs @@ -4,6 +4,13 @@ public class ContinuaCi : IBuildServer { + readonly Arguments _arguments; + + public ContinuaCi(Arguments arguments) + { + _arguments = arguments; + } + public bool CanApplyToCurrentContext() { using (var registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\VSoft Technologies\\Continua CI Agent")) @@ -19,7 +26,7 @@ public void PerformPreProcessingSteps(string gitDirectory) throw new ErrorException("Failed to find .git directory on agent"); } - GitHelper.NormalizeGitDirectory(gitDirectory); + GitHelper.NormalizeGitDirectory(gitDirectory, _arguments); } public string[] GenerateSetParameterMessage(string name, string value) diff --git a/GitVersion/BuildServers/GitHelper.cs b/GitVersion/BuildServers/GitHelper.cs index 0074132f01..448ca7179e 100644 --- a/GitVersion/BuildServers/GitHelper.cs +++ b/GitVersion/BuildServers/GitHelper.cs @@ -1,12 +1,11 @@ namespace GitVersion { - using System; using System.Linq; using LibGit2Sharp; public static class GitHelper { - public static void NormalizeGitDirectory(string gitDirectory) + public static void NormalizeGitDirectory(string gitDirectory, Arguments arguments) { using (var repo = new Repository(gitDirectory)) { @@ -15,7 +14,7 @@ public static void NormalizeGitDirectory(string gitDirectory) Logger.WriteInfo(string.Format("Fetching from remote '{0}' using the following refspecs: {1}.", remote.Name, string.Join(", ", remote.FetchRefSpecs.Select(r => r.Specification)))); - var fetchOptions = BuildFetchOptions(); + var fetchOptions = BuildFetchOptions(arguments.Username, arguments.Password); repo.Network.Fetch(remote, fetchOptions); CreateMissingLocalBranchesFromRemoteTrackingOnes(repo, remote.Name); @@ -32,17 +31,17 @@ public static void NormalizeGitDirectory(string gitDirectory) } } - static FetchOptions BuildFetchOptions() + static FetchOptions BuildFetchOptions(string username, string password) { - // TODO: Respect username/password of arguments? - var username = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_USERNAME"); - var password = Environment.GetEnvironmentVariable("GITVERSION_REMOTE_PASSWORD"); - var fetchOptions = new FetchOptions(); if (!string.IsNullOrEmpty(username)) { - fetchOptions.Credentials = new Credentials { Username = username, Password = password }; + fetchOptions.Credentials = new Credentials + { + Username = username, + Password = password + }; } return fetchOptions; diff --git a/GitVersion/BuildServers/TeamCity.cs b/GitVersion/BuildServers/TeamCity.cs index 7577719e45..21f3245b5c 100644 --- a/GitVersion/BuildServers/TeamCity.cs +++ b/GitVersion/BuildServers/TeamCity.cs @@ -4,6 +4,14 @@ public class TeamCity : IBuildServer { + readonly Arguments _arguments; + + public TeamCity(Arguments arguments) + { + _arguments = arguments; + } + + public bool CanApplyToCurrentContext() { return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TEAMCITY_VERSION")); @@ -16,7 +24,7 @@ public void PerformPreProcessingSteps(string gitDirectory) throw new ErrorException("Failed to find .git directory on agent. Please make sure agent checkout mode is enabled for you VCS roots - http://confluence.jetbrains.com/display/TCD8/VCS+Checkout+Mode"); } - GitHelper.NormalizeGitDirectory(gitDirectory); + GitHelper.NormalizeGitDirectory(gitDirectory, _arguments); } public string[] GenerateSetParameterMessage(string name, string value) diff --git a/GitVersion/GitPreparer.cs b/GitVersion/GitPreparer.cs index 356ea356c8..ba5f3e4d0d 100644 --- a/GitVersion/GitPreparer.cs +++ b/GitVersion/GitPreparer.cs @@ -5,25 +5,13 @@ public class GitPreparer { - public GitPreparer(string targetPath, string url, string branchName, string username, string password) + readonly Arguments _arguments; + + public GitPreparer(Arguments arguments) { - TargetPath = targetPath; - Url = url; - BranchName = branchName; - Username = username; - Password = password; + _arguments = arguments; } - public string TargetPath { get; private set; } - - public string Url { get; private set; } - - public string BranchName { get; private set; } - - public string Username { get; private set; } - - public string Password { get; private set; } - public bool IsDynamicGitRepository { get { return !string.IsNullOrWhiteSpace(DynamicGitRepositoryPath); } @@ -33,9 +21,9 @@ public bool IsDynamicGitRepository public string Prepare() { - var gitPath = TargetPath; + var gitPath = _arguments.TargetPath; - if (!string.IsNullOrWhiteSpace(Url)) + if (!string.IsNullOrWhiteSpace(_arguments.TargetUrl)) { gitPath = GetGitInfoFromUrl(); } @@ -45,7 +33,7 @@ public string Prepare() private string GetGitInfoFromUrl() { - var gitDirectory = Path.Combine(TargetPath, "_dynamicrepository", ".git"); + var gitDirectory = Path.Combine(_arguments.TargetPath, "_dynamicrepository", ".git"); if (Directory.Exists(gitDirectory)) { Logger.WriteInfo(string.Format("Deleting existing .git folder from '{0}' to force new checkout from url", gitDirectory)); @@ -54,32 +42,32 @@ private string GetGitInfoFromUrl() } Credentials credentials = null; - if (!string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password)) + if (!string.IsNullOrWhiteSpace(_arguments.Username) && !string.IsNullOrWhiteSpace(_arguments.Password)) { - Logger.WriteInfo(string.Format("Setting up credentials using name '{0}'", Username)); + Logger.WriteInfo(string.Format("Setting up credentials using name '{0}'", _arguments.Username)); credentials = new Credentials() { - Username = Username, - Password = Password + Username = _arguments.Username, + Password = _arguments.Password }; } - Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", Url)); + Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", _arguments.TargetUrl)); - Repository.Clone(Url, gitDirectory, checkout: false, credentials: credentials); + Repository.Clone(_arguments.TargetUrl, gitDirectory, checkout: false, credentials: credentials); - if (!string.IsNullOrWhiteSpace(BranchName)) + if (!string.IsNullOrWhiteSpace(_arguments.TargetBranch)) { // Normalize (download branches) before using the branch - GitHelper.NormalizeGitDirectory(gitDirectory); + GitHelper.NormalizeGitDirectory(gitDirectory, _arguments); using (var repository = new Repository(gitDirectory)) { - var targetBranchName = string.Format("refs/heads/{0}", BranchName); + var targetBranchName = string.Format("refs/heads/{0}", _arguments.TargetBranch); if (!string.Equals(repository.Head.CanonicalName, targetBranchName)) { - Logger.WriteInfo(string.Format("Switching to branch '{0}'", BranchName)); + Logger.WriteInfo(string.Format("Switching to branch '{0}'", _arguments.TargetBranch)); repository.Refs.UpdateTarget("HEAD", targetBranchName); } diff --git a/GitVersion/Program.cs b/GitVersion/Program.cs index 89f1a9c2b1..2061dd2756 100644 --- a/GitVersion/Program.cs +++ b/GitVersion/Program.cs @@ -23,8 +23,7 @@ static void Main() ConfigureLogging(arguments); - var gitPreparer = new GitPreparer(arguments.TargetPath, arguments.TargetUrl, - arguments.TargetBranch, arguments.Username, arguments.Password); + var gitPreparer = new GitPreparer(arguments); var gitDirectory = gitPreparer.Prepare(); if (string.IsNullOrEmpty(gitDirectory)) { @@ -32,7 +31,7 @@ static void Main() Environment.Exit(1); } - var applicableBuildServers = GetApplicableBuildServers().ToList(); + var applicableBuildServers = GetApplicableBuildServers(arguments).ToList(); foreach (var buildServer in applicableBuildServers) { @@ -91,9 +90,9 @@ static void Main() Environment.Exit(exitCode.Value); } - static IEnumerable GetApplicableBuildServers() + static IEnumerable GetApplicableBuildServers(Arguments arguments) { - return BuildServerList.BuildServers.Where(buildServer => buildServer.CanApplyToCurrentContext()); + return BuildServerList.GetApplicableBuildServers(arguments); } static void ConfigureLogging(Arguments arguments) diff --git a/GitVersionTask/VersionAndBranchFinder.cs b/GitVersionTask/VersionAndBranchFinder.cs index b024705706..bd0ff71188 100644 --- a/GitVersionTask/VersionAndBranchFinder.cs +++ b/GitVersionTask/VersionAndBranchFinder.cs @@ -21,7 +21,8 @@ public static bool TryGetVersion(string directory, out VersionAndBranchAndDate v return false; } - foreach (var buildServer in BuildServerList.GetApplicableBuildServers()) + var arguments = new Arguments(); + foreach (var buildServer in BuildServerList.GetApplicableBuildServers(arguments)) { Logger.WriteInfo(string.Format("Executing PerformPreProcessingSteps for '{0}'.", buildServer.GetType().Name)); buildServer.PerformPreProcessingSteps(gitDirectory); diff --git a/GitVersionTask/WriteVersionInfoToBuildLog.cs b/GitVersionTask/WriteVersionInfoToBuildLog.cs index ace27db75f..8f4e6e4d11 100644 --- a/GitVersionTask/WriteVersionInfoToBuildLog.cs +++ b/GitVersionTask/WriteVersionInfoToBuildLog.cs @@ -53,7 +53,8 @@ public void InnerExecute() return; } - WriteIntegrationParameters(versionAndBranch, BuildServerList.GetApplicableBuildServers()); + var arguments = new Arguments(); + WriteIntegrationParameters(versionAndBranch, BuildServerList.GetApplicableBuildServers(arguments)); } public void WriteIntegrationParameters(VersionAndBranch versionAndBranch, IEnumerable applicableBuildServers) diff --git a/Tests/BuildServers/ContinuaCiTests.cs b/Tests/BuildServers/ContinuaCiTests.cs index a4a27dd783..e22a6092e3 100644 --- a/Tests/BuildServers/ContinuaCiTests.cs +++ b/Tests/BuildServers/ContinuaCiTests.cs @@ -8,7 +8,8 @@ public class ContinuaCiTests [Test] public void GenerateBuildVersion() { - var versionBuilder = new ContinuaCi(); + var arguments = new Arguments(); + var versionBuilder = new ContinuaCi(arguments); var continuaCiVersion = versionBuilder.GenerateSetVersionMessage("0.0.0-Beta4.7"); Assert.AreEqual("@@continua[setBuildVersion value='0.0.0-Beta4.7']", continuaCiVersion); } diff --git a/Tests/BuildServers/TeamCityTests.cs b/Tests/BuildServers/TeamCityTests.cs index 59fb56d291..34f60db1d6 100644 --- a/Tests/BuildServers/TeamCityTests.cs +++ b/Tests/BuildServers/TeamCityTests.cs @@ -7,7 +7,8 @@ public class TeamCityTests [Test] public void Develop_branch() { - var versionBuilder = new TeamCity(); + var arguments = new Arguments(); + var versionBuilder = new TeamCity(arguments); var tcVersion = versionBuilder.GenerateSetVersionMessage("0.0.0-Unstable4"); Assert.AreEqual("##teamcity[buildNumber '0.0.0-Unstable4']", tcVersion); } @@ -15,7 +16,8 @@ public void Develop_branch() [Test] public void EscapeValues() { - var versionBuilder = new TeamCity(); + var arguments = new Arguments(); + var versionBuilder = new TeamCity(arguments); var tcVersion = versionBuilder.GenerateSetParameterMessage("Foo", "0.8.0-unstable568 Branch:'develop' Sha:'ee69bff1087ebc95c6b43aa2124bd58f5722e0cb'"); Assert.AreEqual("##teamcity[setParameter name='GitFlowVersion.Foo' value='0.8.0-unstable568 Branch:|'develop|' Sha:|'ee69bff1087ebc95c6b43aa2124bd58f5722e0cb|'']", tcVersion[0]); Assert.AreEqual("##teamcity[setParameter name='GitVersion.Foo' value='0.8.0-unstable568 Branch:|'develop|' Sha:|'ee69bff1087ebc95c6b43aa2124bd58f5722e0cb|'']", tcVersion[1]); diff --git a/Tests/GitHelperTests.cs b/Tests/GitHelperTests.cs index 135f801fb5..245ff91255 100644 --- a/Tests/GitHelperTests.cs +++ b/Tests/GitHelperTests.cs @@ -12,7 +12,8 @@ public void CanDetermineTheVersionFromAFetchedMaster() { var gitDirectory = FakeTeamCityFetchAndCheckout(ASBMTestRepoWorkingDirPath, "refs/heads/master"); - GitHelper.NormalizeGitDirectory(gitDirectory); + var arguments = new Arguments(); + GitHelper.NormalizeGitDirectory(gitDirectory, arguments); using (var repository = new Repository(gitDirectory)) { @@ -29,7 +30,8 @@ public void CanDetermineTheVersionFromAPullRequest() var gitDirectory = FakeTeamCityFetchAndCheckout(repoPath, "refs/pull/1735/merge"); - GitHelper.NormalizeGitDirectory(gitDirectory); + var arguments = new Arguments(); + GitHelper.NormalizeGitDirectory(gitDirectory, arguments); using (var repository = new Repository(gitDirectory)) { @@ -44,7 +46,8 @@ public void CanDetermineTheVersionFromAFetchedDevelop() { var gitDirectory = FakeTeamCityFetchAndCheckout(ASBMTestRepoWorkingDirPath, "refs/heads/develop"); - GitHelper.NormalizeGitDirectory(gitDirectory); + var arguments = new Arguments(); + GitHelper.NormalizeGitDirectory(gitDirectory, arguments); using (var repository = new Repository(gitDirectory)) { @@ -57,7 +60,8 @@ public void CanDetermineTheVersionFromAFetchedFeature() { var gitDirectory = FakeTeamCityFetchAndCheckout(ASBMTestRepoWorkingDirPath, "refs/heads/feature/one"); - GitHelper.NormalizeGitDirectory(gitDirectory); + var arguments = new Arguments(); + GitHelper.NormalizeGitDirectory(gitDirectory, arguments); using (var repository = new Repository(gitDirectory)) { diff --git a/Tests/UpdateAssemblyInfoTests.cs b/Tests/UpdateAssemblyInfoTests.cs index 5902205664..e85933e3d4 100644 --- a/Tests/UpdateAssemblyInfoTests.cs +++ b/Tests/UpdateAssemblyInfoTests.cs @@ -106,7 +106,7 @@ public void StandardExecutionMode_CannotDetermineTheVersionFromADetachedHead() public void SetUp() { //avoid buildserver detection to make the tests pass on the buildserver - BuildServerList.Selector = () => new List(); + BuildServerList.Selector = arguments => new List(); } From 2ff757f57f6bb0580fe591906754d654af10ab1e Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Tue, 18 Mar 2014 17:05:25 +0100 Subject: [PATCH 08/11] GitVersion now writes results to console when a compatible build server is found so the build server can also pick up the version without using it as msbuild task --- GitVersion/BuildServers/BuildServerBase.cs | 33 +++++++++++++++++++ GitVersion/BuildServers/BuildServerList.cs | 17 ++++++++-- GitVersion/BuildServers/ContinuaCi.cs | 34 ++++++++++++++------ GitVersion/BuildServers/IBuildServer.cs | 5 +++ GitVersion/BuildServers/TeamCity.cs | 10 +++--- GitVersion/GitVersion.csproj | 1 + GitVersion/Program.cs | 5 +++ GitVersion/VersionCache.cs | 1 + GitVersionTask/WriteVersionInfoToBuildLog.cs | 1 - 9 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 GitVersion/BuildServers/BuildServerBase.cs diff --git a/GitVersion/BuildServers/BuildServerBase.cs b/GitVersion/BuildServers/BuildServerBase.cs new file mode 100644 index 0000000000..20c5d1a002 --- /dev/null +++ b/GitVersion/BuildServers/BuildServerBase.cs @@ -0,0 +1,33 @@ +namespace GitVersion +{ + using System; + + public abstract class BuildServerBase : IBuildServer + { + public abstract bool CanApplyToCurrentContext(); + public abstract void PerformPreProcessingSteps(string gitDirectory); + public abstract string GenerateSetVersionMessage(string versionToUseForBuildNumber); + public abstract string[] GenerateSetParameterMessage(string name, string value); + + public virtual void WriteIntegration(VersionAndBranch versionAndBranch, Action writer) + { + if (versionAndBranch == null) + { + return; + } + + if (writer == null) + { + return; + } + + writer(string.Format("Executing GenerateSetVersionMessage for '{0}'.", GetType().Name)); + writer(GenerateSetVersionMessage(versionAndBranch.GenerateSemVer())); + writer(string.Format("Executing GenerateBuildLogOutput for '{0}'.", GetType().Name)); + foreach (var buildParameter in BuildOutputFormatter.GenerateBuildLogOutput(versionAndBranch, this)) + { + writer(buildParameter); + } + } + } +} \ No newline at end of file diff --git a/GitVersion/BuildServers/BuildServerList.cs b/GitVersion/BuildServers/BuildServerList.cs index 3de8528a15..493ba0e1fe 100644 --- a/GitVersion/BuildServers/BuildServerList.cs +++ b/GitVersion/BuildServers/BuildServerList.cs @@ -30,14 +30,25 @@ static IEnumerable DefaultSelector(Arguments arguments) }; } + var buildServices = new List(); + foreach (var buildServer in BuildServers) { - if (buildServer.CanApplyToCurrentContext()) + try + { + if (buildServer.CanApplyToCurrentContext()) + { + Logger.WriteInfo(string.Format("Applicable build agent found: '{0}'.", buildServer.GetType().Name)); + buildServices.Add(buildServer); + } + } + catch (Exception ex) { - Logger.WriteInfo(string.Format("Applicable build agent found: '{0}'.", buildServer.GetType().Name)); - yield return buildServer; + Logger.WriteWarning(string.Format("Failed to check build server '{0}': {1}", buildServer.GetType().Name, ex.Message)); } } + + return buildServices; } } } diff --git a/GitVersion/BuildServers/ContinuaCi.cs b/GitVersion/BuildServers/ContinuaCi.cs index 4154cabc63..9fa3a51bb6 100644 --- a/GitVersion/BuildServers/ContinuaCi.cs +++ b/GitVersion/BuildServers/ContinuaCi.cs @@ -2,7 +2,7 @@ { using Microsoft.Win32; - public class ContinuaCi : IBuildServer + public class ContinuaCi : BuildServerBase { readonly Arguments _arguments; @@ -11,15 +11,24 @@ public ContinuaCi(Arguments arguments) _arguments = arguments; } - public bool CanApplyToCurrentContext() + public override bool CanApplyToCurrentContext() { - using (var registryKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\VSoft Technologies\\Continua CI Agent")) + const string KeyName = @"Software\VSoft Technologies\Continua CI Agent"; + + if (RegistryKeyExists(KeyName, RegistryView.Registry32)) { - return registryKey != null; + return true; } + + if (RegistryKeyExists(KeyName, RegistryView.Registry64)) + { + return true; + } + + return false; } - public void PerformPreProcessingSteps(string gitDirectory) + public override void PerformPreProcessingSteps(string gitDirectory) { if (string.IsNullOrEmpty(gitDirectory)) { @@ -29,18 +38,25 @@ public void PerformPreProcessingSteps(string gitDirectory) GitHelper.NormalizeGitDirectory(gitDirectory, _arguments); } - public string[] GenerateSetParameterMessage(string name, string value) + public override string[] GenerateSetParameterMessage(string name, string value) { - return new [] + return new[] { string.Format("@@continua[setVariable name='GitVersion.{0}' value='{1}']", name, value) }; } - public string GenerateSetVersionMessage(string versionToUseForBuildNumber) + public override string GenerateSetVersionMessage(string versionToUseForBuildNumber) { return string.Format("@@continua[setBuildVersion value='{0}']", versionToUseForBuildNumber); } - } + private static bool RegistryKeyExists(string keyName, RegistryView registryView) + { + var localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView); + localKey = localKey.OpenSubKey(keyName); + + return localKey != null; + } + } } diff --git a/GitVersion/BuildServers/IBuildServer.cs b/GitVersion/BuildServers/IBuildServer.cs index ed554156a1..28a7e38a12 100644 --- a/GitVersion/BuildServers/IBuildServer.cs +++ b/GitVersion/BuildServers/IBuildServer.cs @@ -1,10 +1,15 @@ namespace GitVersion { + using System; + public interface IBuildServer { bool CanApplyToCurrentContext(); void PerformPreProcessingSteps(string gitDirectory); string GenerateSetVersionMessage(string versionToUseForBuildNumber); string[] GenerateSetParameterMessage(string name, string value); + + void WriteIntegration(VersionAndBranch versionAndBranch, Action writer); } + } diff --git a/GitVersion/BuildServers/TeamCity.cs b/GitVersion/BuildServers/TeamCity.cs index 21f3245b5c..d9ba7af7b6 100644 --- a/GitVersion/BuildServers/TeamCity.cs +++ b/GitVersion/BuildServers/TeamCity.cs @@ -2,7 +2,7 @@ { using System; - public class TeamCity : IBuildServer + public class TeamCity : BuildServerBase { readonly Arguments _arguments; @@ -12,12 +12,12 @@ public TeamCity(Arguments arguments) } - public bool CanApplyToCurrentContext() + public override bool CanApplyToCurrentContext() { return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TEAMCITY_VERSION")); } - public void PerformPreProcessingSteps(string gitDirectory) + public override void PerformPreProcessingSteps(string gitDirectory) { if (string.IsNullOrEmpty(gitDirectory)) { @@ -27,7 +27,7 @@ public void PerformPreProcessingSteps(string gitDirectory) GitHelper.NormalizeGitDirectory(gitDirectory, _arguments); } - public string[] GenerateSetParameterMessage(string name, string value) + public override string[] GenerateSetParameterMessage(string name, string value) { return new[] { @@ -37,7 +37,7 @@ public string[] GenerateSetParameterMessage(string name, string value) }; } - public string GenerateSetVersionMessage(string versionToUseForBuildNumber) + public override string GenerateSetVersionMessage(string versionToUseForBuildNumber) { return string.Format("##teamcity[buildNumber '{0}']", EscapeValue(versionToUseForBuildNumber)); } diff --git a/GitVersion/GitVersion.csproj b/GitVersion/GitVersion.csproj index 16e8d6e92f..804bccb1eb 100644 --- a/GitVersion/GitVersion.csproj +++ b/GitVersion/GitVersion.csproj @@ -54,6 +54,7 @@ + diff --git a/GitVersion/Program.cs b/GitVersion/Program.cs index 2061dd2756..17fbc606e0 100644 --- a/GitVersion/Program.cs +++ b/GitVersion/Program.cs @@ -40,6 +40,11 @@ static void Main() var versionAndBranch = VersionCache.GetVersion(gitDirectory); + foreach (var buildServer in applicableBuildServers) + { + buildServer.WriteIntegration(versionAndBranch, Logger.WriteInfo); + } + var versionAsKeyValue = versionAndBranch.ToKeyValue(); switch (arguments.VersionPart) { diff --git a/GitVersion/VersionCache.cs b/GitVersion/VersionCache.cs index 82566ea6f1..f179690c4a 100644 --- a/GitVersion/VersionCache.cs +++ b/GitVersion/VersionCache.cs @@ -16,6 +16,7 @@ public static VersionAndBranchAndDate GetVersion(string gitDirectory) { throw new ErrorException("No Tip found. Has repo been initialize?"); } + var ticks = DirectoryDateFinder.GetLastDirectoryWrite(gitDirectory); var key = string.Format("{0}:{1}:{2}", repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks); CachedVersion cachedVersion; diff --git a/GitVersionTask/WriteVersionInfoToBuildLog.cs b/GitVersionTask/WriteVersionInfoToBuildLog.cs index 8f4e6e4d11..4725d1aad9 100644 --- a/GitVersionTask/WriteVersionInfoToBuildLog.cs +++ b/GitVersionTask/WriteVersionInfoToBuildLog.cs @@ -70,6 +70,5 @@ public void WriteIntegrationParameters(VersionAndBranch versionAndBranch, IEnume } } } - } } \ No newline at end of file From 2ed969317f4753da2420ae171402a7818a1535cf Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Tue, 18 Mar 2014 17:24:42 +0100 Subject: [PATCH 09/11] Improved integration with Continua CI --- GitVersion/BuildServers/ContinuaCi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitVersion/BuildServers/ContinuaCi.cs b/GitVersion/BuildServers/ContinuaCi.cs index 9fa3a51bb6..aa159ec1ef 100644 --- a/GitVersion/BuildServers/ContinuaCi.cs +++ b/GitVersion/BuildServers/ContinuaCi.cs @@ -42,7 +42,7 @@ public override string[] GenerateSetParameterMessage(string name, string value) { return new[] { - string.Format("@@continua[setVariable name='GitVersion.{0}' value='{1}']", name, value) + string.Format("@@continua[setVariable name='GitVersion_{0}' value='{1}']", name, value) }; } From 623f61733157fab6852f17d40bc87d926d751ac8 Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Tue, 18 Mar 2014 21:04:53 +0100 Subject: [PATCH 10/11] GitVersion now checks out bare repositories --- GitVersion/GitPreparer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitVersion/GitPreparer.cs b/GitVersion/GitPreparer.cs index ba5f3e4d0d..014d16cf09 100644 --- a/GitVersion/GitPreparer.cs +++ b/GitVersion/GitPreparer.cs @@ -55,7 +55,7 @@ private string GetGitInfoFromUrl() Logger.WriteInfo(string.Format("Retrieving git info from url '{0}'", _arguments.TargetUrl)); - Repository.Clone(_arguments.TargetUrl, gitDirectory, checkout: false, credentials: credentials); + Repository.Clone(_arguments.TargetUrl, gitDirectory, true, false, credentials: credentials); if (!string.IsNullOrWhiteSpace(_arguments.TargetBranch)) { From 292270b96a321202f261b5b4ba3733351335f05b Mon Sep 17 00:00:00 2001 From: Geert van Horrik Date: Wed, 19 Mar 2014 23:27:43 +0100 Subject: [PATCH 11/11] (+) Added /output parameter to allow the customization of the output type (json or buildserver) (-) Removed logging to console --- GitVersion/ArgumentParser.cs | 23 ++++++++++++++------- GitVersion/Arguments.cs | 10 +++++++++ GitVersion/HelpWriter.cs | 13 ++++++------ GitVersion/Program.cs | 40 ++++++++++++++++++++---------------- Tests/ArgumentParserTests.cs | 28 +++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 31 deletions(-) diff --git a/GitVersion/ArgumentParser.cs b/GitVersion/ArgumentParser.cs index a946b36232..03f78b260b 100644 --- a/GitVersion/ArgumentParser.cs +++ b/GitVersion/ArgumentParser.cs @@ -94,6 +94,18 @@ public static Arguments ParseArguments(List commandLineArguments) continue; } + if (IsSwitch("output", name)) + { + var outputType = OutputType.Json; + if (!Enum.TryParse(value, true, out outputType)) + { + throw new ErrorException(string.Format("Value '{0}' cannot be parsed as output type, please use 'json' or 'buildserver'", value)); + } + + arguments.Output = outputType; + continue; + } + throw new ErrorException(string.Format("Could not parse command line parameter '{0}'.", name)); } return arguments; @@ -125,13 +137,10 @@ static void EnsureArgumentsEvenCount(List commandLineArguments, List { - Console.WriteLine(x); }; } else @@ -121,7 +126,6 @@ static void ConfigureLogging(Arguments arguments) writeAction = x => { - Console.WriteLine(x); WriteLogEntry(arguments, x); }; } diff --git a/Tests/ArgumentParserTests.cs b/Tests/ArgumentParserTests.cs index 292c626c84..adda3fb789 100644 --- a/Tests/ArgumentParserTests.cs +++ b/Tests/ArgumentParserTests.cs @@ -61,6 +61,34 @@ public void Username_and_Password_can_be_parsed() Assert.IsFalse(arguments.IsHelp); } + [Test] + public void Unknown_output_should_throw() + { + var exception = Assert.Throws(() => ArgumentParser.ParseArguments("targetDirectoryPath -output invalid_value")); + Assert.AreEqual("Value 'invalid_value' cannot be parsed as output type, please use 'json' or 'buildserver'", exception.Message); + } + + [Test] + public void Output_defaults_to_json() + { + var arguments = ArgumentParser.ParseArguments("targetDirectoryPath"); + Assert.AreEqual(OutputType.Json, arguments.Output); + } + + [Test] + public void Output_json_can_be_parsed() + { + var arguments = ArgumentParser.ParseArguments("targetDirectoryPath -output json"); + Assert.AreEqual(OutputType.Json, arguments.Output); + } + + [Test] + public void Output_buildserver_can_be_parsed() + { + var arguments = ArgumentParser.ParseArguments("targetDirectoryPath -output buildserver"); + Assert.AreEqual(OutputType.BuildServer, arguments.Output); + } + [Test] public void Url_and_BranchName_can_be_parsed() {