Skip to content

Commit dd27b3b

Browse files
committed
fix parsing four-part versions from the update-check API
1 parent 6a9bf10 commit dd27b3b

6 files changed

Lines changed: 38 additions & 23 deletions

File tree

src/SMAPI.Toolkit/Framework/Clients/WebApi/ModEntryVersionModel.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using Newtonsoft.Json;
2+
using StardewModdingAPI.Toolkit.Serialization.Converters;
3+
14
namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
25
{
36
/// <summary>Metadata about a version.</summary>
@@ -7,6 +10,7 @@ public class ModEntryVersionModel
710
** Accessors
811
*********/
912
/// <summary>The version number.</summary>
13+
[JsonConverter(typeof(NonStandardSemanticVersionConverter))]
1014
public ISemanticVersion Version { get; set; }
1115

1216
/// <summary>The mod page URL.</summary>

src/SMAPI.Toolkit/SemanticVersion.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,18 +199,19 @@ public bool IsNonStandard()
199199
/// <returns>Returns whether parsing the version succeeded.</returns>
200200
public static bool TryParse(string version, out ISemanticVersion parsed)
201201
{
202-
return SemanticVersion.TryParseNonStandard(version, out parsed) && !parsed.IsNonStandard();
202+
return SemanticVersion.TryParse(version, allowNonStandard: false, out parsed);
203203
}
204204

205-
/// <summary>Parse a version string without throwing an exception if it fails, including support for non-standard extensions like <see cref="IPlatformSpecificVersion"/>.</summary>
205+
/// <summary>Parse a version string without throwing an exception if it fails.</summary>
206206
/// <param name="version">The version string.</param>
207+
/// <param name="allowNonStandard">Whether to allow non-standard extensions to semantic versioning.</param>
207208
/// <param name="parsed">The parsed representation.</param>
208209
/// <returns>Returns whether parsing the version succeeded.</returns>
209-
public static bool TryParseNonStandard(string version, out ISemanticVersion parsed)
210+
public static bool TryParse(string version, bool allowNonStandard, out ISemanticVersion parsed)
210211
{
211212
try
212213
{
213-
parsed = new SemanticVersion(version, true);
214+
parsed = new SemanticVersion(version, allowNonStandard);
214215
return true;
215216
}
216217
catch
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace StardewModdingAPI.Toolkit.Serialization.Converters
2+
{
3+
/// <summary>Handles deserialization of <see cref="ISemanticVersion"/>, allowing for non-standard extensions.</summary>
4+
internal class NonStandardSemanticVersionConverter : SemanticVersionConverter
5+
{
6+
/*********
7+
** Public methods
8+
*********/
9+
/// <summary>Construct an instance.</summary>
10+
public NonStandardSemanticVersionConverter()
11+
{
12+
this.AllowNonStandard = true;
13+
}
14+
}
15+
}

src/SMAPI.Toolkit/Serialization/Converters/SemanticVersionConverter.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ namespace StardewModdingAPI.Toolkit.Serialization.Converters
77
/// <summary>Handles deserialization of <see cref="ISemanticVersion"/>.</summary>
88
internal class SemanticVersionConverter : JsonConverter
99
{
10+
/*********
11+
** Fields
12+
*********/
13+
/// <summary>Whether to allow non-standard extensions to semantic versioning.</summary>
14+
protected bool AllowNonStandard { get; set; }
15+
16+
1017
/*********
1118
** Accessors
1219
*********/
@@ -78,7 +85,7 @@ private ISemanticVersion ReadString(string str, string path)
7885
{
7986
if (string.IsNullOrWhiteSpace(str))
8087
return null;
81-
if (!SemanticVersion.TryParse(str, out ISemanticVersion version))
88+
if (!SemanticVersion.TryParse(str, allowNonStandard: this.AllowNonStandard, out ISemanticVersion version))
8289
throw new SParseException($"Can't parse semantic version from invalid value '{str}', should be formatted like 1.2, 1.2.30, or 1.2.30-beta (path: {path}).");
8390
return version;
8491
}

src/SMAPI.Web/Controllers/ModsApiController.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ private async Task<ModInfoModel> GetInfoForUpdateKeyAsync(UpdateKey updateKey, b
296296
{
297297
if (result.Version == null)
298298
result.SetError(RemoteModStatus.InvalidData, $"The update key '{updateKey}' matches a mod with no version number.");
299-
else if (!this.TryParseVersion(result.Version, allowNonStandardVersions, out _))
299+
else if (!SemanticVersion.TryParse(result.Version, allowNonStandardVersions, out _))
300300
result.SetError(RemoteModStatus.InvalidData, $"The update key '{updateKey}' matches a mod with invalid semantic version '{result.Version}'.");
301301
}
302302

@@ -360,11 +360,11 @@ private ISemanticVersion GetMappedVersion(string version, IDictionary<string, st
360360
{
361361
// try mapped version
362362
string rawNewVersion = this.GetRawMappedVersion(version, map, allowNonStandard);
363-
if (this.TryParseVersion(rawNewVersion, allowNonStandard, out ISemanticVersion parsedNew))
363+
if (SemanticVersion.TryParse(rawNewVersion, allowNonStandard, out ISemanticVersion parsedNew))
364364
return parsedNew;
365365

366366
// return original version
367-
return this.TryParseVersion(version, allowNonStandard, out ISemanticVersion parsedOld)
367+
return SemanticVersion.TryParse(version, allowNonStandard, out ISemanticVersion parsedOld)
368368
? parsedOld
369369
: null;
370370
}
@@ -383,31 +383,19 @@ private string GetRawMappedVersion(string version, IDictionary<string, string> m
383383
return map[version];
384384

385385
// match parsed version
386-
if (this.TryParseVersion(version, allowNonStandard, out ISemanticVersion parsed))
386+
if (SemanticVersion.TryParse(version, allowNonStandard, out ISemanticVersion parsed))
387387
{
388388
if (map.ContainsKey(parsed.ToString()))
389389
return map[parsed.ToString()];
390390

391391
foreach (var pair in map)
392392
{
393-
if (this.TryParseVersion(pair.Key, allowNonStandard, out ISemanticVersion target) && parsed.Equals(target) && this.TryParseVersion(pair.Value, allowNonStandard, out ISemanticVersion newVersion))
393+
if (SemanticVersion.TryParse(pair.Key, allowNonStandard, out ISemanticVersion target) && parsed.Equals(target) && SemanticVersion.TryParse(pair.Value, allowNonStandard, out ISemanticVersion newVersion))
394394
return newVersion.ToString();
395395
}
396396
}
397397

398398
return version;
399399
}
400-
401-
/// <summary>Try to parse a version string.</summary>
402-
/// <param name="version">The version string.</param>
403-
/// <param name="allowNonStandard">Whether to allow non-standard versions.</param>
404-
/// <param name="parsed">The parsed representation.</param>
405-
/// <returns>Returns whether parsing the version succeeded.</returns>
406-
public bool TryParseVersion(string version, bool allowNonStandard, out ISemanticVersion parsed)
407-
{
408-
return allowNonStandard
409-
? SemanticVersion.TryParseNonStandard(version, out parsed)
410-
: SemanticVersion.TryParse(version, out parsed);
411-
}
412400
}
413401
}

src/SMAPI.Web/Framework/VersionConstraint.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public bool Match(HttpContext httpContext, IRouter route, string routeKey, Route
2828
return
2929
values.TryGetValue(routeKey, out object routeValue)
3030
&& routeValue is string routeStr
31-
&& SemanticVersion.TryParseNonStandard(routeStr, out _);
31+
&& SemanticVersion.TryParse(routeStr, allowNonStandard: true, out _);
3232
}
3333
}
3434
}

0 commit comments

Comments
 (0)