Merge pull request #42 from jellyfin/fix-build

This commit is contained in:
Cody Robibero 2021-11-19 07:22:47 -07:00 committed by GitHub
commit 20c78b2e7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 138 additions and 70 deletions

View File

@ -17,8 +17,6 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
private const string StandardOpfFile = "content.opf";
private const string CalibreOpfFile = "metadata.opf";
private const string DcNamespace = @"http://purl.org/dc/elements/1.1/";
private const string OpfNamespace = @"http://www.idpf.org/2007/opf";
private readonly IFileSystem _fileSystem;
private readonly ILogger<BookProviderFromOpf> _logger;
@ -94,7 +92,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
var doc = new XmlDocument();
doc.Load(metaFile);
OpfReader.ReadOpfData(bookResult, doc, cancellationToken, _logger);
OpfReader.ReadOpfData(bookResult, doc, _logger, cancellationToken);
}
}
}

View File

@ -37,17 +37,17 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
public string Name => "Comic Book Zip Archive Cover Extractor";
/// <inheritdoc />
public async Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
public Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
{
// Check if the file is a .cbz file
var extension = Path.GetExtension(item.Path);
if (string.Equals(extension, CbzFileExtension, StringComparison.OrdinalIgnoreCase))
{
return await LoadCover(item);
return LoadCover(item);
}
else
{
return new DynamicImageResponse { HasImage = false };
return Task.FromResult(new DynamicImageResponse { HasImage = false });
}
}
@ -82,7 +82,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
var (cover, imageFormat) = FindCoverEntryInZip(archive) ?? throw new InvalidOperationException("No supported cover found");
// Copy our cover to memory stream
await cover.Open().CopyToAsync(memoryStream);
await cover.Open().CopyToAsync(memoryStream).ConfigureAwait(false);
// Reset stream position after copying
memoryStream.Position = 0;
@ -117,7 +117,10 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
// There are comics with a cover file, but others with varying names for the cover
// e.g. attackontitan_vol1_Page_001 with no indication that this is the cover except
// that it is the first jpeg entry (and page)
var cover = archive.GetEntry("cover" + extension) ?? archive.Entries.OrderBy(x => x.Name).FirstOrDefault(x => x.Name.EndsWith(extension));
var cover = archive.GetEntry("cover" + extension)
?? archive.Entries
.OrderBy(x => x.Name)
.FirstOrDefault(x => x.Name.EndsWith(extension, StringComparison.OrdinalIgnoreCase));
// If we have found something, return immediately
if (cover is not null)

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
@ -90,13 +91,13 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
/// Gets or sets the list of credits.
/// </summary>
[JsonPropertyName("credits")]
public ComicBookInfoCredit[] Credits { get; set; } = Array.Empty<ComicBookInfoCredit>();
public IReadOnlyList<ComicBookInfoCredit> Credits { get; set; } = Array.Empty<ComicBookInfoCredit>();
/// <summary>
/// Gets or sets the list of tags.
/// </summary>
[JsonPropertyName("tags")]
public string[] Tags { get; set; } = Array.Empty<string>();
public IReadOnlyList<string> Tags { get; set; } = Array.Empty<string>();
/// <summary>
/// Gets or sets the comments.

View File

@ -48,7 +48,9 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
try
{
#pragma warning disable CA2007
await using Stream stream = File.OpenRead(path);
#pragma warning restore CA2007
// not yet async: https://github.com/adamhathcock/sharpcompress/pull/565
using var archive = ZipArchive.Open(stream);
@ -58,8 +60,12 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
var volume = archive.Volumes.First();
if (volume.Comment is not null)
{
#pragma warning disable CA2007
await using var jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(volume.Comment));
var comicBookMetadata = await JsonSerializer.DeserializeAsync<ComicBookInfoFormat>(jsonStream, JsonDefaults.Options, cancellationToken);
#pragma warning restore CA2007
var comicBookMetadata = await JsonSerializer.DeserializeAsync<ComicBookInfoFormat>(jsonStream, JsonDefaults.Options, cancellationToken)
.ConfigureAwait(false);
if (comicBookMetadata is null)
{
@ -120,7 +126,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
metadataResult.ResultLanguage = ReadCultureInfoAsThreeLetterIsoInto(comic.Metadata.Language);
}
if (comic.Metadata.Credits.Length > 0)
if (comic.Metadata.Credits.Count > 0)
{
foreach (var person in comic.Metadata.Credits)
{
@ -151,25 +157,25 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicBookInfo
if (comic.PublicationYear is not null)
{
book.ProductionYear = comic.PublicationYear;
hasFoundMetadata |= true;
hasFoundMetadata = true;
}
if (comic.Issue is not null)
{
book.IndexNumber = comic.Issue;
hasFoundMetadata |= true;
hasFoundMetadata = true;
}
if (comic.Tags is not null && comic.Tags.Length > 0)
if (comic.Tags.Count > 0)
{
book.Tags = comic.Tags;
hasFoundMetadata |= true;
book.Tags = comic.Tags.ToArray();
hasFoundMetadata = true;
}
if (comic.PublicationYear is not null && comic.PublicationMonth is not null)
{
book.PremiereDate = ReadTwoPartDateInto(comic.PublicationYear.Value, comic.PublicationMonth.Value);
hasFoundMetadata |= true;
hasFoundMetadata = true;
}
if (hasFoundMetadata)

View File

@ -30,7 +30,8 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
{
foreach (IComicFileProvider iComicFileProvider in _comicFileProviders)
{
var metadata = await iComicFileProvider.ReadMetadata(info, directoryService, cancellationToken);
var metadata = await iComicFileProvider.ReadMetadata(info, directoryService, cancellationToken)
.ConfigureAwait(false);
if (metadata.HasMetadata)
{
@ -41,7 +42,8 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
return new MetadataResult<Book> { HasMetadata = false };
}
bool IHasItemChangeMonitor.HasChanged(BaseItem item, IDirectoryService directoryService)
/// <inheritdoc />
public bool HasChanged(BaseItem item, IDirectoryService directoryService)
{
foreach (IComicFileProvider iComicFileProvider in _comicFileProviders)
{

View File

@ -37,7 +37,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicInfo
/// <inheritdoc />
public async ValueTask<MetadataResult<Book>> ReadMetadata(ItemInfo info, IDirectoryService directoryService, CancellationToken cancellationToken)
{
var comicInfoXml = await LoadXml(info, directoryService, cancellationToken);
var comicInfoXml = await LoadXml(info, directoryService, cancellationToken).ConfigureAwait(false);
if (comicInfoXml is null)
{
@ -88,7 +88,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicInfo
var comicInfoXml = XDocument.LoadAsync(reader, LoadOptions.None, cancellationToken);
// Read data from XML
return await comicInfoXml;
return await comicInfoXml.ConfigureAwait(false);
}
catch (Exception e)
{

View File

@ -33,7 +33,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicInfo
/// <inheritdoc />
public async ValueTask<MetadataResult<Book>> ReadMetadata(ItemInfo info, IDirectoryService directoryService, CancellationToken cancellationToken)
{
var comicInfoXml = await LoadXml(info, directoryService, cancellationToken);
var comicInfoXml = await LoadXml(info, directoryService, cancellationToken).ConfigureAwait(false);
if (comicInfoXml is null)
{
@ -96,11 +96,14 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.ComicInfo
}
// Open the xml
#pragma warning disable CA2007
await using var containerStream = container.Open();
#pragma warning restore CA2007
var comicInfoXml = XDocument.LoadAsync(containerStream, LoadOptions.None, cancellationToken);
// Read data from XML
return await comicInfoXml;
return await comicInfoXml.ConfigureAwait(false);
}
catch (Exception e)
{

View File

@ -129,12 +129,12 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.Epub
return null;
}
private Task<DynamicImageResponse> LoadCover(ZipArchive epub, XmlDocument opf, string opfRootDirectory)
private async Task<DynamicImageResponse> LoadCover(ZipArchive epub, XmlDocument opf, string opfRootDirectory)
{
var coverRef = ReadCoverPath(opf, opfRootDirectory);
if (coverRef == null)
{
return Task.FromResult(new DynamicImageResponse { HasImage = false });
return new DynamicImageResponse { HasImage = false };
}
var cover = coverRef.Value;
@ -142,13 +142,14 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.Epub
var coverFile = epub.GetEntry(cover.Path);
if (coverFile == null)
{
return Task.FromResult(new DynamicImageResponse { HasImage = false });
return new DynamicImageResponse { HasImage = false };
}
var memoryStream = new MemoryStream();
using (var coverStream = coverFile.Open())
{
coverStream.CopyTo(memoryStream);
await coverStream.CopyToAsync(memoryStream)
.ConfigureAwait(false);
}
memoryStream.Position = 0;
@ -160,7 +161,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.Epub
};
response.SetFormatFromMimeType(cover.MimeType);
return Task.FromResult(response);
return response;
}
private Task<DynamicImageResponse> GetFromZip(BaseItem item)

View File

@ -95,7 +95,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.Epub
var opfDocument = new XmlDocument();
opfDocument.Load(opfStream);
OpfReader.ReadOpfData(result, opfDocument, cancellationToken, _logger);
OpfReader.ReadOpfData(result, opfDocument, _logger, cancellationToken);
}
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
@ -57,7 +58,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
return list;
}
var bookResult = await FetchBookData(googleBookId, cancellationToken);
var bookResult = await FetchBookData(googleBookId, cancellationToken).ConfigureAwait(false);
if (bookResult == null)
{
@ -77,12 +78,16 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
{
cancellationToken.ThrowIfCancellationRequested();
var url = string.Format(GoogleApiUrls.DetailsUrl, googleBookId);
var url = string.Format(CultureInfo.InvariantCulture, GoogleApiUrls.DetailsUrl, googleBookId);
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
using var response = await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false);
#pragma warning disable CA2007
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
#pragma warning restore CA2007
return await JsonSerializer.DeserializeAsync<BookResult>(stream, JsonDefaults.Options, cancellationToken).ConfigureAwait(false);
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
@ -73,12 +74,12 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
public string Name => "Google Books";
/// <inheritdoc />
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(BookInfo item, CancellationToken cancellationToken)
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(BookInfo searchInfo, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var list = new List<RemoteSearchResult>();
var searchResults = await GetSearchResultsInternal(item, cancellationToken);
var searchResults = await GetSearchResultsInternal(searchInfo, cancellationToken).ConfigureAwait(false);
if (searchResults is null)
{
return Enumerable.Empty<RemoteSearchResult>();
@ -105,21 +106,21 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
}
/// <inheritdoc />
public async Task<MetadataResult<Book>> GetMetadata(BookInfo item, CancellationToken cancellationToken)
public async Task<MetadataResult<Book>> GetMetadata(BookInfo info, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var metadataResult = new MetadataResult<Book>();
metadataResult.HasMetadata = false;
var googleBookId = item.GetProviderId("GoogleBooks")
?? await FetchBookId(item, cancellationToken).ConfigureAwait(false);
var googleBookId = info.GetProviderId("GoogleBooks")
?? await FetchBookId(info, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(googleBookId))
{
return metadataResult;
}
var bookResult = await FetchBookData(googleBookId, cancellationToken);
var bookResult = await FetchBookData(googleBookId, cancellationToken).ConfigureAwait(false);
if (bookResult == null)
{
@ -153,12 +154,16 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
// year can be included for better results
GetBookMetadata(item);
var url = string.Format(GoogleApiUrls.SearchUrl, WebUtility.UrlEncode(item.Name), 0, 20);
var url = string.Format(CultureInfo.InvariantCulture, GoogleApiUrls.SearchUrl, WebUtility.UrlEncode(item.Name), 0, 20);
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
using var response = await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false);
#pragma warning disable CA2007
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
#pragma warning restore CA2007
return await JsonSerializer.DeserializeAsync<SearchResult>(stream, JsonDefaults.Options, cancellationToken).ConfigureAwait(false);
}
@ -166,7 +171,8 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
{
cancellationToken.ThrowIfCancellationRequested();
var searchResults = await GetSearchResultsInternal(item, cancellationToken);
var searchResults = await GetSearchResultsInternal(item, cancellationToken)
.ConfigureAwait(false);
if (searchResults?.Items == null)
{
return null;
@ -181,7 +187,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
}
// no match so move on to the next item
if (!GetComparableName(i.VolumeInfo.Title).Equals(comparableName))
if (!GetComparableName(i.VolumeInfo.Title).Equals(comparableName, StringComparison.Ordinal))
{
continue;
}
@ -209,12 +215,16 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
{
cancellationToken.ThrowIfCancellationRequested();
var url = string.Format(GoogleApiUrls.DetailsUrl, googleBookId);
var url = string.Format(CultureInfo.InvariantCulture, GoogleApiUrls.DetailsUrl, googleBookId);
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
using var response = await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false);
#pragma warning disable CA2007
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
#pragma warning restore CA2007
return await JsonSerializer.DeserializeAsync<BookResult>(stream, JsonDefaults.Options, cancellationToken).ConfigureAwait(false);
}
@ -233,8 +243,8 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
try
{
book.ProductionYear = bookResult.VolumeInfo.PublishedDate?.Length > 4
? Convert.ToInt32(bookResult.VolumeInfo.PublishedDate[..4])
: Convert.ToInt32(bookResult.VolumeInfo.PublishedDate);
? Convert.ToInt32(bookResult.VolumeInfo.PublishedDate[..4], CultureInfo.InvariantCulture)
: Convert.ToInt32(bookResult.VolumeInfo.PublishedDate, CultureInfo.InvariantCulture);
}
catch (Exception)
{
@ -252,7 +262,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
tags.Add(bookResult.VolumeInfo.MainCategory);
}
if (bookResult.VolumeInfo.Categories is { Length: > 0 })
if (bookResult.VolumeInfo.Categories is { Count: > 0 })
{
foreach (var category in bookResult.VolumeInfo.Categories)
{
@ -284,12 +294,12 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
return string.Empty;
}
name = name.ToLower();
name = name.ToLower(CultureInfo.InvariantCulture);
name = name.Normalize(NormalizationForm.FormKD);
foreach (var pair in _replaceEndNumerals)
{
if (name.EndsWith(pair.Key))
if (name.EndsWith(pair.Key, StringComparison.OrdinalIgnoreCase))
{
name = name.Remove(name.IndexOf(pair.Key, StringComparison.InvariantCulture), pair.Key.Length);
name += pair.Value;
@ -303,13 +313,13 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
{
// skip char modifier and diacritics
}
else if (Remove.IndexOf(c) > -1)
else if (Remove.IndexOf(c, StringComparison.Ordinal) > -1)
{
// skip chars we are removing
}
else if (Spacers.IndexOf(c) > -1)
else if (Spacers.IndexOf(c, StringComparison.Ordinal) > -1)
{
sb.Append(" ");
sb.Append(' ');
}
else if (c == '&')
{
@ -322,8 +332,8 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
}
name = sb.ToString();
name = name.Replace("the", " ");
name = name.Replace(" - ", ": ");
name = name.Replace("the", " ", StringComparison.OrdinalIgnoreCase);
name = name.Replace(" - ", ": ", StringComparison.Ordinal);
var regex = new Regex(@"\s+");
name = regex.Replace(name, " ");

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
@ -24,6 +25,6 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
/// Gets or sets the list of items.
/// </summary>
[JsonPropertyName("items")]
public BookResult[] Items { get; set; } = Array.Empty<BookResult>();
public IReadOnlyList<BookResult> Items { get; set; } = Array.Empty<BookResult>();
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
@ -18,7 +19,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
/// Gets or sets the list of authors.
/// </summary>
[JsonPropertyName("authors")]
public string[] Authors { get; set; } = Array.Empty<string>();
public IReadOnlyList<string> Authors { get; set; } = Array.Empty<string>();
/// <summary>
/// Gets or sets the published date.
@ -54,7 +55,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers.GoogleBooks
/// Gets or sets the list of categories.
/// </summary>
[JsonPropertyName("categories")]
public string[] Categories { get; set; } = Array.Empty<string>();
public IReadOnlyList<string> Categories { get; set; } = Array.Empty<string>();
/// <summary>
/// Gets or sets the average rating.

View File

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Xml;
@ -22,14 +23,14 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
/// </summary>
/// <param name="bookResult">The metadata result to update.</param>
/// <param name="doc">The xdocument to parse.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="logger">Instance of the <see cref="ILogger{TCategoryName}"/> interface.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <typeparam name="TCategoryName">The type of category.</typeparam>
public static void ReadOpfData<TCategoryName>(
MetadataResult<Book> bookResult,
XmlDocument doc,
CancellationToken cancellationToken,
ILogger<TCategoryName> logger)
ILogger<TCategoryName> logger,
CancellationToken cancellationToken)
{
var book = bookResult.Item;
@ -100,7 +101,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
{
try
{
book.IndexNumber = Convert.ToInt32(seriesIndexNode.Attributes["content"]?.Value);
book.IndexNumber = Convert.ToInt32(seriesIndexNode.Attributes["content"]?.Value, CultureInfo.InvariantCulture);
}
catch (Exception)
{
@ -128,7 +129,7 @@ namespace Jellyfin.Plugin.Bookshelf.Providers
{
try
{
book.CommunityRating = Convert.ToInt32(ratingNode.Attributes["content"]?.Value);
book.CommunityRating = Convert.ToInt32(ratingNode.Attributes["content"]?.Value, CultureInfo.InvariantCulture);
}
catch (Exception)
{

View File

@ -1,13 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Rules for Jellyfin" Description="Code analysis rules for Jellyfin" ToolsVersion="14.0">
<RuleSet Name="Rules for Jellyfin.Server" Description="Code analysis rules for Jellyfin.Server.csproj" ToolsVersion="14.0">
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
<Rule Id="SA1202" Action="Info" />
<!-- disable warning SA1204: Static members must appear before non-static members -->
<Rule Id="SA1204" Action="Info" />
<!-- disable warning SA1404: Code analysis suppression should have justification -->
<Rule Id="SA1404" Action="Info" />
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
<Rule Id="SA1009" Action="None" />
<!-- disable warning SA1011: Closing square bracket should be followed by a space. -->
@ -16,12 +9,18 @@
<Rule Id="SA1101" Action="None" />
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
<Rule Id="SA1108" Action="None" />
<!-- disable warning SA1118: Parameter must not span multiple lines. -->
<Rule Id="SA1118" Action="None" />
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
<Rule Id="SA1128" Action="None" />
<!-- disable warning SA1130: Use lambda syntax -->
<Rule Id="SA1130" Action="None" />
<!-- disable warning SA1200: 'using' directive must appear within a namespace declaration -->
<Rule Id="SA1200" Action="None" />
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
<Rule Id="SA1202" Action="None" />
<!-- disable warning SA1204: Static members must appear before non-static members -->
<Rule Id="SA1204" Action="None" />
<!-- disable warning SA1309: Fields must not begin with an underscore -->
<Rule Id="SA1309" Action="None" />
<!-- disable warning SA1413: Use trailing comma in multi-line initializers -->
@ -39,20 +38,51 @@
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.Design">
<!-- error on CA1063: Implement IDisposable correctly -->
<Rule Id="CA1063" Action="Error" />
<!-- error on CA1305: Specify IFormatProvider -->
<Rule Id="CA1305" Action="Error" />
<!-- error on CA1307: Specify StringComparison for clarity -->
<Rule Id="CA1307" Action="Error" />
<!-- error on CA1309: Use ordinal StringComparison -->
<Rule Id="CA1309" Action="Error" />
<!-- error on CA1725: Parameter names should match base declaration -->
<Rule Id="CA1725" Action="Error" />
<!-- error on CA1725: Call async methods when in an async method -->
<Rule Id="CA1727" Action="Error" />
<!-- error on CA1813: Avoid unsealed attributes -->
<Rule Id="CA1813" Action="Error" />
<!-- error on CA1843: Do not use 'WaitAll' with a single task -->
<Rule Id="CA1843" Action="Error" />
<!-- error on CA1845: Use span-based 'string.Concat' -->
<Rule Id="CA1845" Action="Error" />
<!-- error on CA2016: Forward the CancellationToken parameter to methods that take one
or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token -->
<Rule Id="CA2016" Action="Error" />
<!-- error on CA2254: Template should be a static expression -->
<Rule Id="CA2254" Action="Error" />
<!-- disable warning CA1014: Mark assemblies with CLSCompliantAttribute -->
<Rule Id="CA1014" Action="Info" />
<!-- disable warning CA1024: Use properties where appropriate -->
<Rule Id="CA1024" Action="Info" />
<!-- disable warning CA1031: Do not catch general exception types -->
<Rule Id="CA1031" Action="Info" />
<!-- disable warning CA1032: Implement standard exception constructors -->
<Rule Id="CA1032" Action="Info" />
<!-- disable warning CA1040: Avoid empty interfaces -->
<Rule Id="CA1040" Action="Info" />
<!-- disable warning CA1062: Validate arguments of public methods -->
<Rule Id="CA1062" Action="Info" />
<!-- TODO: enable when false positives are fixed -->
<!-- disable warning CA1508: Avoid dead conditional code -->
<Rule Id="CA1508" Action="Info" />
<!-- disable warning CA1716: Identifiers should not match keywords -->
<Rule Id="CA1716" Action="Info" />
<!-- disable warning CA1720: Identifiers should not contain type names -->
<Rule Id="CA1720" Action="Info" />
<!-- disable warning CA1724: Type names should not match namespaces -->
<Rule Id="CA1724" Action="Info" />
<!-- disable warning CA1805: Do not initialize unnecessarily -->
<Rule Id="CA1805" Action="Info" />
<!-- disable warning CA1812: internal class that is apparently never instantiated.
@ -63,11 +93,11 @@
<Rule Id="CA1822" Action="Info" />
<!-- disable warning CA2000: Dispose objects before losing scope -->
<Rule Id="CA2000" Action="Info" />
<!-- disable warning CA2253: Named placeholders should not be numeric values -->
<Rule Id="CA2253" Action="Info" />
<!-- disable warning CA5394: Do not use insecure randomness -->
<Rule Id="CA5394" Action="Info" />
<!-- disable warning CA1014: Mark assemblies with CLSCompliantAttribute -->
<Rule Id="CA1014" Action="Info" />
<!-- disable warning CA1054: Change the type of parameter url from string to System.Uri -->
<Rule Id="CA1054" Action="None" />
<!-- disable warning CA1055: URI return values should not be strings -->
@ -78,5 +108,11 @@
<Rule Id="CA1303" Action="None" />
<!-- disable warning CA1308: Normalize strings to uppercase -->
<Rule Id="CA1308" Action="None" />
<!-- disable warning CA1848: Use the LoggerMessage delegates -->
<Rule Id="CA1848" Action="None" />
<!-- disable warning CA2101: Specify marshaling for P/Invoke string arguments -->
<Rule Id="CA2101" Action="None" />
<!-- disable warning CA2234: Pass System.Uri objects instead of strings -->
<Rule Id="CA2234" Action="None" />
</Rules>
</RuleSet>