Merge pull request #1942 from Bond-009/nullable

Enable nullable reference types for Jellyfin.Server
This commit is contained in:
Vasily 2019-11-27 11:48:41 +03:00 committed by GitHub
commit c45d54efb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 17 deletions

View File

@ -10,6 +10,7 @@
<PropertyGroup> <PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
@ -21,6 +22,7 @@ using MediaBrowser.Model.Globalization;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Serilog; using Serilog;
using Serilog.Extensions.Logging; using Serilog.Extensions.Logging;
using SQLitePCL; using SQLitePCL;
@ -35,7 +37,7 @@ namespace Jellyfin.Server
{ {
private static readonly CancellationTokenSource _tokenSource = new CancellationTokenSource(); private static readonly CancellationTokenSource _tokenSource = new CancellationTokenSource();
private static readonly ILoggerFactory _loggerFactory = new SerilogLoggerFactory(); private static readonly ILoggerFactory _loggerFactory = new SerilogLoggerFactory();
private static ILogger _logger; private static ILogger _logger = NullLogger.Instance;
private static bool _restartOnShutdown; private static bool _restartOnShutdown;
/// <summary> /// <summary>
@ -86,6 +88,12 @@ namespace Jellyfin.Server
{ {
var stopWatch = new Stopwatch(); var stopWatch = new Stopwatch();
stopWatch.Start(); stopWatch.Start();
// Log all uncaught exceptions to std error
static void UnhandledExceptionToConsole(object sender, UnhandledExceptionEventArgs e) =>
Console.Error.WriteLine("Unhandled Exception\n" + e.ExceptionObject.ToString());
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionToConsole;
ServerApplicationPaths appPaths = CreateApplicationPaths(options); ServerApplicationPaths appPaths = CreateApplicationPaths(options);
// $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
@ -97,6 +105,8 @@ namespace Jellyfin.Server
_logger = _loggerFactory.CreateLogger("Main"); _logger = _loggerFactory.CreateLogger("Main");
// Log uncaught exceptions to the logging instead of std error
AppDomain.CurrentDomain.UnhandledException -= UnhandledExceptionToConsole;
AppDomain.CurrentDomain.UnhandledException += (sender, e) AppDomain.CurrentDomain.UnhandledException += (sender, e)
=> _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception"); => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception");
@ -129,7 +139,7 @@ namespace Jellyfin.Server
_logger.LogInformation( _logger.LogInformation(
"Jellyfin version: {Version}", "Jellyfin version: {Version}",
Assembly.GetEntryAssembly().GetName().Version.ToString(3)); Assembly.GetEntryAssembly()!.GetName().Version!.ToString(3));
ApplicationHost.LogEnvironmentInfo(_logger, appPaths); ApplicationHost.LogEnvironmentInfo(_logger, appPaths);
@ -354,16 +364,25 @@ namespace Jellyfin.Server
private static async Task<IConfiguration> CreateConfiguration(IApplicationPaths appPaths) private static async Task<IConfiguration> CreateConfiguration(IApplicationPaths appPaths)
{ {
const string ResourcePath = "Jellyfin.Server.Resources.Configuration.logging.json";
string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json"); string configPath = Path.Combine(appPaths.ConfigurationDirectoryPath, "logging.json");
if (!File.Exists(configPath)) if (!File.Exists(configPath))
{ {
// For some reason the csproj name is used instead of the assembly name // For some reason the csproj name is used instead of the assembly name
using (Stream rscstr = typeof(Program).Assembly using (Stream? resource = typeof(Program).Assembly.GetManifestResourceStream(ResourcePath))
.GetManifestResourceStream("Jellyfin.Server.Resources.Configuration.logging.json"))
using (Stream fstr = File.Open(configPath, FileMode.CreateNew))
{ {
await rscstr.CopyToAsync(fstr).ConfigureAwait(false); if (resource == null)
{
throw new InvalidOperationException(
string.Format(
CultureInfo.InvariantCulture,
"Invalid resource path: '{0}'",
ResourcePath));
}
using Stream dst = File.Open(configPath, FileMode.CreateNew);
await resource.CopyToAsync(dst).ConfigureAwait(false);
} }
} }
@ -426,7 +445,7 @@ namespace Jellyfin.Server
{ {
_logger.LogInformation("Starting new instance"); _logger.LogInformation("Starting new instance");
string module = options.RestartPath; var module = options.RestartPath;
if (string.IsNullOrWhiteSpace(module)) if (string.IsNullOrWhiteSpace(module))
{ {
@ -434,7 +453,6 @@ namespace Jellyfin.Server
} }
string commandLineArgsString; string commandLineArgsString;
if (options.RestartArgs != null) if (options.RestartArgs != null)
{ {
commandLineArgsString = options.RestartArgs ?? string.Empty; commandLineArgsString = options.RestartArgs ?? string.Empty;

View File

@ -13,39 +13,39 @@ namespace Jellyfin.Server
/// </summary> /// </summary>
/// <value>The path to the data directory.</value> /// <value>The path to the data directory.</value>
[Option('d', "datadir", Required = false, HelpText = "Path to use for the data folder (database files, etc.).")] [Option('d', "datadir", Required = false, HelpText = "Path to use for the data folder (database files, etc.).")]
public string DataDir { get; set; } public string? DataDir { get; set; }
/// <summary> /// <summary>
/// Gets or sets the path to the web directory. /// Gets or sets the path to the web directory.
/// </summary> /// </summary>
/// <value>The path to the web directory.</value> /// <value>The path to the web directory.</value>
[Option('w', "webdir", Required = false, HelpText = "Path to the Jellyfin web UI resources.")] [Option('w', "webdir", Required = false, HelpText = "Path to the Jellyfin web UI resources.")]
public string WebDir { get; set; } public string? WebDir { get; set; }
/// <summary> /// <summary>
/// Gets or sets the path to the cache directory. /// Gets or sets the path to the cache directory.
/// </summary> /// </summary>
/// <value>The path to the cache directory.</value> /// <value>The path to the cache directory.</value>
[Option('C', "cachedir", Required = false, HelpText = "Path to use for caching.")] [Option('C', "cachedir", Required = false, HelpText = "Path to use for caching.")]
public string CacheDir { get; set; } public string? CacheDir { get; set; }
/// <summary> /// <summary>
/// Gets or sets the path to the config directory. /// Gets or sets the path to the config directory.
/// </summary> /// </summary>
/// <value>The path to the config directory.</value> /// <value>The path to the config directory.</value>
[Option('c', "configdir", Required = false, HelpText = "Path to use for configuration data (user settings and pictures).")] [Option('c', "configdir", Required = false, HelpText = "Path to use for configuration data (user settings and pictures).")]
public string ConfigDir { get; set; } public string? ConfigDir { get; set; }
/// <summary> /// <summary>
/// Gets or sets the path to the log directory. /// Gets or sets the path to the log directory.
/// </summary> /// </summary>
/// <value>The path to the log directory.</value> /// <value>The path to the log directory.</value>
[Option('l', "logdir", Required = false, HelpText = "Path to use for writing log files.")] [Option('l', "logdir", Required = false, HelpText = "Path to use for writing log files.")]
public string LogDir { get; set; } public string? LogDir { get; set; }
/// <inheritdoc /> /// <inheritdoc />
[Option("ffmpeg", Required = false, HelpText = "Path to external FFmpeg executable to use in place of default found in PATH.")] [Option("ffmpeg", Required = false, HelpText = "Path to external FFmpeg executable to use in place of default found in PATH.")]
public string FFmpegPath { get; set; } public string? FFmpegPath { get; set; }
/// <inheritdoc /> /// <inheritdoc />
[Option("service", Required = false, HelpText = "Run as headless service.")] [Option("service", Required = false, HelpText = "Run as headless service.")]
@ -57,14 +57,14 @@ namespace Jellyfin.Server
/// <inheritdoc /> /// <inheritdoc />
[Option("package-name", Required = false, HelpText = "Used when packaging Jellyfin (example, synology).")] [Option("package-name", Required = false, HelpText = "Used when packaging Jellyfin (example, synology).")]
public string PackageName { get; set; } public string? PackageName { get; set; }
/// <inheritdoc /> /// <inheritdoc />
[Option("restartpath", Required = false, HelpText = "Path to restart script.")] [Option("restartpath", Required = false, HelpText = "Path to restart script.")]
public string RestartPath { get; set; } public string? RestartPath { get; set; }
/// <inheritdoc /> /// <inheritdoc />
[Option("restartargs", Required = false, HelpText = "Arguments for restart script.")] [Option("restartargs", Required = false, HelpText = "Arguments for restart script.")]
public string RestartArgs { get; set; } public string? RestartArgs { get; set; }
} }
} }

View File

@ -6,6 +6,8 @@
<!-- disable warning SA1204: Static members must appear before non-static members --> <!-- disable warning SA1204: Static members must appear before non-static members -->
<Rule Id="SA1204" Action="Info" /> <Rule Id="SA1204" Action="Info" />
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
<Rule Id="SA1009" Action="None" />
<!-- disable warning SA1101: Prefix local calls with 'this.' --> <!-- disable warning SA1101: Prefix local calls with 'this.' -->
<Rule Id="SA1101" Action="None" /> <Rule Id="SA1101" Action="None" />
<!-- disable warning SA1108: Block statements should not contain embedded comments --> <!-- disable warning SA1108: Block statements should not contain embedded comments -->