Skip to content

Commit 27d4d0c

Browse files
committed
Made GitVersionVariables more like DTO
1 parent 598b370 commit 27d4d0c

File tree

13 files changed

+128
-128
lines changed

13 files changed

+128
-128
lines changed

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
3333

3434
<IsUnitTestProject>false</IsUnitTestProject>
35-
<DisableApiAnalyzers>false</DisableApiAnalyzers>
35+
<DisableApiAnalyzers>true</DisableApiAnalyzers>
3636
<IsUnitTestProject Condition="$(MSBuildProjectName.EndsWith('.Tests')) or $(MSBuildProjectName.EndsWith('.Testing'))">true</IsUnitTestProject>
3737
</PropertyGroup>
3838

src/GitVersion.App.Tests/Helpers/ExecutionResults.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public virtual VersionVariables OutputVariables
2323
var jsonEndIndex = Output.IndexOf("}", StringComparison.Ordinal);
2424
var json = Output.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1);
2525

26-
return VersionVariables.FromJson(json);
26+
return VersionVariablesHelper.FromJson(json);
2727
}
2828
}
2929
}

src/GitVersion.App.Tests/Helpers/ProgramFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public VersionVariables? OutputVariables
9090
var jsonEndIndex = Output.IndexOf("}", StringComparison.Ordinal);
9191
var json = Output.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1);
9292

93-
return VersionVariables.FromJson(json);
93+
return VersionVariablesHelper.FromJson(json);
9494
}
9595
}
9696
}

src/GitVersion.App.Tests/JsonOutputOnBuildServerTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void BeingOnBuildServerWithOutputJsonAndOutputFileDoesNotFail(string outp
6161
var filePath = PathHelper.Combine(fixture.LocalRepositoryFixture.RepositoryPath, fileName);
6262
var json = File.ReadAllText(filePath);
6363

64-
var outputVariables = VersionVariables.FromJson(json);
64+
var outputVariables = VersionVariablesHelper.FromJson(json);
6565
outputVariables.ShouldNotBeNull();
6666
outputVariables.FullSemVer.ShouldBeEquivalentTo(expectedVersion);
6767
}

src/GitVersion.App/ArgumentParser.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class ArgumentParser : IArgumentParser
1313
private readonly IConsole console;
1414
private readonly IGlobbingResolver globbingResolver;
1515
private const string defaultOutputFileName = "GitVersion.json";
16+
private static readonly IEnumerable<string> availableVariables = VersionVariables.AvailableVariables;
1617

1718
public ArgumentParser(IEnvironment environment, ICurrentBuildAgent buildAgent, IConsole console, IGlobbingResolver globbingResolver)
1819
{
@@ -382,13 +383,13 @@ private static void ParseShowVariable(Arguments arguments, string? value, string
382383

383384
if (!value.IsNullOrWhiteSpace())
384385
{
385-
versionVariable = VersionVariables.AvailableVariables.SingleOrDefault(av => av.Equals(value.Replace("'", ""), StringComparison.CurrentCultureIgnoreCase));
386+
versionVariable = availableVariables.SingleOrDefault(av => av.Equals(value.Replace("'", ""), StringComparison.CurrentCultureIgnoreCase));
386387
}
387388

388389
if (versionVariable == null)
389390
{
390391
var message = $"{name} requires a valid version variable. Available variables are:{System.Environment.NewLine}" +
391-
string.Join(", ", VersionVariables.AvailableVariables.Select(x => string.Concat("'", x, "'")));
392+
string.Join(", ", availableVariables.Select(x => string.Concat("'", x, "'")));
392393
throw new WarningException(message);
393394
}
394395

@@ -399,14 +400,14 @@ private static void ParseFormat(Arguments arguments, string? value)
399400
{
400401
if (value.IsNullOrWhiteSpace())
401402
{
402-
throw new WarningException("Format requires a valid format string. Available variables are: " + string.Join(", ", VersionVariables.AvailableVariables));
403+
throw new WarningException("Format requires a valid format string. Available variables are: " + string.Join(", ", availableVariables));
403404
}
404405

405-
var foundVariable = VersionVariables.AvailableVariables.Any(variable => value.Contains(variable, StringComparison.CurrentCultureIgnoreCase));
406+
var foundVariable = availableVariables.Any(variable => value.Contains(variable, StringComparison.CurrentCultureIgnoreCase));
406407

407408
if (!foundVariable)
408409
{
409-
throw new WarningException("Format requires a valid format string. Available variables are: " + string.Join(", ", VersionVariables.AvailableVariables));
410+
throw new WarningException("Format requires a valid format string. Available variables are: " + string.Join(", ", availableVariables));
410411
}
411412

412413
arguments.Format = value;

src/GitVersion.Core.Tests/Extensions/GitToolsTestingExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, IG
104104

105105
public static void WriteVersionVariables(this RepositoryFixtureBase fixture, string versionFile)
106106
{
107-
var versionInfo = fixture.GetVersion();
107+
var versionVariables = fixture.GetVersion();
108108

109109
using var stream = File.Open(versionFile, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
110110
using var writer = new StreamWriter(stream);
111-
writer.Write(versionInfo.ToString());
111+
writer.Write(versionVariables.ToJsonString());
112112
}
113113

114114
public static void AssertFullSemver(this RepositoryFixtureBase fixture, string fullSemver,

src/GitVersion.Core.Tests/VersionCalculation/JsonVersionBuilderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using GitVersion.Core.Tests.Helpers;
2+
using GitVersion.OutputVariables;
23
using GitVersion.VersionCalculation;
34
using Microsoft.Extensions.DependencyInjection;
45

@@ -28,7 +29,6 @@ public void Json()
2829

2930
var variableProvider = serviceProvider.GetRequiredService<IVariableProvider>();
3031
var variables = variableProvider.GetVariablesFor(semanticVersion, configuration, null);
31-
var json = variables.ToString();
32-
json.ShouldMatchApproved(c => c.SubFolder("Approved"));
32+
variables.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
3333
}
3434
}

src/GitVersion.Core.Tests/VersionCalculation/VariableProviderTests.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using GitVersion.Core.Tests.Helpers;
22
using GitVersion.Logging;
3+
using GitVersion.OutputVariables;
34
using GitVersion.VersionCalculation;
45
using Microsoft.Extensions.DependencyInjection;
56

@@ -49,7 +50,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForPreRelease()
4950

5051
var vars = this.variableProvider.GetVariablesFor(semVer, configuration, null);
5152

52-
vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
53+
vars.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
5354
}
5455

5556
[Test]
@@ -74,7 +75,7 @@ public void ProvidesVariablesInContinuousDeploymentModeForPreRelease()
7475

7576
var vars = this.variableProvider.GetVariablesFor(semVer, configuration, null);
7677

77-
vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
78+
vars.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
7879
}
7980

8081
[Test]
@@ -98,7 +99,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForStable()
9899

99100
var vars = this.variableProvider.GetVariablesFor(semVer, configuration, null);
100101

101-
vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
102+
vars.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
102103
}
103104

104105
[Test]
@@ -122,7 +123,7 @@ public void ProvidesVariablesInContinuousDeploymentModeForStable()
122123

123124
var vars = this.variableProvider.GetVariablesFor(semVer, configuration, null);
124125

125-
vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
126+
vars.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
126127
}
127128

128129
[Test]
@@ -148,7 +149,7 @@ public void ProvidesVariablesInContinuousDeploymentModeForStableWhenCurrentCommi
148149

149150
var variables = this.variableProvider.GetVariablesFor(semVer, configuration, SemanticVersion.Empty);
150151

151-
variables.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
152+
variables.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
152153
}
153154

154155
[Test]
@@ -220,7 +221,7 @@ public void ProvidesVariablesInContinuousDeliveryModeForFeatureBranch()
220221

221222
var vars = this.variableProvider.GetVariablesFor(semVer, configuration, null);
222223

223-
vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
224+
vars.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
224225
}
225226

226227
[Test]
@@ -247,6 +248,6 @@ public void ProvidesVariablesInContinuousDeliveryModeForFeatureBranchWithCustomA
247248

248249
var vars = this.variableProvider.GetVariablesFor(semVer, configuration, null);
249250

250-
vars.ToString().ShouldMatchApproved(c => c.SubFolder("Approved"));
251+
vars.ToJsonString().ShouldMatchApproved(c => c.SubFolder("Approved"));
251252
}
252253
}
Lines changed: 3 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System.Text.Encodings.Web;
21
using GitVersion.Extensions;
3-
using GitVersion.Helpers;
4-
using YamlDotNet.Serialization;
52
using static GitVersion.Extensions.ObjectExtensions;
63

74
namespace GitVersion.OutputVariables;
@@ -97,115 +94,20 @@ public VersionVariables(string major,
9794
[ReflectionIgnore]
9895
public string? FileName { get; set; }
9996

100-
[ReflectionIgnore]
101-
public string? this[string variable] => typeof(VersionVariables).GetProperty(variable)?.GetValue(this, null) as string;
102-
10397
public IEnumerator<KeyValuePair<string, string>> GetEnumerator() => this.GetProperties().GetEnumerator();
10498

10599
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
106100

107-
// FIX ME: Shall we return an instance with no ctorArgs or explicitly fail when properties is null?
108-
private static VersionVariables FromDictionary(IEnumerable<KeyValuePair<string, string>>? properties)
109-
{
110-
var type = typeof(VersionVariables);
111-
var constructors = type.GetConstructors();
112-
113-
var ctor = constructors.Single();
114-
var ctorArgs = ctor.GetParameters()
115-
.Select(p => properties?.Single(v => string.Equals(v.Key, p.Name, StringComparison.InvariantCultureIgnoreCase)).Value)
116-
.Cast<object>()
117-
.ToArray();
118-
var instance = Activator.CreateInstance(type, ctorArgs).NotNull();
119-
return (VersionVariables)instance;
120-
}
121-
122-
public static VersionVariables FromJson(string json)
123-
{
124-
var serializeOptions = JsonSerializerOptions();
125-
var variablePairs = JsonSerializer.Deserialize<Dictionary<string, string>>(json, serializeOptions);
126-
return FromDictionary(variablePairs);
127-
}
128-
129-
public static VersionVariables FromFile(string filePath, IFileSystem fileSystem)
130-
{
131-
try
132-
{
133-
var retryAction = new RetryAction<IOException, VersionVariables>();
134-
return retryAction.Execute(() => FromFileInternal(filePath, fileSystem));
135-
}
136-
catch (AggregateException ex)
137-
{
138-
var lastException = ex.InnerExceptions.LastOrDefault() ?? ex.InnerException;
139-
if (lastException != null)
140-
{
141-
throw lastException;
142-
}
143-
throw;
144-
}
145-
}
146-
private static VersionVariables FromFileInternal(string filePath, IFileSystem fileSystem)
147-
{
148-
using var stream = fileSystem.OpenRead(filePath);
149-
using var reader = new StreamReader(stream);
150-
var dictionary = new Deserializer().Deserialize<Dictionary<string, string>>(reader);
151-
var versionVariables = FromDictionary(dictionary);
152-
versionVariables.FileName = filePath;
153-
return versionVariables;
154-
}
155-
156101
public bool TryGetValue(string variable, out string? variableValue)
157102
{
158-
if (ContainsKey(variable))
103+
var propertyInfo = typeof(VersionVariables).GetProperty(variable);
104+
if (propertyInfo != null)
159105
{
160-
variableValue = this[variable];
106+
variableValue = propertyInfo.GetValue(this, null) as string;
161107
return true;
162108
}
163109

164110
variableValue = null;
165111
return false;
166112
}
167-
168-
private static bool ContainsKey(string variable) => typeof(VersionVariables).GetProperty(variable) != null;
169-
170-
public override string ToString()
171-
{
172-
var variablesType = typeof(VersionVariablesJsonModel);
173-
var variables = new VersionVariablesJsonModel();
174-
175-
foreach (var (key, value) in this.GetProperties())
176-
{
177-
var propertyInfo = variablesType.GetProperty(key);
178-
propertyInfo?.SetValue(variables, ChangeType(value, propertyInfo.PropertyType));
179-
}
180-
181-
var serializeOptions = JsonSerializerOptions();
182-
183-
return JsonSerializer.Serialize(variables, serializeOptions);
184-
}
185-
186-
private static JsonSerializerOptions JsonSerializerOptions()
187-
{
188-
var serializeOptions = new JsonSerializerOptions
189-
{
190-
WriteIndented = true,
191-
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
192-
Converters = { new VersionVariablesJsonStringConverter() }
193-
};
194-
return serializeOptions;
195-
}
196-
197-
private static object? ChangeType(object? value, Type type)
198-
{
199-
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
200-
{
201-
if (value == null || value.ToString()?.Length == 0)
202-
{
203-
return null;
204-
}
205-
206-
type = Nullable.GetUnderlyingType(type)!;
207-
}
208-
209-
return Convert.ChangeType(value, type);
210-
}
211113
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System.Text.Encodings.Web;
2+
using GitVersion.Extensions;
3+
using GitVersion.Helpers;
4+
using YamlDotNet.Serialization;
5+
6+
namespace GitVersion.OutputVariables;
7+
8+
public static class VersionVariablesHelper
9+
{
10+
public static VersionVariables FromJson(string json)
11+
{
12+
var serializeOptions = JsonSerializerOptions();
13+
var variablePairs = JsonSerializer.Deserialize<Dictionary<string, string>>(json, serializeOptions);
14+
return FromDictionary(variablePairs);
15+
}
16+
17+
public static VersionVariables FromFile(string filePath, IFileSystem fileSystem)
18+
{
19+
try
20+
{
21+
var retryAction = new RetryAction<IOException, VersionVariables>();
22+
return retryAction.Execute(() => FromFileInternal(filePath, fileSystem));
23+
}
24+
catch (AggregateException ex)
25+
{
26+
var lastException = ex.InnerExceptions.LastOrDefault() ?? ex.InnerException;
27+
if (lastException != null)
28+
{
29+
throw lastException;
30+
}
31+
32+
throw;
33+
}
34+
}
35+
36+
public static string ToJsonString(this VersionVariables versionVariables)
37+
{
38+
var variablesType = typeof(VersionVariablesJsonModel);
39+
var variables = new VersionVariablesJsonModel();
40+
41+
foreach (var (key, value) in versionVariables.GetProperties())
42+
{
43+
var propertyInfo = variablesType.GetProperty(key);
44+
propertyInfo?.SetValue(variables, ChangeType(value, propertyInfo.PropertyType));
45+
}
46+
47+
var serializeOptions = JsonSerializerOptions();
48+
49+
return JsonSerializer.Serialize(variables, serializeOptions);
50+
}
51+
52+
private static VersionVariables FromDictionary(IEnumerable<KeyValuePair<string, string>>? properties)
53+
{
54+
var type = typeof(VersionVariables);
55+
var constructors = type.GetConstructors();
56+
57+
var ctor = constructors.Single();
58+
var ctorArgs = ctor.GetParameters()
59+
.Select(p => properties?.Single(v => string.Equals(v.Key, p.Name, StringComparison.InvariantCultureIgnoreCase)).Value)
60+
.Cast<object>()
61+
.ToArray();
62+
var instance = Activator.CreateInstance(type, ctorArgs).NotNull();
63+
return (VersionVariables)instance;
64+
}
65+
66+
private static VersionVariables FromFileInternal(string filePath, IFileSystem fileSystem)
67+
{
68+
using var stream = fileSystem.OpenRead(filePath);
69+
using var reader = new StreamReader(stream);
70+
var dictionary = new Deserializer().Deserialize<Dictionary<string, string>>(reader);
71+
var versionVariables = FromDictionary(dictionary);
72+
versionVariables.FileName = filePath;
73+
return versionVariables;
74+
}
75+
76+
private static JsonSerializerOptions JsonSerializerOptions()
77+
{
78+
var serializeOptions = new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, Converters = { new VersionVariablesJsonStringConverter() } };
79+
return serializeOptions;
80+
}
81+
82+
private static object? ChangeType(object? value, Type type)
83+
{
84+
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
85+
{
86+
if (value == null || value.ToString()?.Length == 0)
87+
{
88+
return null;
89+
}
90+
91+
type = Nullable.GetUnderlyingType(type)!;
92+
}
93+
94+
return Convert.ChangeType(value, type);
95+
}
96+
}

0 commit comments

Comments
 (0)