reverse mod build package migration to .NET 5 (#837)
The migrated package didn't work consistently in VIsual Studio, so this suppresses nullable annotations in .NET Standard instead.
This commit is contained in:
parent
df955c0d3e
commit
238045ba9c
|
@ -5,7 +5,10 @@
|
|||
<Product>SMAPI</Product>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AssemblySearchPaths>$(AssemblySearchPaths);{GAC}</AssemblySearchPaths>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<!--enable nullable annotations, except in .NET Standard 2.0 where they aren't supported-->
|
||||
<Nullable Condition="'$(TargetFramework)' == 'net5.0'">enable</Nullable>
|
||||
<NoWarn Condition="'$(TargetFramework)' != 'net5.0'">$(NoWarn);CS8632</NoWarn>
|
||||
|
||||
<!--set platform-->
|
||||
<DefineConstants Condition="$(OS) == 'Windows_NT'">$(DefineConstants);SMAPI_FOR_WINDOWS</DefineConstants>
|
||||
|
|
|
@ -413,19 +413,9 @@ when you compile it.
|
|||
|
||||
## Release notes
|
||||
## Upcoming release
|
||||
* Migrated from .NET Standard 2.0 to .NET 5.0.
|
||||
* Added detection for Xbox app game folders.
|
||||
* Internal refactoring.
|
||||
|
||||
**Troubleshooting:**
|
||||
Due to the framework change, you might see build errors like _task failed unexpectedly_ that mentions `System.Runtime Version=5.0.0`. If so:
|
||||
|
||||
1. Make sure you have Visual Studio 2022 or later.
|
||||
2. Exit all instances of Visual Studio.
|
||||
3. Delete the hidden `.vs` folder in your solution folder.
|
||||
4. Delete the `bin` and `obj` folders in each project folder.
|
||||
5. Reopen the solution and rebuild, and now it should work fine.
|
||||
|
||||
## 4.0.0
|
||||
Released 30 November 2021.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
<RootNamespace>StardewModdingAPI.ModBuildConfig.Analyzer</RootNamespace>
|
||||
<Version>3.0.0</Version>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<OutputPath>bin</OutputPath>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
<!--build-->
|
||||
<RootNamespace>StardewModdingAPI.ModBuildConfig</RootNamespace>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
<RootNamespace>StardewModdingAPI</RootNamespace>
|
||||
<Description>Provides toolkit interfaces which are available to SMAPI mods.</Description>
|
||||
<TargetFrameworks>net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net5.0; netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -105,7 +105,12 @@ namespace StardewModdingAPI.Toolkit.Framework
|
|||
/// <param name="raw">The raw characters to parse.</param>
|
||||
/// <param name="index">The index of the next character to read.</param>
|
||||
/// <param name="tag">The parsed tag.</param>
|
||||
private static bool TryParseTag(char[] raw, ref int index, [NotNullWhen(true)] out string? tag)
|
||||
private static bool TryParseTag(char[] raw, ref int index,
|
||||
#if NET5_0_OR_GREATER
|
||||
[NotNullWhen(true)]
|
||||
#endif
|
||||
out string? tag
|
||||
)
|
||||
{
|
||||
// read tag length
|
||||
int length = 0;
|
||||
|
|
|
@ -16,7 +16,9 @@ namespace StardewModdingAPI.Toolkit.Framework.UpdateData
|
|||
public ModSiteKey Site { get; }
|
||||
|
||||
/// <summary>The mod ID within the repository.</summary>
|
||||
#if NET5_0_OR_GREATER
|
||||
[MemberNotNullWhen(true, nameof(LooksValid))]
|
||||
#endif
|
||||
public string? ID { get; }
|
||||
|
||||
/// <summary>If specified, a substring in download names/descriptions to match.</summary>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
<RootNamespace>StardewModdingAPI.Toolkit</RootNamespace>
|
||||
<Description>A library which encapsulates mod-handling logic for mod managers and tools. Not intended for use by mods.</Description>
|
||||
<TargetFrameworks>net5.0</TargetFrameworks>
|
||||
<TargetFrameworks>net5.0; netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -198,7 +198,12 @@ namespace StardewModdingAPI.Toolkit
|
|||
/// <param name="version">The version string.</param>
|
||||
/// <param name="parsed">The parsed representation.</param>
|
||||
/// <returns>Returns whether parsing the version succeeded.</returns>
|
||||
public static bool TryParse(string? version, [NotNullWhen(true)] out ISemanticVersion? parsed)
|
||||
public static bool TryParse(string? version,
|
||||
#if NET5_0_OR_GREATER
|
||||
[NotNullWhen(true)]
|
||||
#endif
|
||||
out ISemanticVersion? parsed
|
||||
)
|
||||
{
|
||||
return SemanticVersion.TryParse(version, allowNonStandard: false, out parsed);
|
||||
}
|
||||
|
@ -208,7 +213,12 @@ namespace StardewModdingAPI.Toolkit
|
|||
/// <param name="allowNonStandard">Whether to allow non-standard extensions to semantic versioning.</param>
|
||||
/// <param name="parsed">The parsed representation.</param>
|
||||
/// <returns>Returns whether parsing the version succeeded.</returns>
|
||||
public static bool TryParse(string? version, bool allowNonStandard, [NotNullWhen(true)] out ISemanticVersion? parsed)
|
||||
public static bool TryParse(string? version, bool allowNonStandard,
|
||||
#if NET5_0_OR_GREATER
|
||||
[NotNullWhen(true)]
|
||||
#endif
|
||||
out ISemanticVersion? parsed
|
||||
)
|
||||
{
|
||||
if (version == null)
|
||||
{
|
||||
|
|
|
@ -37,7 +37,12 @@ namespace StardewModdingAPI.Toolkit.Serialization
|
|||
/// <returns>Returns false if the file doesn't exist, else true.</returns>
|
||||
/// <exception cref="ArgumentException">The given <paramref name="fullPath"/> is empty or invalid.</exception>
|
||||
/// <exception cref="JsonReaderException">The file contains invalid JSON.</exception>
|
||||
public bool ReadJsonFileIfExists<TModel>(string fullPath, [NotNullWhen(true)] out TModel? result)
|
||||
public bool ReadJsonFileIfExists<TModel>(string fullPath,
|
||||
#if NET5_0_OR_GREATER
|
||||
[NotNullWhen(true)]
|
||||
#endif
|
||||
out TModel? result
|
||||
)
|
||||
{
|
||||
// validate
|
||||
if (string.IsNullOrWhiteSpace(fullPath))
|
||||
|
|
|
@ -115,7 +115,9 @@ namespace StardewModdingAPI.Toolkit.Serialization.Models
|
|||
*********/
|
||||
/// <summary>Normalize whitespace in a raw string.</summary>
|
||||
/// <param name="input">The input to strip.</param>
|
||||
#if NET5_0_OR_GREATER
|
||||
[return: NotNullIfNotNull("input")]
|
||||
#endif
|
||||
private string? NormalizeWhitespace(string? input)
|
||||
{
|
||||
return input
|
||||
|
|
|
@ -33,7 +33,9 @@ namespace StardewModdingAPI.Toolkit.Serialization.Models
|
|||
*********/
|
||||
/// <summary>Normalize whitespace in a raw string.</summary>
|
||||
/// <param name="input">The input to strip.</param>
|
||||
#if NET5_0_OR_GREATER
|
||||
[return: NotNullIfNotNull("input")]
|
||||
#endif
|
||||
private string? NormalizeWhitespace(string? input)
|
||||
{
|
||||
return input?.Trim();
|
||||
|
|
|
@ -54,7 +54,9 @@ namespace StardewModdingAPI.Toolkit.Serialization.Models
|
|||
*********/
|
||||
/// <summary>Normalize whitespace in a raw string.</summary>
|
||||
/// <param name="input">The input to strip.</param>
|
||||
#if NET5_0_OR_GREATER
|
||||
[return: NotNullIfNotNull("input")]
|
||||
#endif
|
||||
private string? NormalizeWhitespace(string? input)
|
||||
{
|
||||
return input?.Trim();
|
||||
|
|
|
@ -50,7 +50,9 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
/// <summary>Normalize an asset name to match how MonoGame's content APIs would normalize and cache it.</summary>
|
||||
/// <param name="assetName">The asset name to normalize.</param>
|
||||
[Pure]
|
||||
#if NET5_0_OR_GREATER
|
||||
[return: NotNullIfNotNull("assetName")]
|
||||
#endif
|
||||
public static string? NormalizeAssetName(string? assetName)
|
||||
{
|
||||
assetName = assetName?.Trim();
|
||||
|
@ -64,7 +66,9 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
/// <param name="path">The file path to normalize.</param>
|
||||
/// <remarks>This should only be used for file paths. For asset names, use <see cref="NormalizeAssetName"/> instead.</remarks>
|
||||
[Pure]
|
||||
#if NET5_0_OR_GREATER
|
||||
[return: NotNullIfNotNull("path")]
|
||||
#endif
|
||||
public static string? NormalizePath(string? path)
|
||||
{
|
||||
path = path?.Trim();
|
||||
|
@ -89,7 +93,7 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
}
|
||||
|
||||
// keep trailing separator
|
||||
if ((!hasRoot || segments.Any()) && PathUtilities.PossiblePathSeparators.Contains(path[^1]))
|
||||
if ((!hasRoot || segments.Any()) && PathUtilities.PossiblePathSeparators.Contains(path[path.Length - 1]))
|
||||
newPath += PathUtilities.PreferredPathSeparator;
|
||||
|
||||
return newPath;
|
||||
|
@ -101,7 +105,43 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
[Pure]
|
||||
public static string GetRelativePath(string sourceDir, string targetPath)
|
||||
{
|
||||
#if NET5_0
|
||||
return Path.GetRelativePath(sourceDir, targetPath);
|
||||
#else
|
||||
// NOTE:
|
||||
// this is a heuristic implementation that works in the cases SMAPI needs it for, but it
|
||||
// doesn't handle all edge cases (e.g. case-sensitivity on Linux, or traversing between
|
||||
// UNC paths on Windows). SMAPI and mods will use the more robust .NET 5 version anyway
|
||||
// though, this is only for compatibility with the mod build package.
|
||||
|
||||
// convert to URIs
|
||||
Uri from = new(sourceDir.TrimEnd(PathUtilities.PossiblePathSeparators) + "/");
|
||||
Uri to = new(targetPath.TrimEnd(PathUtilities.PossiblePathSeparators) + "/");
|
||||
if (from.Scheme != to.Scheme)
|
||||
throw new InvalidOperationException($"Can't get path for '{targetPath}' relative to '{sourceDir}'.");
|
||||
|
||||
// get relative path
|
||||
string rawUrl = Uri.UnescapeDataString(from.MakeRelativeUri(to).ToString());
|
||||
if (rawUrl.StartsWith("file://"))
|
||||
rawUrl = PathUtilities.WindowsUncRoot + rawUrl.Substring("file://".Length);
|
||||
string relative = PathUtilities.NormalizePath(rawUrl);
|
||||
|
||||
// normalize
|
||||
if (relative == "")
|
||||
relative = ".";
|
||||
else
|
||||
{
|
||||
// trim trailing slash from URL
|
||||
if (relative.EndsWith(PathUtilities.PreferredPathSeparator.ToString()))
|
||||
relative = relative.Substring(0, relative.Length - 1);
|
||||
|
||||
// fix root
|
||||
if (relative.StartsWith("file:") && !targetPath.Contains("file:"))
|
||||
relative = relative.Substring("file:".Length);
|
||||
}
|
||||
|
||||
return relative;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Get whether a path is relative and doesn't try to climb out of its containing folder (e.g. doesn't contain <c>../</c>).</summary>
|
||||
|
|
Loading…
Reference in New Issue