Skip to content

add JSON Serializer #2060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 24, 2020
3 changes: 1 addition & 2 deletions src/GitVersionCore.Tests/JsonVersionBuilderTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using NUnit.Framework;
using Shouldly;
using GitVersion.OutputFormatters;
using GitVersion.OutputVariables;
using GitVersion;
using GitVersionCore.Tests.Helpers;
Expand Down Expand Up @@ -38,7 +37,7 @@ public void Json()

var variableProvider = sp.GetService<IVariableProvider>();
var variables = variableProvider.GetVariablesFor(semanticVersion, config, false);
var json = JsonOutputFormatter.ToJson(variables);
var json = variables.ToString();
json.ShouldMatchApproved(c => c.SubFolder("Approved"));
}
}
Expand Down
17 changes: 8 additions & 9 deletions src/GitVersionCore.Tests/VariableProviderTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using GitVersion;
using GitVersion.Logging;
using GitVersion.OutputFormatters;
using GitVersion.OutputVariables;
using GitVersion.VersioningModes;
using GitVersionCore.Tests.Helpers;
Expand Down Expand Up @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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]
Expand All @@ -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"));
}
}
}
16 changes: 12 additions & 4 deletions src/GitVersionCore/BuildServers/AppVeyor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using GitVersion.OutputVariables;
using GitVersion.Logging;
using System.Text;
using GitVersion.Helpers;

namespace GitVersion.BuildServers
{
Expand All @@ -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");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, it's back using our own Serializer 🙇

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😄

var response = httpClient.PutAsync("api/build", stringContent).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();

Expand All @@ -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();

Expand Down
30 changes: 30 additions & 0 deletions src/GitVersionCore/Extensions/ObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace GitVersion.Extensions
{
public static class ObjectExtensions
{
public sealed class ReflectionIgnoreAttribute : Attribute
{
}

public static void Deconstruct<TKey, TValue>(
this KeyValuePair<TKey, TValue> kvp,
out TKey key,
out TValue value)
{
key = kvp.Key;
value = kvp.Value;
}

public static IEnumerable<KeyValuePair<string, string>> GetProperties(this object obj)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could properly use a better name 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GetProperties is fine?

{
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<string, string>(p.Name, (string) p.GetValue(obj, null)));
}
}
}
33 changes: 33 additions & 0 deletions src/GitVersionCore/Helpers/JsonSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Text;
using GitVersion.Extensions;

namespace GitVersion.Helpers
{
public static class JsonSerializer
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this overkill?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. This turned out quite a bit more complicated than I had originally visioned, seeing how naïve the existing custom serialization code is. Is all of this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can write a simpler one that only supports dictionary in one depth?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asbjornu Please take another look, I chose a more simplified version that can only do objects.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much simpler and sufficient, I think. If we need the full power of a full-fledged JSON serializer, we'll add a dependency to one, but I don't think that need is here at the moment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with adding such dependency is that you may have dependency conflicts with those using the same JSON serializer dependency.
Reason for #2017 😉 When using AppVeyor, that needed ewtonsoft.json dep and the project uses newtonsoft.json in a different version.

{
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"));
}
}
38 changes: 0 additions & 38 deletions src/GitVersionCore/OutputFormatters/JsonOutputFormatter.cs

This file was deleted.

12 changes: 5 additions & 7 deletions src/GitVersionCore/OutputVariables/VersionVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -125,12 +127,7 @@ public static IEnumerable<string> AvailableVariables

public IEnumerator<KeyValuePair<string, string>> 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<string, string>(p.Name, (string)p.GetValue(this, null)))
.GetEnumerator();
return this.GetProperties().GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
Expand Down Expand Up @@ -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);
}
}
}
2 changes: 1 addition & 1 deletion src/GitVersionExe/ExecCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void Execute()
switch (arguments.ShowVariable)
{
case null:
Console.WriteLine(JsonOutputFormatter.ToJson(variables));
Console.WriteLine(variables.ToString());
break;

default:
Expand Down