diff --git a/src/GitVersionCore.Tests/JsonVersionBuilderTests.cs b/src/GitVersionCore.Tests/JsonVersionBuilderTests.cs index 9ae1113834..3fbf73ad18 100644 --- a/src/GitVersionCore.Tests/JsonVersionBuilderTests.cs +++ b/src/GitVersionCore.Tests/JsonVersionBuilderTests.cs @@ -1,7 +1,6 @@ using System; using NUnit.Framework; using Shouldly; -using GitVersion.OutputFormatters; using GitVersion.OutputVariables; using GitVersion; using GitVersionCore.Tests.Helpers; @@ -38,7 +37,7 @@ public void Json() var variableProvider = sp.GetService(); var variables = variableProvider.GetVariablesFor(semanticVersion, config, false); - var json = JsonOutputFormatter.ToJson(variables); + var json = variables.ToString(); json.ShouldMatchApproved(c => c.SubFolder("Approved")); } } diff --git a/src/GitVersionCore.Tests/VariableProviderTests.cs b/src/GitVersionCore.Tests/VariableProviderTests.cs index 7556b8837c..e61b2e1ad4 100644 --- a/src/GitVersionCore.Tests/VariableProviderTests.cs +++ b/src/GitVersionCore.Tests/VariableProviderTests.cs @@ -1,6 +1,5 @@ using GitVersion; using GitVersion.Logging; -using GitVersion.OutputFormatters; using GitVersion.OutputVariables; using GitVersion.VersioningModes; using GitVersionCore.Tests.Helpers; @@ -74,7 +73,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForPreRelease() var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -101,7 +100,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForPreReleaseWithPadding() var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -127,7 +126,7 @@ public void ProvidesVariablesInContinuousDeploymentModeForPreRelease() var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -152,7 +151,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForStable() var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -177,7 +176,7 @@ public void ProvidesVariablesInContinuousDeploymentModeForStable() var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -205,7 +204,7 @@ public void ProvidesVariablesInContinuousDeploymentModeForStableWhenCurrentCommi var vars = variableProvider.GetVariablesFor(semVer, config, true); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -277,7 +276,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForFeatureBranch() var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } [Test] @@ -304,7 +303,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForFeatureBranchWithCustomA var vars = variableProvider.GetVariablesFor(semVer, config, false); - JsonOutputFormatter.ToJson(vars).ShouldMatchApproved(c => c.SubFolder("Approved")); + vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved")); } } } diff --git a/src/GitVersionCore/BuildServers/AppVeyor.cs b/src/GitVersionCore/BuildServers/AppVeyor.cs index 6c7c593453..5a4a341a7d 100644 --- a/src/GitVersionCore/BuildServers/AppVeyor.cs +++ b/src/GitVersionCore/BuildServers/AppVeyor.cs @@ -3,6 +3,7 @@ using GitVersion.OutputVariables; using GitVersion.Logging; using System.Text; +using GitVersion.Helpers; namespace GitVersion.BuildServers { @@ -22,9 +23,12 @@ public override string GenerateSetVersionMessage(VersionVariables variables) using var httpClient = GetHttpClient(); - var body = $"{{\"version\":\"{variables.FullSemVer}.build.{buildNumber}\"}}"; + var body = new + { + version = $"{variables.FullSemVer}.build.{buildNumber}", + }; - var stringContent = new StringContent(body, Encoding.UTF8, "application/json"); + var stringContent = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json"); var response = httpClient.PutAsync("api/build", stringContent).GetAwaiter().GetResult(); response.EnsureSuccessStatusCode(); @@ -35,9 +39,13 @@ public override string[] GenerateSetParameterMessage(string name, string value) { var httpClient = GetHttpClient(); - var body = $"{{\"name\": \"GitVersion_{name}\",\"value\": \"{value}\"}}"; + var body = new + { + name = $"GitVersion_{name}", + value = $"{value}" + }; - var stringContent = new StringContent(body, Encoding.UTF8, "application/json"); + var stringContent = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json"); var response = httpClient.PostAsync("api/build/variables", stringContent).GetAwaiter().GetResult(); response.EnsureSuccessStatusCode(); diff --git a/src/GitVersionCore/Extensions/ObjectExtensions.cs b/src/GitVersionCore/Extensions/ObjectExtensions.cs new file mode 100644 index 0000000000..8751d48e81 --- /dev/null +++ b/src/GitVersionCore/Extensions/ObjectExtensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace GitVersion.Extensions +{ + public static class ObjectExtensions + { + internal sealed class ReflectionIgnoreAttribute : Attribute + { + } + + public static void Deconstruct( + this KeyValuePair kvp, + out TKey key, + out TValue value) + { + key = kvp.Key; + value = kvp.Value; + } + + public static IEnumerable> GetProperties(this object obj) + { + var type = typeof(string); + return obj.GetType().GetProperties() + .Where(p => p.PropertyType == type && !p.GetIndexParameters().Any() && !p.GetCustomAttributes(typeof(ReflectionIgnoreAttribute), false).Any()) + .Select(p => new KeyValuePair(p.Name, (string) p.GetValue(obj, null))); + } + } +} diff --git a/src/GitVersionCore/Helpers/JsonSerializer.cs b/src/GitVersionCore/Helpers/JsonSerializer.cs new file mode 100644 index 0000000000..e017674068 --- /dev/null +++ b/src/GitVersionCore/Helpers/JsonSerializer.cs @@ -0,0 +1,33 @@ +using System.Text; +using GitVersion.Extensions; + +namespace GitVersion.Helpers +{ + public static class JsonSerializer + { + public static string Serialize(object obj) + { + var builder = new StringBuilder(); + builder.AppendLine("{"); + var first = true; + foreach (var (key, value) in obj.GetProperties()) + { + if (!first) builder.AppendLine(","); + else first = false; + + builder.Append($" \"{key}\":"); + + // preserve leading zeros for padding + if (NotAPaddedNumber(value) && int.TryParse(value, out var number)) + builder.Append(number); + else + builder.Append($"\"{value}\""); + } + + builder.AppendLine().Append("}"); + return builder.ToString(); + } + + private static bool NotAPaddedNumber(string value) => value != null && (value == "0" || !value.StartsWith("0")); + } +} diff --git a/src/GitVersionCore/OutputFormatters/JsonOutputFormatter.cs b/src/GitVersionCore/OutputFormatters/JsonOutputFormatter.cs deleted file mode 100644 index cf4b52cb04..0000000000 --- a/src/GitVersionCore/OutputFormatters/JsonOutputFormatter.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using GitVersion.OutputVariables; -using GitVersion.Extensions; - -namespace GitVersion.OutputFormatters -{ - public static class JsonOutputFormatter - { - public static string ToJson(VersionVariables variables) - { - var builder = new StringBuilder(); - builder.AppendLine("{"); - var last = variables.Last().Key; - foreach (var variable in variables) - { - var isLast = (variable.Key == last); - // preserve leading zeros for padding - if (int.TryParse(variable.Value, out var value) && NotAPaddedNumber(variable)) - builder.AppendLineFormat(" \"{0}\":{1}{2}", variable.Key, value, isLast ? string.Empty : ","); - else - builder.AppendLineFormat(" \"{0}\":\"{1}\"{2}", variable.Key, variable.Value, isLast ? string.Empty : ","); - } - - builder.Append("}"); - return builder.ToString(); - } - - private static bool NotAPaddedNumber(KeyValuePair variable) - { - if (variable.Value == "0") - return true; - - return !variable.Value.StartsWith("0"); - } - } -} diff --git a/src/GitVersionCore/OutputVariables/VersionVariables.cs b/src/GitVersionCore/OutputVariables/VersionVariables.cs index a89f0180a6..216c19377f 100644 --- a/src/GitVersionCore/OutputVariables/VersionVariables.cs +++ b/src/GitVersionCore/OutputVariables/VersionVariables.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using GitVersion.Helpers; using YamlDotNet.Serialization; +using static GitVersion.Extensions.ObjectExtensions; namespace GitVersion.OutputVariables { @@ -125,12 +127,7 @@ public static IEnumerable AvailableVariables public IEnumerator> GetEnumerator() { - var type = typeof(string); - return typeof(VersionVariables) - .GetProperties() - .Where(p => p.PropertyType == type && !p.GetIndexParameters().Any() && !p.GetCustomAttributes(typeof(ReflectionIgnoreAttribute), false).Any()) - .Select(p => new KeyValuePair(p.Name, (string)p.GetValue(this, null))) - .GetEnumerator(); + return this.GetProperties().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() @@ -178,8 +175,9 @@ public bool ContainsKey(string variable) return typeof(VersionVariables).GetProperty(variable) != null; } - private sealed class ReflectionIgnoreAttribute : Attribute + public override string ToString() { + return JsonSerializer.Serialize(this); } } } diff --git a/src/GitVersionExe/ExecCommand.cs b/src/GitVersionExe/ExecCommand.cs index 38a40ff958..8ffc471773 100644 --- a/src/GitVersionExe/ExecCommand.cs +++ b/src/GitVersionExe/ExecCommand.cs @@ -54,7 +54,7 @@ public void Execute() switch (arguments.ShowVariable) { case null: - Console.WriteLine(JsonOutputFormatter.ToJson(variables)); + Console.WriteLine(variables.ToString()); break; default: