Skip to content

Commit 1f88fca

Browse files
authored
Update Plugins Tooling to use SemanticVersion (#422)
* Update Plugins Tooling to use PluginVersion class
1 parent 6682df1 commit 1f88fca

File tree

14 files changed

+248
-25
lines changed

14 files changed

+248
-25
lines changed

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Core.Tests/PluginIdentityTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class PluginIdentityTest
1919
[DataRow("Test\nPlugin")]
2020
public void HasValidId_InvalidCharacters_ReturnFalse(string id)
2121
{
22-
var sut = new PluginIdentity(id, new Version(1, 2, 3));
22+
var sut = new PluginIdentity(id, new PluginVersion(1, 2, 3));
2323
Assert.IsFalse(sut.HasValidId(out string _));
2424
}
2525

@@ -31,14 +31,14 @@ public void HasValidId_InvalidCharacters_ReturnFalse(string id)
3131
[DataRow("Test.Plugin-1.2")]
3232
public void HasValidId_ValidId_ReturnTrue(string id)
3333
{
34-
var sut = new PluginIdentity(id, new Version(1, 2, 3));
34+
var sut = new PluginIdentity(id, new PluginVersion(1, 2, 3));
3535
Assert.IsTrue(sut.HasValidId(out string _));
3636
}
3737

3838
[TestMethod]
3939
public void HasValidId_LongId_ReturnFalse()
4040
{
41-
var sut = new PluginIdentity(new string('A', PluginIdentity.MaxIdLength + 1), new Version(1, 2, 3));
41+
var sut = new PluginIdentity(new string('A', PluginIdentity.MaxIdLength + 1), new PluginVersion(1, 2, 3));
4242
Assert.IsFalse(sut.HasValidId(out string _));
4343
}
4444
}

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Core/Metadata/PluginMetadata.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Collections.Generic;
66
using System.Text.Json.Serialization;
77
using Microsoft.Performance.SDK;
8+
using Microsoft.Performance.Toolkit.Plugins.Core.Serialization;
9+
using NuGet.Versioning;
810

911
namespace Microsoft.Performance.Toolkit.Plugins.Core.Metadata
1012
{
@@ -44,7 +46,7 @@ public PluginMetadata(
4446
ulong installedSize,
4547
string displayName,
4648
string description,
47-
Version sdkVersion,
49+
SemanticVersion sdkVersion,
4850
Uri projectUrl,
4951
IEnumerable<PluginOwnerInfo> owners)
5052
{
@@ -85,7 +87,8 @@ public PluginMetadata(
8587
/// <summary>
8688
/// Gets the version of the performance SDK which this plugin depends upon.
8789
/// </summary>
88-
public Version SdkVersion { get; }
90+
[JsonConverter(typeof(SemanticVersionJsonConverter))]
91+
public SemanticVersion SdkVersion { get; }
8992

9093
/// <summary>
9194
/// Gets the owners information of this plugin.

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Core/PluginIdentity.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public sealed class PluginIdentity
2626
/// <param name="version">
2727
/// The version of this plugin.
2828
/// </param>
29-
public PluginIdentity(string id, Version version)
29+
public PluginIdentity(string id, PluginVersion version)
3030
{
3131
Guard.NotNull(id, nameof(id));
3232
Guard.NotNull(version, nameof(version));
@@ -43,7 +43,7 @@ public PluginIdentity(string id, Version version)
4343
/// <summary>
4444
/// Gets the version of this plugin.
4545
/// </summary>
46-
public Version Version { get; }
46+
public PluginVersion Version { get; }
4747

4848
/// <inheritdoc />
4949
public bool Equals(PluginIdentity other)
@@ -77,7 +77,7 @@ public static bool Equals(PluginIdentity a, PluginIdentity b)
7777
}
7878

7979
return string.Equals(a.Id, b.Id, StringComparison.Ordinal) &&
80-
Version.Equals(a.Version, b.Version);
80+
PluginVersion.Equals(a.Version, b.Version);
8181
}
8282

8383
/// <inheritdoc />

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Core/PluginVersion.cs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.Performance.SDK;
5+
using NuGet.Versioning;
6+
using System;
7+
8+
namespace Microsoft.Performance.Toolkit.Plugins.Core
9+
{
10+
/// <summary>
11+
/// Represents a version of a plugin.
12+
/// </summary>
13+
public sealed class PluginVersion
14+
: IEquatable<PluginVersion>
15+
{
16+
private readonly SemanticVersion version;
17+
18+
/// <summary>
19+
/// Parses the specified version string and returns a new instance of <see cref="PluginVersion"/>.
20+
/// </summary>
21+
/// <param name="versionString">The version string to parse.</param>
22+
/// <returns>A new instance of <see cref="PluginVersion"/>.</returns>
23+
/// <exception cref="ArgumentNullException">Thrown when <paramref name="versionString"/> is null.</exception>
24+
/// <exception cref="ArgumentException">Thrown when <paramref name="versionString"/> is not a valid version.</exception>
25+
public static PluginVersion Parse(string versionString)
26+
{
27+
Guard.NotNull(versionString, nameof(versionString));
28+
29+
return new PluginVersion(SemanticVersion.Parse(versionString));
30+
}
31+
32+
private PluginVersion(SemanticVersion version)
33+
{
34+
this.version = version;
35+
}
36+
37+
/// <summary>
38+
/// Initializes a new instance of the <see cref="PluginVersion"/> class.
39+
/// </summary>
40+
/// <param name="major">The major version number.</param>
41+
/// <param name="minor">The minor version number.</param>
42+
/// <param name="patch">The patch version number.</param>
43+
public PluginVersion(int major, int minor, int patch)
44+
: this(new SemanticVersion(major, minor, patch))
45+
{
46+
}
47+
48+
/// <summary>
49+
/// Initializes a new instance of the <see cref="PluginVersion"/> class.
50+
/// </summary>
51+
/// <param name="major">The major version number.</param>
52+
/// <param name="minor">The minor version number.</param>
53+
/// <param name="patch">The patch version number.</param>
54+
/// <param name="preReleaseTag">The pre-release tag.</param>
55+
public PluginVersion(int major, int minor, int patch, string preReleaseTag)
56+
: this(new SemanticVersion(major, minor, patch, preReleaseTag))
57+
{
58+
}
59+
60+
/// <summary>
61+
/// Initializes a new instance of the <see cref="PluginVersion"/> class.
62+
/// </summary>
63+
/// <param name="major">The major version number.</param>
64+
/// <param name="minor">The minor version number.</param>
65+
/// <param name="patch">The patch version number.</param>
66+
/// <param name="preReleaseTag">The pre-release tag.</param>
67+
/// <param name="buildMetadata">The build metadata.</param>
68+
public PluginVersion(int major, int minor, int patch, string preReleaseTag, string buildMetadata)
69+
: this(new SemanticVersion(major, minor, patch, preReleaseTag, buildMetadata))
70+
{
71+
}
72+
73+
/// <summary>
74+
/// Gets the major version number.
75+
/// </summary>
76+
public int Major => version.Major;
77+
78+
/// <summary>
79+
/// Gets the minor version number.
80+
/// </summary>
81+
public int Minor => version.Minor;
82+
83+
/// <summary>
84+
/// Gets the patch version number.
85+
/// </summary>
86+
public int Patch => version.Patch;
87+
88+
/// <summary>
89+
/// Gets the pre-release tag.
90+
/// </summary>
91+
public string PreReleaseTag => version.Release;
92+
93+
/// <summary>
94+
/// Returns the string representation of the version.
95+
/// </summary>
96+
/// <returns>The string representation of the version.</returns>
97+
public override string ToString()
98+
{
99+
return version.ToString();
100+
}
101+
102+
public static bool operator ==(PluginVersion left, PluginVersion right)
103+
{
104+
if (ReferenceEquals(left, right))
105+
{
106+
return true;
107+
}
108+
109+
if (left is null || right is null)
110+
{
111+
return false;
112+
}
113+
114+
return left.Equals(right);
115+
}
116+
117+
public static bool operator !=(PluginVersion left, PluginVersion right)
118+
{
119+
return !(left == right);
120+
}
121+
122+
public static bool operator <(PluginVersion left, PluginVersion right)
123+
{
124+
return left.version < right.version;
125+
}
126+
127+
public static bool operator <=(PluginVersion left, PluginVersion right)
128+
{
129+
return left.version <= right.version;
130+
}
131+
132+
public static bool operator >(PluginVersion left, PluginVersion right)
133+
{
134+
return left.version > right.version;
135+
}
136+
137+
public static bool operator >=(PluginVersion left, PluginVersion right)
138+
{
139+
return left.version >= right.version;
140+
}
141+
142+
/// <summary>
143+
/// Determines whether the specified object is equal to the current object.
144+
/// </summary>
145+
/// <param name="obj">The object to compare with the current object.</param>
146+
/// <returns>true if the specified object is equal to the current object; otherwise, false.</returns>
147+
public override bool Equals(object obj)
148+
{
149+
return this.Equals(obj as PluginVersion);
150+
}
151+
152+
/// <summary>
153+
/// Determines whether the specified <see cref="PluginVersion"/> is equal to the current <see cref="PluginVersion"/>.
154+
/// </summary>
155+
/// <param name="other">The <see cref="PluginVersion"/> to compare with the current <see cref="PluginVersion"/>.</param>
156+
/// <returns>true if the specified <see cref="PluginVersion"/> is equal to the current <see cref="PluginVersion"/>; otherwise, false.</returns>
157+
public bool Equals(PluginVersion other)
158+
{
159+
return SemanticVersion.Equals(this.version, other.version);
160+
}
161+
162+
/// <summary>
163+
/// Serves as the default hash function.
164+
/// </summary>
165+
/// <returns>A hash code for the current object.</returns>
166+
public override int GetHashCode()
167+
{
168+
return this.version.GetHashCode();
169+
}
170+
}
171+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
8+
namespace Microsoft.Performance.Toolkit.Plugins.Core.Serialization
9+
{
10+
public class PluginVersionJsonConverter : JsonConverter<PluginVersion>
11+
{
12+
public override PluginVersion Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
13+
{
14+
var versionString = reader.GetString();
15+
return versionString is null ? null : PluginVersion.Parse(versionString);
16+
}
17+
public override void Write(Utf8JsonWriter writer, PluginVersion value, JsonSerializerOptions options)
18+
{
19+
writer.WriteStringValue(value.ToString());
20+
}
21+
}
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using NuGet.Versioning;
5+
using System;
6+
using System.Text.Json;
7+
using System.Text.Json.Serialization;
8+
9+
namespace Microsoft.Performance.Toolkit.Plugins.Core.Serialization
10+
{
11+
public class SemanticVersionJsonConverter : JsonConverter<SemanticVersion>
12+
{
13+
public override SemanticVersion Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
14+
{
15+
var versionString = reader.GetString();
16+
return versionString is null ? null : SemanticVersion.Parse(versionString);
17+
}
18+
19+
public override void Write(Utf8JsonWriter writer, SemanticVersion value, JsonSerializerOptions options)
20+
{
21+
writer.WriteStringValue(value.ToString());
22+
}
23+
}
24+
}

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Runtime.Tests/FileSystemInstalledPluginStorageTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ public async Task RemoveAsync_PluginInstallDirRemoved()
362362

363363
var fakeSerializer = new Mock<ISerializer<PluginContentsMetadata>>();
364364
var fakeChecksumCalculator = new Mock<IDirectoryChecksumCalculator>();
365-
var fakePluginIdentity = new PluginIdentity("foo", new Version(1, 0, 0));
365+
var fakePluginIdentity = new PluginIdentity("foo", new PluginVersion(1, 0, 0));
366366

367367
var fakeDir = new Mock<IPluginsStorageDirectory>();
368368
fakeDir.Setup(d => d.GetRootDirectory(fakePluginIdentity)).Returns(this.tempDirectory);
@@ -403,7 +403,7 @@ public async Task TryGetPluginContentsInfoAsync_PluginContentsInfoFileExists_Plu
403403
fakeSerializer.Setup(x => x.DeserializeAsync(It.IsAny<Stream>(), It.IsAny<CancellationToken>())).ReturnsAsync(fakeContentsInfo);
404404

405405
var fakeChecksumCalculator = new Mock<IDirectoryChecksumCalculator>();
406-
var fakePluginIdentity = new PluginIdentity("foo", new Version(1, 0, 0));
406+
var fakePluginIdentity = new PluginIdentity("foo", new PluginVersion(1, 0, 0));
407407

408408
var fakeDir = new Mock<IPluginsStorageDirectory>();
409409
string contentsFileDestPath = Path.Combine(this.tempDirectory, "contents.txt");
@@ -437,7 +437,7 @@ public async Task TryGetPluginContentsInfoAsync_PluginContentsInfoFileDoesNotExi
437437

438438
var fakeSerializer = new Mock<ISerializer<PluginContentsMetadata>>();
439439
var fakeChecksumCalculator = new Mock<IDirectoryChecksumCalculator>();
440-
var fakePluginIdentity = new PluginIdentity("foo", new Version(1, 0, 0));
440+
var fakePluginIdentity = new PluginIdentity("foo", new PluginVersion(1, 0, 0));
441441

442442
var fakeDir = new Mock<IPluginsStorageDirectory>();
443443
string contentsFileDestPath = Path.Combine(this.tempDirectory, "contents.txt");

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Runtime.Tests/FileSystemPluginRegistryTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ private InstalledPluginInfo CreatePluginWithBumpedVersion(InstalledPluginInfo pl
567567
new PluginMetadata(
568568
new PluginIdentity(
569569
plugin.Metadata.Identity.Id,
570-
new Version(plugin.Metadata.Identity.Version.Major + 1, 0, 0, 0)),
570+
new PluginVersion(plugin.Metadata.Identity.Version.Major + 1, 0, 0, "alpha")),
571571
plugin.Metadata.InstalledSize,
572572
plugin.Metadata.DisplayName,
573573
plugin.Metadata.Description,

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Runtime.Tests/TestData/FakeMetadata.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using Microsoft.Performance.Toolkit.Plugins.Core;
55
using Microsoft.Performance.Toolkit.Plugins.Core.Metadata;
6+
using NuGet.Versioning;
67

78
namespace Microsoft.Performance.Toolkit.Plugins.Runtime.Tests;
89

@@ -11,11 +12,11 @@ internal static class FakeMetadata
1112
public static PluginMetadata GetFakeMetadataWithOnlyIdentityAndSdkVersion()
1213
{
1314
return new PluginMetadata(
14-
new PluginIdentity("fake_id", new Version("1.0.0")),
15+
new PluginIdentity("fake_id", PluginVersion.Parse("1.0.0")),
1516
0,
1617
null,
1718
null,
18-
new Version("1.0.0"),
19+
SemanticVersion.Parse("1.0.0"),
1920
null,
2021
null);
2122
}

src/PluginsSystem/Microsoft.Performance.Toolkit.Plugins.Runtime.Tests/Validation/PluginIdentifierValidatorTest.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Performance.Toolkit.Plugins.Core.Metadata;
77
using Microsoft.Performance.Toolkit.Plugins.Runtime.Validation;
88
using Microsoft.VisualStudio.TestTools.UnitTesting;
9+
using NuGet.Versioning;
910

1011
namespace Microsoft.Performance.Toolkit.Plugins.Runtime.Tests.Validation;
1112

@@ -38,9 +39,9 @@ public void InvalidPluginIdDoesNotPassGate()
3839

3940
private PluginMetadata CreatePluginMetadata(string pluginId)
4041
{
41-
var stubVersion = new Version(1, 2, 3);
42+
var stubVersion = new SemanticVersion(1, 2, 3);
4243

43-
var pluginIdentity = new PluginIdentity(pluginId, stubVersion);
44+
var pluginIdentity = new PluginIdentity(pluginId, PluginVersion.Parse(stubVersion.ToString()));
4445

4546
return new PluginMetadata(
4647
pluginIdentity,

0 commit comments

Comments
 (0)