New: Drop Mono Support

Co-Authored-By: ta264 <ta264@users.noreply.github.com>
This commit is contained in:
Qstick 2021-06-26 23:19:41 -04:00
parent 79a10fa18f
commit cc572729ff
69 changed files with 39 additions and 1248 deletions

View File

@ -115,10 +115,6 @@ stages:
artifact: WindowsCoreTests
displayName: Publish Windows Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net472/linux-x64/publish'
artifact: LinuxTests
displayName: Publish Linux Mono Test Package
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- publish: '$(testsFolder)/net5.0/linux-x64/publish'
artifact: LinuxCoreTests
displayName: Publish Linux Test Package
@ -277,14 +273,6 @@ stages:
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/macos/net5.0
- task: ArchiveFiles@2
displayName: Create Linux Mono tar
inputs:
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux.tar.gz'
archiveType: 'tar'
tarCompression: 'gz'
includeRootFolder: false
rootFolderOrFile: $(artifactsFolder)/linux-x64/net472
- task: ArchiveFiles@2
displayName: Create Linux Core tar
inputs:
@ -439,14 +427,6 @@ stages:
- powershell: Set-Service SCardSvr -StartupType Manual
displayName: Enable Windows Test Service
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
- bash: |
SYMLINK=6_6_0
MONOPREFIX=/Library/Frameworks/Mono.framework/Versions/$SYMLINK
echo "##vso[task.setvariable variable=MONOPREFIX;]$MONOPREFIX"
echo "##vso[task.setvariable variable=PKG_CONFIG_PATH;]$MONOPREFIX/lib/pkgconfig:$MONOPREFIX/share/pkgconfig:$PKG_CONFIG_PATH"
echo "##vso[task.setvariable variable=PATH;]$MONOPREFIX/bin:$PATH"
displayName: Set Mono Version
condition: and(succeeded(), eq(variables['osName'], 'Mac'))
- bash: find ${TESTSFOLDER} -name "Radarr.Test.Dummy" -exec chmod a+x {} \;
displayName: Make Test Dummy Executable
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
@ -470,18 +450,6 @@ stages:
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
strategy:
matrix:
mono520:
testName: 'Mono 5.20'
artifactName: LinuxTests
containerImage: ghcr.io/servarr/testimages:mono-5.20
mono610:
testName: 'Mono 6.10'
artifactName: LinuxTests
containerImage: ghcr.io/servarr/testimages:mono-6.10
mono612:
testName: 'Mono 6.12'
artifactName: LinuxTests
containerImage: ghcr.io/servarr/testimages:mono-6.12
alpine:
testName: 'Musl Net Core'
artifactName: LinuxMuslCoreTests
@ -566,14 +534,6 @@ stages:
vmImage: $(imageName)
steps:
- bash: |
SYMLINK=6_6_0
MONOPREFIX=/Library/Frameworks/Mono.framework/Versions/$SYMLINK
echo "##vso[task.setvariable variable=MONOPREFIX;]$MONOPREFIX"
echo "##vso[task.setvariable variable=PKG_CONFIG_PATH;]$MONOPREFIX/lib/pkgconfig:$MONOPREFIX/share/pkgconfig:$PKG_CONFIG_PATH"
echo "##vso[task.setvariable variable=PATH;]$MONOPREFIX/bin:$PATH"
displayName: Set Mono Version
condition: and(succeeded(), eq(variables['osName'], 'Mac'))
- task: UseDotNet@2
displayName: 'Install .net core'
inputs:
@ -665,21 +625,6 @@ stages:
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
strategy:
matrix:
mono520:
testName: 'Mono 5.20'
artifactName: LinuxTests
containerImage: ghcr.io/servarr/testimages:mono-5.20
pattern: 'Radarr.*.linux.tar.gz'
mono610:
testName: 'Mono 6.10'
artifactName: LinuxTests
containerImage: ghcr.io/servarr/testimages:mono-6.10
pattern: 'Radarr.*.linux.tar.gz'
mono612:
testName: 'Mono 6.12'
artifactName: LinuxTests
containerImage: ghcr.io/servarr/testimages:mono-6.12
pattern: 'Radarr.*.linux.tar.gz'
alpine:
testName: 'Musl Net Core'
artifactName: LinuxMuslCoreTests

View File

@ -33,7 +33,6 @@ EnableBsdSupport()
if grep -qv freebsd-x64 src/Directory.Build.props; then
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64</RuntimeIdentifiers>^g" src/Directory.Build.props
sed -i'' -e "s^<ExcludedRuntimeFrameworkPairs>\(.*\)</ExcludedRuntimeFrameworkPairs>^<ExcludedRuntimeFrameworkPairs>\1;freebsd-x64:net472</ExcludedRuntimeFrameworkPairs>^g" src/Directory.Build.props
fi
}
@ -148,11 +147,6 @@ PackageMacOS()
PackageFiles "$folder" "$framework" "osx-x64"
if [ "$framework" = "net472" ]; then
echo "Adding Startup script"
cp macOS/Radarr $folder
fi
echo "Removing Service helpers"
rm -f $folder/ServiceUninstall.*
rm -f $folder/ServiceInstall.*
@ -337,7 +331,6 @@ then
PackageTests "net5.0" "linux-x64"
PackageTests "net5.0" "linux-musl-x64"
PackageTests "net5.0" "osx-x64"
PackageTests "net472" "linux-x64"
if [ "$ENABLE_BSD" = "YES" ];
then
PackageTests "net5.0" "freebsd-x64"
@ -377,7 +370,6 @@ then
Package "net5.0" "linux-musl-arm64"
Package "net5.0" "linux-arm"
Package "net5.0" "osx-x64"
Package "net472" "linux-x64"
if [ "$ENABLE_BSD" = "YES" ];
then
Package "net5.0" "freebsd-x64"

View File

@ -6,7 +6,6 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<RuntimeIdentifiers>win-x64;win-x86;osx-x64;linux-x64;linux-musl-x64;linux-arm;linux-arm64;linux-musl-arm64</RuntimeIdentifiers>
<ExcludedRuntimeFrameworkPairs>win-x64:net472;win-x86:net472;osx-x64:net472;linux-arm:net472;linux-arm64:net472;linux-musl-x64:net472;linux-musl-arm64:net472</ExcludedRuntimeFrameworkPairs>
<RadarrRootDir>$(MSBuildThisFileDirectory)..\</RadarrRootDir>
@ -100,14 +99,6 @@
<PackageReference Include="coverlet.collector" Version="3.0.4-preview.27.ge7cb7c3b40" />
</ItemGroup>
<!-- Allow building net framework using mono -->
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup Condition="'$(RadarrProject)'=='true' and '$(EnableAnalyzers)'=='false'">
<!-- FXCop Built into Net5 SDK now as NETAnalyzers, Enabled by default on net5 projects -->
<EnableNETAnalyzers>false</EnableNETAnalyzers>

View File

@ -1,11 +1,4 @@
<Project>
<!-- below net4.7.1 the new portable pdb format has no line numbers, pdb to mdb probably doesn't like it either -->
<PropertyGroup Condition="'$(TargetFramework)' == 'net472'">
<DebugType>full</DebugType>
</PropertyGroup>
<Import Project="Targets/PublishAllRids.targets" />
<Import Project="Targets/FixBindingRedirects.targets" />
<Import Project="Targets/MonoFacades.targets" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and !$(RuntimeIdentifier.StartsWith('win'))" />
<Import Project="Targets/CopyRuntimes.targets" />
</Project>

View File

@ -1,3 +0,0 @@
Copied from mono/4.5/Facades of the mono 5.4 release.
These are the mono version of the dotnet Core TypeForwardedTo assemblies.
Using these assemblies is no longer necessary once we reach mono 5.18 as minimum version

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NBuilder" Version="6.1.0" />

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.Support" Version="3.141.0" />

View File

@ -1,13 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Host\Radarr.Host.csproj" />
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />
<ProjectReference Include="..\NzbDrone.Test.Dummy\Radarr.Test.Dummy.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.ServiceProcess" />
</ItemGroup>
</Project>

View File

@ -1,17 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Messaging;
using TinyIoC;
#if NETCOREAPP
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Loader;
#endif
namespace NzbDrone.Common.Composition
{
public abstract class ContainerBuilderBase
@ -27,12 +24,6 @@ namespace NzbDrone.Common.Composition
assemblies.Add(OsInfo.IsWindows ? "Radarr.Windows" : "Radarr.Mono");
assemblies.Add("Radarr.Common");
#if !NETCOREAPP
foreach (var assembly in assemblies)
{
_loadedTypes.AddRange(Assembly.Load(assembly).GetExportedTypes());
}
#else
var startupPath = AppDomain.CurrentDomain.BaseDirectory;
foreach (var assemblyName in assemblies)
@ -44,14 +35,12 @@ namespace NzbDrone.Common.Composition
toRegisterResolver.AddRange(assemblies.Intersect(new[] { "Radarr.Core" }));
RegisterNativeResolver(toRegisterResolver);
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ContainerResolveEventHandler);
#endif
Container = new Container(new TinyIoCContainer(), _loadedTypes);
AutoRegisterInterfaces();
Container.Register(args);
}
#if NETCOREAPP
private static Assembly ContainerResolveEventHandler(object sender, ResolveEventArgs args)
{
var resolver = new AssemblyDependencyResolver(args.RequestingAssembly.Location);
@ -103,7 +92,6 @@ namespace NzbDrone.Common.Composition
return NativeLibrary.Load(mappedName, assembly, dllImportSearchPath);
}
#endif
private void AutoRegisterInterfaces()
{

View File

@ -26,21 +26,8 @@ namespace NzbDrone.Common.EnvironmentInfo
static PlatformInfo()
{
#if NETCOREAPP
_platform = PlatformType.NetCore;
_version = Environment.Version;
#else
if (Type.GetType("Mono.Runtime") != null)
{
_platform = PlatformType.Mono;
_version = GetMonoVersion();
}
else
{
_platform = PlatformType.DotNet;
_version = GetDotNetVersion();
}
#endif
}
public static PlatformType Platform => _platform;

View File

@ -23,7 +23,6 @@ namespace NzbDrone.Common.EnvironmentInfo
serviceProvider.ServiceExist(ServiceProvider.SERVICE_NAME) &&
serviceProvider.GetStatus(ServiceProvider.SERVICE_NAME) == ServiceControllerStatus.StartPending;
#if NETCOREAPP
// net5.0 will return Radarr.dll for entry assembly, we need the actual
// executable name (Radarr on linux). On mono this will return the location of
// the mono executable itself, which is not what we want.
@ -34,12 +33,6 @@ namespace NzbDrone.Common.EnvironmentInfo
ExecutingApplication = entry.FileName;
IsWindowsTray = OsInfo.IsWindows && entry.ModuleName == $"{ProcessProvider.RADARR_PROCESS_NAME}.exe";
}
#else
// On mono we need to get the location of the Radarr assembly, not Mono.
// Can't be running tray app in mono.
ExecutingApplication = Assembly.GetEntryAssembly()?.Location;
#endif
}
static RuntimeInfo()

View File

@ -1,12 +0,0 @@
using System;
namespace NzbDrone.Common.Expansive
{
public class CircularReferenceException : Exception
{
public CircularReferenceException(string message)
: base(message)
{
}
}
}

View File

@ -1,213 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Dynamic;
using System.Linq;
using System.Text.RegularExpressions;
namespace NzbDrone.Common.Expansive
{
public static class Expansive
{
private static PatternStyle _patternStyle;
public static bool RequireAllExpansions { get; set; }
public static Func<string, string> DefaultExpansionFactory { get; set; }
static Expansive()
{
Initialize();
}
public static string Expand(this string source)
{
return source.Expand(DefaultExpansionFactory);
}
public static string Expand(this string source, params string[] args)
{
var output = source;
var tokens = new List<string>();
var pattern = new Regex(_patternStyle.TokenMatchPattern, RegexOptions.IgnoreCase);
var calls = new Stack<string>();
string callingToken = null;
while (pattern.IsMatch(output))
{
foreach (Match match in pattern.Matches(output))
{
var token = _patternStyle.TokenReplaceFilter(match.Value);
var tokenIndex = 0;
if (!tokens.Contains(token))
{
tokens.Add(token);
tokenIndex = tokens.Count - 1;
}
else
{
tokenIndex = tokens.IndexOf(token);
}
output = Regex.Replace(output, _patternStyle.OutputFilter(match.Value), "{" + tokenIndex + "}");
}
}
var newArgs = new List<string>();
foreach (var arg in args)
{
var newArg = arg;
var tokenPattern = new Regex(_patternStyle.TokenFilter(string.Join("|", tokens)));
while (tokenPattern.IsMatch(newArg))
{
foreach (Match match in tokenPattern.Matches(newArg))
{
var token = _patternStyle.TokenReplaceFilter(match.Value);
if (calls.Contains(string.Format("{0}:{1}", callingToken, token)))
{
throw new CircularReferenceException(string.Format("Circular Reference Detected for token '{0}'.", callingToken));
}
calls.Push(string.Format("{0}:{1}", callingToken, token));
callingToken = token;
newArg = Regex.Replace(newArg, _patternStyle.OutputFilter(match.Value), args[tokens.IndexOf(token)]);
}
}
newArgs.Add(newArg);
}
return string.Format(output, newArgs.ToArray());
}
public static string Expand(this string source, Func<string, string> expansionFactory)
{
return source.ExpandInternal(expansionFactory);
}
public static string Expand(this string source, object model)
{
return source.ExpandInternal(
name =>
{
IDictionary<string, object> modelDict = model.ToDictionary();
if (RequireAllExpansions && !modelDict.ContainsKey(name))
{
return "";
}
if (modelDict[name] == null)
{
return "";
}
return modelDict[name].ToString();
});
}
private static void Initialize()
{
_patternStyle = new PatternStyle
{
TokenMatchPattern = @"\{[a-zA-Z]\w*\}",
TokenReplaceFilter = token => token.Replace("{", "").Replace("}", ""),
OutputFilter = output => (output.StartsWith("{") && output.EndsWith("}") ? output : @"\{" + output + @"\}"),
TokenFilter = tokens => "{(" + tokens + ")}"
};
}
private static string ExpandInternal(this string source, Func<string, string> expansionFactory)
{
if (expansionFactory == null)
{
throw new ApplicationException("ExpansionFactory not defined.\nDefine a DefaultExpansionFactory or call Expand(source, Func<string, string> expansionFactory))");
}
var pattern = new Regex(_patternStyle.TokenMatchPattern, RegexOptions.IgnoreCase);
var callTreeParent = new Tree<string>("root").Root;
return source.Explode(pattern, _patternStyle, expansionFactory, callTreeParent);
}
private static string Explode(this string source, Regex pattern, PatternStyle patternStyle, Func<string, string> expansionFactory, TreeNode<string> parent)
{
var output = source;
while (output.HasChildren(pattern))
{
foreach (Match match in pattern.Matches(source))
{
var child = match.Value;
var token = patternStyle.TokenReplaceFilter(match.Value);
var thisNode = parent.Children.Add(token);
// if we have already encountered this token in this call tree, we have a circular reference
if (thisNode.CallTree.Contains(token))
{
throw new CircularReferenceException(string.Format("Circular Reference Detected for token '{0}'. Call Tree: {1}->{2}",
token,
string.Join("->", thisNode.CallTree.ToArray().Reverse()),
token));
}
// expand this match
var expandedValue = expansionFactory(token);
// Replace the match with the expanded value
child = Regex.Replace(child, patternStyle.OutputFilter(match.Value), expandedValue);
// Recursively expand the child until we no longer encounter nested tokens (or hit a circular reference)
child = child.Explode(pattern, patternStyle, expansionFactory, thisNode);
// finally, replace the match in the output with the fully-expanded value
output = Regex.Replace(output, patternStyle.OutputFilter(match.Value), child);
}
}
return output;
}
private static bool HasChildren(this string token, Regex pattern)
{
return pattern.IsMatch(token);
}
/// <summary>
/// Turns the object into an ExpandoObject
/// </summary>
private static dynamic ToExpando(this object o)
{
var result = new ExpandoObject();
var d = result as IDictionary<string, object>; //work with the Expando as a Dictionary
if (o is ExpandoObject)
{
return o; //shouldn't have to... but just in case
}
if (o is NameValueCollection || o.GetType().IsSubclassOf(typeof(NameValueCollection)))
{
var nv = (NameValueCollection)o;
nv.Cast<string>().Select(key => new KeyValuePair<string, object>(key, nv[key])).ToList().ForEach(i => d.Add(i));
}
else
{
var props = o.GetType().GetProperties();
foreach (var item in props)
{
d.Add(item.Name, item.GetValue(o, null));
}
}
return result;
}
/// <summary>
/// Turns the object into a Dictionary
/// </summary>
private static IDictionary<string, object> ToDictionary(this object thingy)
{
return (IDictionary<string, object>)thingy.ToExpando();
}
}
}

View File

@ -1,12 +0,0 @@
using System;
namespace NzbDrone.Common.Expansive
{
internal class PatternStyle
{
public string TokenMatchPattern { get; set; }
public Func<string, string> TokenFilter { get; set; }
public Func<string, string> TokenReplaceFilter { get; set; }
public Func<string, string> OutputFilter { get; set; }
}
}

View File

@ -1,11 +0,0 @@
namespace NzbDrone.Common.Expansive
{
internal class Tree<T> : TreeNode<T>
{
public Tree(T rootValue)
: base(rootValue)
{
Value = rootValue;
}
}
}

View File

@ -1,90 +0,0 @@
using System.Collections.Generic;
namespace NzbDrone.Common.Expansive
{
internal class TreeNode<T>
{
private List<T> _CallTree;
private TreeNode<T> _Parent;
public TreeNode(T value)
{
Value = value;
Parent = null;
Children = new TreeNodeList<T>(this);
_CallTree = new List<T>();
}
public TreeNode(T value, TreeNode<T> parent)
{
Value = value;
Parent = parent;
Children = new TreeNodeList<T>(this);
_CallTree = new List<T>();
}
public TreeNode<T> Parent
{
get
{
return _Parent;
}
set
{
if (value == _Parent)
{
return;
}
if (_Parent != null)
{
_Parent.Children.Remove(this);
}
if (value != null && !value.Children.Contains(this))
{
value.Children.Add(this);
}
_Parent = value;
}
}
public TreeNode<T> Root
{
get
{
//return (Parent == null) ? this : Parent.Root;
TreeNode<T> node = this;
while (node.Parent != null)
{
node = node.Parent;
}
return node;
}
}
public TreeNodeList<T> Children { get; private set; }
public List<T> CallTree
{
get
{
_CallTree = new List<T>();
TreeNode<T> node = this;
while (node.Parent != null)
{
node = node.Parent;
_CallTree.Add(node.Value);
}
return _CallTree;
}
private set => _CallTree = value;
}
public T Value { get; set; }
}
}

View File

@ -1,31 +0,0 @@
using System.Collections.Generic;
namespace NzbDrone.Common.Expansive
{
internal class TreeNodeList<T> : List<TreeNode<T>>
{
public TreeNode<T> Parent;
public TreeNodeList(TreeNode<T> parent)
{
Parent = parent;
}
public new TreeNode<T> Add(TreeNode<T> node)
{
base.Add(node);
node.Parent = Parent;
return node;
}
public TreeNode<T> Add(T value)
{
return Add(new TreeNode<T>(value));
}
public override string ToString()
{
return "Count=" + Count.ToString();
}
}
}

View File

@ -1,2 +0,0 @@
Source: https://github.com/anderly/Expansive
Microsoft Public License (MS-PL): http://opensource.org/licenses/MS-PL

View File

@ -6,14 +6,6 @@ namespace NzbDrone.Common.Extensions
{
public static class DictionaryExtensions
{
#if !NETCOREAPP
public static TValue GetValueOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue = default(TValue))
{
TValue value;
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
}
#endif
public static Dictionary<T1, T2> Merge<T1, T2>(this Dictionary<T1, T2> first, Dictionary<T1, T2> second)
{
if (first == null)

View File

@ -33,19 +33,10 @@ namespace NzbDrone.Common.Http.Dispatchers
{
var webRequest = (HttpWebRequest)WebRequest.Create((Uri)request.Url);
if (PlatformInfo.IsMono)
{
// On Mono GZipStream/DeflateStream leaks memory if an exception is thrown, use an intermediate buffer in that case.
webRequest.AutomaticDecompression = DecompressionMethods.None;
webRequest.Headers.Add("Accept-Encoding", "gzip");
}
else
{
// Deflate is not a standard and could break depending on implementation.
// we should just stick with the more compatible Gzip
//http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net
webRequest.AutomaticDecompression = DecompressionMethods.GZip;
}
// Deflate is not a standard and could break depending on implementation.
// we should just stick with the more compatible Gzip
//http://stackoverflow.com/questions/8490718/how-to-decompress-stream-deflated-with-java-util-zip-deflater-in-net
webRequest.AutomaticDecompression = DecompressionMethods.GZip;
webRequest.Method = request.Method.ToString();
webRequest.UserAgent = _userAgentBuilder.GetUserAgent(request.UseSimplifiedUserAgent);
@ -86,9 +77,6 @@ namespace NzbDrone.Common.Http.Dispatchers
if (httpWebResponse == null)
{
// Workaround for mono not closing connections properly in certain situations.
AbortWebRequest(webRequest);
// The default messages for WebException on mono are pretty horrible.
if (e.Status == WebExceptionStatus.NameResolutionFailure)
{
@ -122,19 +110,6 @@ namespace NzbDrone.Common.Http.Dispatchers
try
{
data = responseStream.ToBytes();
if (PlatformInfo.IsMono && httpWebResponse.ContentEncoding == "gzip")
{
using (var compressedStream = new MemoryStream(data))
using (var gzip = new GZipStream(compressedStream, CompressionMode.Decompress))
using (var decompressedStream = new MemoryStream())
{
gzip.CopyTo(decompressedStream);
data = decompressedStream.ToArray();
}
httpWebResponse.Headers.Remove("Content-Encoding");
}
}
catch (Exception ex)
{
@ -244,36 +219,5 @@ namespace NzbDrone.Common.Http.Dispatchers
}
}
}
// Workaround for mono not closing connections properly on timeouts
private void AbortWebRequest(HttpWebRequest webRequest)
{
// First affected version was mono 5.16
if (OsInfo.IsNotWindows && _platformInfo.Version >= new Version(5, 16))
{
try
{
var currentOperationInfo = webRequest.GetType().GetField("currentOperation", BindingFlags.NonPublic | BindingFlags.Instance);
var currentOperation = currentOperationInfo.GetValue(webRequest);
if (currentOperation != null)
{
var responseStreamInfo = currentOperation.GetType().GetField("responseStream", BindingFlags.NonPublic | BindingFlags.Instance);
var responseStream = responseStreamInfo.GetValue(currentOperation) as Stream;
// Note that responseStream will likely be null once mono fixes it.
responseStream?.Dispose();
}
}
catch (Exception ex)
{
// This can fail randomly on future mono versions that have been changed/fixed. Log to sentry and ignore.
_logger.Trace()
.Exception(ex)
.Message("Unable to dispose responseStream on mono {0}", _platformInfo.Version)
.Write();
}
}
}
}
}

View File

@ -4,11 +4,7 @@
{
public static readonly HttpAccept Rss = new HttpAccept("application/rss+xml, text/rss+xml, application/xml, text/xml");
public static readonly HttpAccept Json = new HttpAccept("application/json");
#if NETCOREAPP
public static readonly HttpAccept JsonCharset = new HttpAccept("application/json; charset=utf-8");
#else
public static readonly HttpAccept JsonCharset = new HttpAccept("application/json;charset=utf-8");
#endif
public static readonly HttpAccept Html = new HttpAccept("text/html");
public string Value { get; private set; }

View File

@ -1,20 +0,0 @@
using System;
using System.Net;
namespace NzbDrone.Common.Http
{
public class NzbDroneWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
((HttpWebRequest)request).KeepAlive = false;
((HttpWebRequest)request).ServicePoint.Expect100Continue = false;
}
return request;
}
}
}

View File

@ -44,11 +44,7 @@ namespace NzbDrone.Common.Processes
public static int GetCurrentProcessId()
{
#if NETCOREAPP
return Environment.ProcessId;
#else
return Process.GetCurrentProcess().Id;
#endif
}
public ProcessInfo GetCurrentProcess()

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
<DefineConstants Condition="'$(RuntimeIdentifier)' == 'linux-musl-x64' or '$(RuntimeIdentifier)' == 'linux-musl-arm64'">ISMUSL</DefineConstants>
</PropertyGroup>
<ItemGroup>
@ -12,17 +12,12 @@
<PackageReference Include="System.Text.Json" Version="5.0.1" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.113.0-0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="5.0.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.ServiceProcess" />
</ItemGroup>
<ItemGroup>
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">
<DesignTime>True</DesignTime>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
<ApplicationIcon>..\NzbDrone.Host\Radarr.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>

View File

@ -1,63 +0,0 @@
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.HealthCheck.Checks;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
using static NzbDrone.Core.HealthCheck.Checks.MonoDebugCheck;
namespace NzbDrone.Core.Test.HealthCheck.Checks
{
[TestFixture]
public class MonoDebugFixture : CoreTest<MonoDebugCheck>
{
private void GivenHasStackFrame(bool hasStackFrame)
{
Mocker.GetMock<StackFrameHelper>()
.Setup(f => f.HasStackFrameInfo())
.Returns(hasStackFrame);
}
[Test]
public void should_return_ok_if_not_mono()
{
if (PlatformInfo.IsMono)
{
throw new IgnoreException("non mono specific test");
}
Subject.Check().ShouldBeOk();
}
[Test]
public void should_return_ok_if_not_debug()
{
MonoOnly();
GivenHasStackFrame(false);
Subject.Check().ShouldBeOk();
}
[Test]
public void should_log_warning_if_not_debug()
{
MonoOnly();
GivenHasStackFrame(false);
Subject.Check();
ExceptionVerification.ExpectedWarns(1);
}
[Test]
public void should_return_ok_if_debug()
{
MonoOnly();
GivenHasStackFrame(true);
Subject.Check().ShouldBeOk();
}
}
}

View File

@ -1,68 +0,0 @@
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Processes;
using NzbDrone.Core.HealthCheck.Checks;
using NzbDrone.Core.Localization;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.HealthCheck.Checks
{
[TestFixture]
public class MonoNotNetCoreCheckFixture : CoreTest<MonoNotNetCoreCheck>
{
[SetUp]
public void setup()
{
Mocker.GetMock<ILocalizationService>()
.Setup(s => s.GetLocalizedString(It.IsAny<string>()))
.Returns("Some Warning Message");
}
[Test]
[Platform(Exclude = "Mono")]
public void should_return_ok_if_net_core()
{
Subject.Check().ShouldBeOk();
}
[Test]
[Platform("Mono")]
public void should_log_error_if_mono()
{
Subject.Check().ShouldBeError();
}
[Test]
[Platform("Mono")]
public void should_return_error_if_otherbsd()
{
Mocker.GetMock<IProcessProvider>()
.Setup(x => x.StartAndCapture("uname", null, null))
.Returns(new ProcessOutput
{
Lines = new List<ProcessOutputLine>
{
new ProcessOutputLine(ProcessOutputLevel.Standard, "OpenBSD")
}
});
Subject.Check().ShouldBeError();
}
[Test]
[Platform("Mono")]
public void should_log_error_if_freebsd()
{
Mocker.GetMock<IProcessProvider>()
.Setup(x => x.StartAndCapture("uname", null, null))
.Returns(new ProcessOutput
{
Lines = new List<ProcessOutputLine>
{
new ProcessOutputLine(ProcessOutputLevel.Standard, "FreeBSD")
}
});
Subject.Check().ShouldBeError();
}
}
}

View File

@ -1,82 +0,0 @@
using System;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.HealthCheck.Checks;
using NzbDrone.Core.Localization;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.HealthCheck.Checks
{
[TestFixture]
public class MonoVersionCheckFixture : CoreTest<MonoVersionCheck>
{
[SetUp]
public void Setup()
{
Mocker.GetMock<ILocalizationService>()
.Setup(s => s.GetLocalizedString(It.IsAny<string>()))
.Returns("Some Warning Message");
}
private void GivenOutput(string version)
{
MonoOnly();
Mocker.GetMock<IPlatformInfo>()
.SetupGet(s => s.Version)
.Returns(new Version(version));
}
[TestCase("5.20")]
[TestCase("6.4")]
[TestCase("6.12")]
public void should_return_ok(string version)
{
GivenOutput(version);
Subject.Check().ShouldBeOk();
}
public void should_return_notice(string version)
{
GivenOutput(version);
Subject.Check().ShouldBeNotice();
}
public void should_return_warning(string version)
{
GivenOutput(version);
Subject.Check().ShouldBeWarning();
}
[TestCase("2.10.2")]
[TestCase("2.10.8.1")]
[TestCase("3.0.0.1")]
[TestCase("3.2.0.1")]
[TestCase("3.2.1")]
[TestCase("3.2.7")]
[TestCase("3.6.1")]
[TestCase("3.8")]
[TestCase("3.10")]
[TestCase("4.0.0.0")]
[TestCase("4.2")]
[TestCase("4.4.0")]
[TestCase("4.4.1")]
[TestCase("5.4")]
[TestCase("5.8")]
[TestCase("5.10")]
[TestCase("5.12")]
[TestCase("5.14")]
[TestCase("5.16")]
[TestCase("5.18")]
public void should_return_error(string version)
{
GivenOutput(version);
Subject.Check().ShouldBeError();
}
}
}

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.78" />

View File

@ -1,49 +0,0 @@
using System.Diagnostics;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Localization;
namespace NzbDrone.Core.HealthCheck.Checks
{
public class MonoDebugCheck : HealthCheckBase
{
private readonly Logger _logger;
private readonly StackFrameHelper _stackFrameHelper;
public override bool CheckOnSchedule => false;
public MonoDebugCheck(Logger logger, StackFrameHelper stackFrameHelper, ILocalizationService localizationService)
: base(localizationService)
{
_logger = logger;
_stackFrameHelper = stackFrameHelper;
}
public class StackFrameHelper
{
public virtual bool HasStackFrameInfo()
{
var stackTrace = new StackTrace(true);
return stackTrace.FrameCount > 0 && stackTrace.GetFrame(0).GetFileName().IsNotNullOrWhiteSpace();
}
}
public override HealthCheck Check()
{
if (!PlatformInfo.IsMono)
{
return new HealthCheck(GetType());
}
if (!_stackFrameHelper.HasStackFrameInfo())
{
_logger.Warn("Mono is not running with --debug switch");
return new HealthCheck(GetType());
}
return new HealthCheck(GetType());
}
}
}

View File

@ -1,49 +0,0 @@
using System.Linq;
using System.Runtime.InteropServices;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Processes;
using NzbDrone.Core.Localization;
namespace NzbDrone.Core.HealthCheck.Checks
{
public class MonoNotNetCoreCheck : HealthCheckBase
{
private static string[] MonoUnames = new string[] { "OpenBSD", "MidnightBSD", "NetBSD" };
private readonly IProcessProvider _processProvider;
public MonoNotNetCoreCheck(IProcessProvider processProvider,
ILocalizationService localizationService)
: base(localizationService)
{
_processProvider = processProvider;
}
public override HealthCheck Check()
{
if (!PlatformInfo.IsMono)
{
return new HealthCheck(GetType());
}
// Don't warn on linux x86 - we don't build x86 net core
if (OsInfo.IsLinux && RuntimeInformation.ProcessArchitecture == Architecture.X86)
{
return new HealthCheck(GetType(), HealthCheckResult.Error, _localizationService.GetLocalizedString("Monox86SupportCheckMessage"), "#mono-support-end-of-life");
}
// Check for BSD
var output = _processProvider.StartAndCapture("uname");
if (output?.ExitCode == 0 && MonoUnames.Contains(output?.Lines.First().Content))
{
return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format(_localizationService.GetLocalizedString("MonoBSDSupportCheckMessage"), OsInfo.Os), "#mono-support-end-of-life");
}
return new HealthCheck(GetType(),
HealthCheckResult.Error,
_localizationService.GetLocalizedString("MonoNotNetCoreCheckMessage"),
"#update-to-net-core-version");
}
public override bool CheckOnSchedule => false;
}
}

View File

@ -1,46 +0,0 @@
using System;
using NLog;
using NLog.Fluent;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Localization;
namespace NzbDrone.Core.HealthCheck.Checks
{
public class MonoTlsCheck : HealthCheckBase
{
private readonly IPlatformInfo _platformInfo;
private readonly Logger _logger;
public MonoTlsCheck(IPlatformInfo platformInfo, ILocalizationService localizationService, Logger logger)
: base(localizationService)
{
_platformInfo = platformInfo;
_logger = logger;
}
public override HealthCheck Check()
{
if (!PlatformInfo.IsMono)
{
return new HealthCheck(GetType());
}
var monoVersion = _platformInfo.Version;
if (monoVersion >= new Version("5.8.0") && Environment.GetEnvironmentVariable("MONO_TLS_PROVIDER") == "legacy")
{
_logger.Debug()
.Message("Mono version {0} and legacy TLS provider is selected, recommending user to switch to btls.", monoVersion)
.WriteSentryDebug("LegacyTlsProvider", monoVersion.ToString())
.Write();
return new HealthCheck(GetType(), HealthCheckResult.Warning, _localizationService.GetLocalizedString("MonoTlsCheckMessage"), "#mono-tls-legacy");
}
return new HealthCheck(GetType());
}
public override bool CheckOnSchedule => false;
}
}

View File

@ -1,66 +0,0 @@
using System;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Localization;
namespace NzbDrone.Core.HealthCheck.Checks
{
public class MonoVersionCheck : HealthCheckBase
{
private readonly IPlatformInfo _platformInfo;
private readonly Logger _logger;
public MonoVersionCheck(IPlatformInfo platformInfo, ILocalizationService localizationService, Logger logger)
: base(localizationService)
{
_platformInfo = platformInfo;
_logger = logger;
}
public override HealthCheck Check()
{
if (!PlatformInfo.IsMono)
{
return new HealthCheck(GetType());
}
var monoVersion = _platformInfo.Version;
// Currently best stable Mono version (5.18 gets us .net 4.7.2 support)
var bestVersion = new Version("5.20");
var targetVersion = new Version("5.20");
if (monoVersion >= targetVersion)
{
_logger.Debug("Mono version is {0} or better: {1}", targetVersion, monoVersion);
return new HealthCheck(GetType());
}
// Stable Mono versions
var stableVersion = new Version("5.20");
if (monoVersion >= stableVersion)
{
_logger.Debug("Mono version is {0} or better: {1}", stableVersion, monoVersion);
return new HealthCheck(GetType(),
HealthCheckResult.Notice,
string.Format(_localizationService.GetLocalizedString("MonoVersionCheckUpgradeRecommendedMessage"), monoVersion, bestVersion),
"#currently-installed-mono-version-is-supported-but-upgrading-is-recommended");
}
var oldVersion = new Version("5.20");
if (monoVersion >= oldVersion)
{
return new HealthCheck(GetType(),
HealthCheckResult.Error,
string.Format(_localizationService.GetLocalizedString("MonoVersionCheckUpgradeRecommendedMessage"), monoVersion, bestVersion),
"#currently-installed-mono-version-is-old-and-unsupported");
}
return new HealthCheck(GetType(),
HealthCheckResult.Error,
string.Format(_localizationService.GetLocalizedString("MonoVersionCheckUpgradeRecommendedMessage"), monoVersion, bestVersion),
"#currently-installed-mono-version-is-old-and-unsupported");
}
public override bool CheckOnSchedule => false;
}
}

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.78" />
@ -22,10 +22,6 @@
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common\Radarr.Common.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="..\..\Logo\64.png">
<Link>Resources\Logo\64.png</Link>

View File

@ -1,12 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Host\Radarr.Host.csproj" />
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.ServiceProcess" />
</ItemGroup>
</Project>

View File

@ -24,11 +24,7 @@ namespace Radarr.Host
try
{
Logger.Info("Starting Radarr - {0} - Version {1}",
#if NETCOREAPP
Process.GetCurrentProcess().MainModule.FileName,
#else
Assembly.GetCallingAssembly().Location,
#endif
Assembly.GetExecutingAssembly().GetName().Version);
if (!PlatformValidation.IsValidate(userAlert))

View File

@ -1,18 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="2.2.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="5.0.5" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="5.0.5" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.2" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
</ItemGroup>
@ -29,7 +21,4 @@
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.ServiceProcess" />
</ItemGroup>
</Project>

View File

@ -57,17 +57,10 @@ namespace Radarr.Host.Middleware
}
});
#if NETCOREAPP
appBuilder.UseEndpoints(x =>
{
x.MapHub<MessageHub>(URL_BASE + "/signalr/messages");
});
#else
appBuilder.UseSignalR(x =>
{
x.MapHub<MessageHub>("/signalr/messages");
});
#endif
// This is a side effect of haing multiple IoC containers, TinyIoC and whatever
// Kestrel/SignalR is using. Ideally we'd have one IoC container, but that's non-trivial with TinyIoC

View File

@ -108,24 +108,14 @@ namespace Radarr.Host
{
services
.AddSignalR()
#if !NETCOREAPP
.AddJsonProtocol(options =>
{
options.PayloadSerializerSettings = Json.GetSerializerSettings();
});
#else
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions = STJson.GetSerializerSettings();
});
#endif
})
.Configure(app =>
{
#if NETCOREAPP
app.UseRouting();
#endif
app.Properties["host.AppName"] = BuildInfo.AppName;
app.UsePathBase(_configFileProvider.UrlBase);

View File

@ -1,12 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="1.1.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.5" />
</ItemGroup>
<ItemGroup>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />

View File

@ -1,15 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="Mono.Posix-4.5" Version="4.5.0" PrivateAssets="all" />
</ItemGroup>
<!--
The netstandard veresion here doesn't work in net framework
See https://github.com/xamarin/XamarinComponents/issues/282
-->
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="5.20.1-servarr1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,15 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="Mono.Posix-4.5" Version="4.5.0" PrivateAssets="all" />
</ItemGroup>
<!--
The netstandard veresion here doesn't work in net framework
See https://github.com/xamarin/XamarinComponents/issues/282
-->
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<ItemGroup>
<PackageReference Include="Mono.Posix.NETStandard" Version="5.20.1-servarr1" />
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
</ItemGroup>

View File

@ -1,12 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Core\Radarr.Core.csproj" />
<ProjectReference Include="..\NzbDrone.Common\Radarr.Common.csproj" />

View File

@ -7,11 +7,7 @@ namespace NzbDrone.SignalR
public object Body { get; set; }
public string Name { get; set; }
#if !NETCOREAPP
[Newtonsoft.Json.JsonIgnore]
#else
[System.Text.Json.Serialization.JsonIgnore]
#endif
public ModelAction Action { get; set; }
}
}

View File

@ -152,9 +152,7 @@ namespace NzbDrone.Test.Common.AutoMoq
_registeredMocks = new Dictionary<Type, object>();
AddTheAutoMockingContainerExtensionToTheContainer(container);
#if NETCOREAPP
ContainerBuilderBase.RegisterNativeResolver(new[] { "System.Data.SQLite", "Radarr.Core" });
#endif
}
private static void AddTheAutoMockingContainerExtensionToTheContainer(IUnityContainer container)

View File

@ -55,8 +55,7 @@ namespace NzbDrone.Test.Common
if (BuildInfo.IsDebug)
{
var frameworkFolder = PlatformInfo.IsNetCore ? "net5.0" : "net472";
Start(Path.Combine(TestContext.CurrentContext.TestDirectory, "..", "..", "_output", frameworkFolder, consoleExe));
Start(Path.Combine(TestContext.CurrentContext.TestDirectory, "..", "..", "_output", "net5.0", consoleExe));
}
else
{

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
</Project>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="4.7.0" />

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Common.Test\Radarr.Common.Test.csproj" />

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NLog" Version="4.7.0" />

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net5.0-windows;net472</TargetFrameworks>
<TargetFrameworks>net5.0-windows</TargetFrameworks>
<RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>..\NzbDrone.Host\Radarr.ico</ApplicationIcon>
@ -14,9 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Host\Radarr.Host.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="8.6.2" />

View File

@ -1,54 +0,0 @@
using System;
using System.Linq;
using System.Reflection;
using NzbDrone.Common.Reflection;
using Radarr.Http.REST;
namespace Radarr.Http.Mapping
{
public static class MappingValidation
{
public static void ValidateMapping(Type modelType, Type resourceType)
{
var errors = modelType.GetSimpleProperties().Where(c => !c.GetGetMethod().IsStatic).Select(p => GetError(resourceType, p)).Where(c => c != null).ToList();
if (errors.Any())
{
throw new ResourceMappingException(errors);
}
PrintExtraProperties(modelType, resourceType);
}
private static void PrintExtraProperties(Type modelType, Type resourceType)
{
var resourceBaseProperties = typeof(RestResource).GetProperties().Select(c => c.Name);
var resourceProperties = resourceType.GetProperties().Select(c => c.Name).Except(resourceBaseProperties);
var modelProperties = modelType.GetProperties().Select(c => c.Name);
var extra = resourceProperties.Except(modelProperties);
foreach (var extraProp in extra)
{
Console.WriteLine("Extra: [{0}]", extraProp);
}
}
private static string GetError(Type resourceType, PropertyInfo modelProperty)
{
var resourceProperty = resourceType.GetProperties().FirstOrDefault(c => c.Name == modelProperty.Name);
if (resourceProperty == null)
{
return string.Format("public {0} {1} {{ get; set; }}", modelProperty.PropertyType.Name, modelProperty.Name);
}
if (resourceProperty.PropertyType != modelProperty.PropertyType && !typeof(RestResource).IsAssignableFrom(resourceProperty.PropertyType))
{
return string.Format("Expected {0}.{1} to have type of {2} but found {3}", resourceType.Name, resourceProperty.Name, modelProperty.PropertyType, resourceProperty.PropertyType);
}
return null;
}
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Radarr.Http.Mapping
{
public class ResourceMappingException : ApplicationException
{
public ResourceMappingException(IEnumerable<string> error)
: base(Environment.NewLine + string.Join(Environment.NewLine, error.OrderBy(c => c)))
{
}
}
}

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="8.6.2" />

View File

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<ItemGroup>
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
</ItemGroup>
</Project>

View File

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net5.0;net472</TargetFrameworks>
<TargetFrameworks>net5.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net5.0'">
<ItemGroup>
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
</ItemGroup>
</Project>

View File

@ -1,17 +0,0 @@
<Project>
<Target Name="FixBindingRedirects"
AfterTargets="ResolveAssemblyReferences"
BeforeTargets="GenerateBindingRedirects">
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(RuntimeIdentifier)' == 'linux-x64'">
<SuggestedBindingRedirects Remove="System.Net.Http, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and $(RuntimeIdentifier.StartsWith('win'))">
<SuggestedBindingRedirects Remove="System.Runtime.InteropServices.RuntimeInformation, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</ItemGroup>
</Target>
</Project>

View File

@ -1,52 +0,0 @@
<Project>
<!--
When compiling without mono, but targeting mono we need to replace some assemblies with facades to make it run on mono.
This MonoFacades.targets file should only be included if not targeting windows and targeting net4x.
Warning: We ONLY support facades that reside directly in MonoFacadesPath, otherwise the joining of items becomes complicated.
Any MonoFacade listed that doesn't exist on disk will be removed instead of replaced.
See: https://github.com/mono/mono/blob/master/tools/nuget-hash-extractor/download.sh
That list defines assemblies that are prohibited from being loaded from the appdir, instead loading from mono GAC.
-->
<PropertyGroup>
<MonoFacadesPath>$(MSBuildThisFileDirectory)..\Libraries\Mono\</MonoFacadesPath>
<ResolveReferencesDependsOn>
$(ResolveReferencesDependsOn);
SubstituteMonoFacadesBuild
</ResolveReferencesDependsOn>
</PropertyGroup>
<ItemGroup>
<MonoFacade Include="$(MonoFacadesPath)*.dll" />
<MonoFacade Include="System.IO.Compression.dll" />
<MonoFacade Include="System.Net.Http.dll" />
<!-- List of MonoFacade by FileName -->
<MonoFacade_Facade Include="@(MonoFacade->'%(Filename)%(Extension)')" />
</ItemGroup>
<Target Name="SubstituteMonoFacadesBuild"
AfterTargets="ResolveAssemblyReferences"
BeforeTargets="GenerateBindingRedirects">
<ItemGroup>
<!-- List of ReferenceCopyLocalPaths by FileName and filter out those without Facades -->
<MonoFacade_Resolved Include="@(ReferenceCopyLocalPaths->'%(Filename)%(Extension)')">
<OriginalIdentity>%(ReferenceCopyLocalPaths.Identity)</OriginalIdentity>
<MonoFacadeIdentity>$(MonoFacadesPath)%(Filename)%(Extension)</MonoFacadeIdentity>
</MonoFacade_Resolved>
<MonoFacade_Unrelated Include="@(MonoFacade_Resolved)" />
<MonoFacade_Unrelated Remove="@(MonoFacade_Facade)" />
<MonoFacade_Resolved Remove="@(MonoFacade_Unrelated)" />
<!-- Modify the actual copy list -->
<ReferenceCopyLocalPaths Remove="@(MonoFacade_Resolved->'%(OriginalIdentity)')" />
<ReferenceCopyLocalPaths Include="@(MonoFacade_Resolved->'%(MonoFacadeIdentity)')" Condition="Exists('%(MonoFacade_Resolved.MonoFacadeIdentity)')" />
</ItemGroup>
</Target>
</Project>

View File

@ -21,8 +21,6 @@
<Framework>%(Framework)</Framework>
</Renamed>
<Renamed Remove="$(ExcludedRuntimeFrameworkPairs)" />
<!-- Transform RuntimeIdentifierForPublish items to project items to pass to MSBuild task -->
<ProjectToPublish Include="@(Renamed->'$(MSBuildProjectFullPath)')">
<AdditionalProperties>RuntimeIdentifier=%(Renamed.Runtime);TargetFramework=%(Renamed.Framework)</AdditionalProperties>