diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index a283ad2dbb..6249bc92ab 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -29,6 +29,14 @@ jobs:
- name: Run tests
run: xvfb-run ./build test+only --configuration=Release --where="Category!=FlakyNetwork"
+ - name: Publish ckan.dll to NuGet
+ env:
+ NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
+ if: env.NUGET_API_KEY
+ run: |
+ curl -o nuget.exe -L 'https://dist.nuget.org/win-x86-commandline/v5.6.0/nuget.exe'
+ mono nuget.exe push _build/out/CKAN/Release/bin/*.nupkg ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json -SkipDuplicate
+
- name: Build dmg
run: ./build osx --configuration=Release --exclusive
- name: Build deb
diff --git a/AutoUpdate/CKAN-autoupdate.csproj b/AutoUpdate/CKAN-autoupdate.csproj
index bae16e8402..581f14cd2b 100644
--- a/AutoUpdate/CKAN-autoupdate.csproj
+++ b/AutoUpdate/CKAN-autoupdate.csproj
@@ -20,6 +20,7 @@
..\assets\ckan.ico
net48;net7.0-windows
true
+ true
512
prompt
4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c8ada8e77d..20f71d65af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -30,6 +30,7 @@ All notable changes to this project will be documented in this file.
- [Netkan] Fix null reference exception in swinfo transformer (#3999 by: HebaruSan)
- [Netkan] Improve netkan relationship error message (#4020, #4021 by: HebaruSan)
- [Core] Get KSP2 version from game assembly (#4034 by: HebaruSan)
+- [Multiple] Build nuget package, support netstandard2.0 build (#4039 by: HebaruSan)
## v1.34.4 (Niven)
diff --git a/Core/CKAN-core.csproj b/Core/CKAN-core.csproj
index b3f998f100..bdac8c276d 100644
--- a/Core/CKAN-core.csproj
+++ b/Core/CKAN-core.csproj
@@ -18,32 +18,43 @@
false
7.3
IDE1006
- net48;net7.0
+ netstandard2.0;net48;net7.0
PrepareResources;$(CompileDependsOn)
+
+ CKAN
+ Comprehensive Kerbal Archive Network
+ Manages mods for KSP1 and KPS2
+ $([System.Text.RegularExpressions.Regex]::Replace(
+ $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)\..\CHANGELOG.md")),
+ "^.*?##\s+v(\S+).*$", "$1",
+ System.Text.RegularExpressions.RegexOptions.Singleline))
+ $(Version)
+ The CKAN Authors
+ Copyright © CKAN Authors 2014–2024
+ KerbalSpaceProgram Mods
+ true
+ true
+ MIT
+ README.md
+ https://github.com/KSP-CKAN/CKAN
+ https://github.com/KSP-CKAN/CKAN
+ git
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Properties\GlobalAssemblyVersionInfo.cs
@@ -53,6 +64,7 @@
+
diff --git a/Core/Extensions/EnumerableExtensions.cs b/Core/Extensions/EnumerableExtensions.cs
index ca57a2aedf..8c6b30042c 100644
--- a/Core/Extensions/EnumerableExtensions.cs
+++ b/Core/Extensions/EnumerableExtensions.cs
@@ -15,16 +15,43 @@ public static ICollection AsCollection(this IEnumerable source)
? throw new ArgumentNullException(nameof(source))
: source is ICollection collection ? collection : source.ToArray();
-#if NET45
-
- public static HashSet ToHashSet(this IEnumerable source)
+#if NET45 || NETSTANDARD2_0
+
+ #if NET45
+ public
+ #elif NETSTANDARD2_0
+ internal
+ #endif
+ static HashSet ToHashSet(this IEnumerable source)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return new HashSet(source);
}
+ #if NET45
+ public
+ #elif NETSTANDARD2_0
+ internal
+ #endif
+ static HashSet ToHashSet(this IEnumerable source,
+ IEqualityComparer comparer)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ return new HashSet(source, comparer);
+ }
+
+#endif
+
+#if NET45
+
public static IEnumerable Append(this IEnumerable source, T next)
=> source.Concat(Enumerable.Repeat(next, 1));
@@ -115,7 +142,7 @@ public static TimeSpan Sum(this IEnumerable source)
public static IEnumerable ZipMany(this IEnumerable seq1, IEnumerable seq2, Func> func)
=> seq1.Zip(seq2, func).SelectMany(seqs => seqs);
-#if NETFRAMEWORK
+#if NETFRAMEWORK || NETSTANDARD2_0
///
/// Eliminate duplicate elements based on the value returned by a callback
@@ -142,7 +169,7 @@ public static IEnumerable TraverseNodes(this T start, Func getNext)
}
}
-#if NETFRAMEWORK
+#if NETFRAMEWORK || NETSTANDARD2_0
///
/// Make pairs out of the elements of two sequences
diff --git a/Core/Registry/IRegistryQuerier.cs b/Core/Registry/IRegistryQuerier.cs
index 060c216b15..378e5b3c38 100644
--- a/Core/Registry/IRegistryQuerier.cs
+++ b/Core/Registry/IRegistryQuerier.cs
@@ -7,6 +7,9 @@
using CKAN.Versioning;
using CKAN.Games;
+#if NETSTANDARD2_0
+using CKAN.Extensions;
+#endif
namespace CKAN
{
diff --git a/Core/Relationships/SanityChecker.cs b/Core/Relationships/SanityChecker.cs
index ab36d3fc20..0fb88eefe3 100644
--- a/Core/Relationships/SanityChecker.cs
+++ b/Core/Relationships/SanityChecker.cs
@@ -1,7 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
+
using CKAN.Versioning;
+#if NETSTANDARD2_0
+using CKAN.Extensions;
+#endif
namespace CKAN
{
diff --git a/Core/Types/CkanModule.cs b/Core/Types/CkanModule.cs
index b0211c3cd6..67272748c5 100644
--- a/Core/Types/CkanModule.cs
+++ b/Core/Types/CkanModule.cs
@@ -14,6 +14,9 @@
using CKAN.Versioning;
using CKAN.Games;
+#if NETSTANDARD2_0
+using CKAN.Extensions;
+#endif
namespace CKAN
{
diff --git a/Core/Types/License.cs b/Core/Types/License.cs
index b618ac1132..3eb5a6a169 100644
--- a/Core/Types/License.cs
+++ b/Core/Types/License.cs
@@ -3,6 +3,10 @@
using Newtonsoft.Json;
+#if NETSTANDARD2_0
+using CKAN.Extensions;
+#endif
+
namespace CKAN
{
///
diff --git a/GUI/CKAN-GUI.csproj b/GUI/CKAN-GUI.csproj
index beb157d9d6..ff39ae5f99 100644
--- a/GUI/CKAN-GUI.csproj
+++ b/GUI/CKAN-GUI.csproj
@@ -21,6 +21,7 @@
net48;net7.0-windows
$(TargetFramework.Replace("-windows", ""))
true
+ true
512
prompt
4
diff --git a/README.md b/README.md
index 4fe9976302..815d5902f9 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ It provides strong assurances that mods are installed in the way prescribed by t
for the correct version of Kerbal Space Program, alongside their dependencies, and without any conflicting mods.
CKAN is great for players _and_ for authors:
+
- players can find new content and install it with just a few clicks;
- modders don't have to worry about misinstall problems or outdated versions;
diff --git a/Tests/Core/Registry/CompatibilitySorter.cs b/Tests/Core/Registry/CompatibilitySorter.cs
index 9a323aa109..49490db012 100644
--- a/Tests/Core/Registry/CompatibilitySorter.cs
+++ b/Tests/Core/Registry/CompatibilitySorter.cs
@@ -5,7 +5,9 @@
using CKAN;
using CKAN.Versioning;
+#if NET45
using CKAN.Extensions;
+#endif
using Tests.Data;
diff --git a/build.cake b/build.cake
index e42238b02c..c1ffd67ce5 100644
--- a/build.cake
+++ b/build.cake
@@ -15,6 +15,9 @@ var configuration = Argument("configuration", "Debug");
var solution = Argument("solution", "CKAN.sln");
var rootDirectory = Context.Environment.WorkingDirectory;
+var coreProj = rootDirectory.Combine("Core")
+ .CombineWithFilePath("CKAN-core.csproj")
+ .FullPath;
var buildDirectory = rootDirectory.Combine("_build");
var nugetDirectory = buildDirectory.Combine("lib")
.Combine("nuget");
@@ -190,37 +193,11 @@ Task("Restore")
.Description("Intermediate - Download dependencies")
.Does(() =>
{
- if (IsRunningOnWindows())
+ DotNetRestore(solution, new DotNetRestoreSettings
{
- DotNetRestore(solution, new DotNetRestoreSettings
- {
- PackagesDirectory = nugetDirectory,
- EnvironmentVariables = new Dictionary { { "Configuration", configuration } },
- });
- }
- else
- {
- // NuGet is confused by multi-targeting, and
- // Mono has no idea what "net7.0" is. Only restore for buildNetFramework.
- DotNetRestore(solution, new DotNetRestoreSettings
- {
- PackagesDirectory = nugetDirectory,
- EnvironmentVariables = new Dictionary { { "Configuration", configuration } },
- MSBuildSettings = new DotNetMSBuildSettings()
- .SetConfiguration(configuration)
- .WithProperty("TargetFramework",
- buildNetFramework),
- });
- DotNetRestore(solution, new DotNetRestoreSettings
- {
- PackagesDirectory = nugetDirectory,
- EnvironmentVariables = new Dictionary { { "Configuration", "NoGUI" } },
- MSBuildSettings = new DotNetMSBuildSettings()
- .SetConfiguration("NoGUI")
- .WithProperty("TargetFramework",
- "net7.0"),
- });
- }
+ PackagesDirectory = nugetDirectory,
+ EnvironmentVariables = new Dictionary { { "Configuration", configuration } },
+ });
});
Task("Build")
@@ -241,15 +218,21 @@ Task("Build")
}
else
{
- // Mono has no idea what "net7.0" is
+ // Use dotnet to build the Core DLL to get the nupkg
+ // (only created if all TargetFrameworks are built together)
+ DotNetBuild(coreProj, new DotNetBuildSettings
+ {
+ Configuration = configuration,
+ });
+ // Use Mono to build for net48 since dotnet can't use WinForms on Linux
MSBuild(solution,
settings => settings.SetConfiguration(configuration)
.WithProperty("TargetFramework",
buildNetFramework));
+ // Use dotnet to build the stuff Mono can't build
DotNetBuild(solution, new DotNetBuildSettings
{
Configuration = "NoGUI",
- NoRestore = true,
Framework = "net7.0",
});
}
@@ -296,7 +279,7 @@ Task("Repack-Ckan")
.Combine(configuration)
.Combine("bin")
.Combine(buildNetFramework))));
- // Need netstandard.dll facade to instantiate types from ValveKeyValue on Mono
+ // Need facade to instantiate types from netstandard2.0 DLLs on Mono
assemblyPaths.Add(FacadesDirectory().CombineWithFilePath("netstandard.dll"));
var ckanLogFile = repackDirectory.Combine(configuration)
.CombineWithFilePath($"ckan.log");
@@ -355,6 +338,8 @@ Task("Repack-Netkan")
var netkanLogFile = repackDirectory.Combine(configuration)
.CombineWithFilePath($"netkan.log");
var assemblyPaths = GetFiles(string.Format("{0}/*.dll", netkanBinDirectory));
+ // Need facade to instantiate types from netstandard2.0 DLLs on Mono
+ assemblyPaths.Add(FacadesDirectory().CombineWithFilePath("netstandard.dll"));
ReportRepacking(netkanFile, netkanLogFile);
ILRepack(
netkanFile,
@@ -446,6 +431,7 @@ Task("Test-UnitTests+Only")
{
Configuration = configuration,
NoBuild = true,
+ NoLogo = true,
Filter = where,
ResultsDirectory = nunitOutputDirectory,
Verbosity = DotNetVerbosity.Minimal,
@@ -456,7 +442,9 @@ Task("Test-UnitTests+Only")
DotNetTest(solution, new DotNetTestSettings
{
Configuration = "NoGUI",
+ Framework = "net7.0",
NoBuild = true,
+ NoLogo = true,
Filter = where,
ResultsDirectory = nunitOutputDirectory,
Verbosity = DotNetVerbosity.Minimal,
@@ -471,6 +459,7 @@ Task("Test-UnitTests+Only")
Configuration = configuration,
Where = where,
Work = nunitOutputDirectory,
+ NoHeader = true,
// Work around System.Runtime.Remoting.RemotingException : Tcp transport error.
Process = NUnit3ProcessOption.InProcess,
});