Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable .NET source code analysis #784

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,6 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true

# .NET source code analysis
dotnet_code_quality.CA1826.exclude_ordefault_methods = true
2 changes: 1 addition & 1 deletion src/BaGet.Azure/Search/AzureSearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ private string BuildSeachQuery(string query, string packageType, string framewor
return queryBuilder.ToString();
}

private string BuildSearchFilter(bool includePrerelease, bool includeSemVer2)
private static string BuildSearchFilter(bool includePrerelease, bool includeSemVer2)
{
var searchFilters = SearchFilters.Default;

Expand Down
2 changes: 2 additions & 0 deletions src/BaGet.Azure/Search/ExactMatchCustomAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Azure.Search.Models;

namespace BaGet.Azure
Expand All @@ -10,6 +11,7 @@ public static class ExactMatchCustomAnalyzer
{
public const string Name = "baget-exact-match-analyzer";

[SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "Would be a breaking change")]
public static CustomAnalyzer Instance = new CustomAnalyzer(
Name,
TokenizerName.Keyword,
Expand Down
4 changes: 2 additions & 2 deletions src/BaGet.Azure/Search/IndexActionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class IndexActionBuilder
return AddOrUpdatePackage(registration, isUpdate: true);
}

private IReadOnlyList<IndexAction<KeyedDocument>> AddOrUpdatePackage(
private static IReadOnlyList<IndexAction<KeyedDocument>> AddOrUpdatePackage(
PackageRegistration registration,
bool isUpdate)
{
Expand Down Expand Up @@ -105,7 +105,7 @@ public class IndexActionBuilder
return result;
}

private string EncodePackageId(string key)
private static string EncodePackageId(string key)
{
// Keys can only contain letters, digits, underscore(_), dash(-), or equal sign(=).
// TODO: Align with NuGet.org's algorithm.
Expand Down
2 changes: 2 additions & 0 deletions src/BaGet.Azure/Table/TableOperationBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using BaGet.Core;
using Microsoft.Azure.Cosmos.Table;
Expand All @@ -8,6 +9,7 @@

namespace BaGet.Azure
{
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Would be a breaking change since it's part of the public API")]
public class TableOperationBuilder
{
public TableOperation AddPackage(Package package)
Expand Down
6 changes: 3 additions & 3 deletions src/BaGet.Azure/Table/TablePackageDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ public async Task<PackageAddResult> AddAsync(Package package, CancellationToken
attempt++;
_logger.LogWarning(
e,
$"Retrying due to precondition failure, attempt {{Attempt}} of {MaxPreconditionFailures}..",
attempt);
"Retrying due to precondition failure, attempt {Attempt} of {MaxPreconditionFailures}",
attempt, MaxPreconditionFailures);
}
}
}
Expand Down Expand Up @@ -196,7 +196,7 @@ public async Task<bool> UnlistPackageAsync(string id, NuGetVersion version, Canc
cancellationToken);
}

private List<string> MinimalColumnSet => new List<string> { "PartitionKey" };
private static List<string> MinimalColumnSet => new List<string> { "PartitionKey" };

private async Task<bool> TryUpdatePackageAsync(TableOperation operation, CancellationToken cancellationToken)
{
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Azure/Table/TableSearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public Task<DependentsResponse> FindDependentsAsync(string packageId, Cancellati
return results;
}

private string GenerateSearchFilter(string searchText, bool includePrerelease, bool includeSemVer2)
private static string GenerateSearchFilter(string searchText, bool includePrerelease, bool includeSemVer2)
{
var result = "";

Expand Down
4 changes: 2 additions & 2 deletions src/BaGet.Core/Extensions/PackageArchiveReaderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ private static Uri ParseUri(string uriString)

private static string[] ParseAuthors(string authors)
{
if (string.IsNullOrEmpty(authors)) return new string[0];
if (string.IsNullOrEmpty(authors)) return Array.Empty<string>();

return authors.Split(new[] { ',', ';', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
}

private static string[] ParseTags(string tags)
{
if (string.IsNullOrEmpty(tags)) return new string[0];
if (string.IsNullOrEmpty(tags)) return Array.Empty<string>();

return tags.Split(new[] { ',', ';', ' ', '\t', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
}
Expand Down
4 changes: 2 additions & 2 deletions src/BaGet.Core/Indexing/SymbolIndexingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ bool IsValidSymbolFileInfo(FileInfo file)
return entries.Select(e => new FileInfo(e)).All(IsValidSymbolFileInfo);
}

private async Task<PortablePdb> ExtractPortablePdbAsync(
private static async Task<PortablePdb> ExtractPortablePdbAsync(
PackageArchiveReader symbolPackage,
string pdbPath,
CancellationToken cancellationToken)
Expand All @@ -147,7 +147,7 @@ bool IsValidSymbolFileInfo(FileInfo file)
{
using (var rawPdbStream = await symbolPackage.GetStreamAsync(pdbPath, cancellationToken))
{
pdbStream = await rawPdbStream.AsTemporaryFileStreamAsync();
pdbStream = await rawPdbStream.AsTemporaryFileStreamAsync(cancellationToken);

string signature;
using (var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(pdbStream, MetadataStreamOptions.LeaveOpen))
Expand Down
4 changes: 2 additions & 2 deletions src/BaGet.Core/Metadata/RegistrationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public virtual BaGetRegistrationIndexResponse BuildIndex(PackageRegistration reg
new BaGetRegistrationIndexPage
{
RegistrationPageUrl = _url.GetRegistrationIndexUrl(registration.PackageId),
Count = registration.Packages.Count(),
Count = registration.Packages.Count,
Lower = sortedPackages.First().Version.ToNormalizedString().ToLowerInvariant(),
Upper = sortedPackages.Last().Version.ToNormalizedString().ToLowerInvariant(),
ItemsOrNull = sortedPackages.Select(ToRegistrationIndexPageItem).ToList(),
Expand Down Expand Up @@ -92,7 +92,7 @@ public virtual RegistrationLeafResponse BuildLeaf(Package package)
},
};

private IReadOnlyList<DependencyGroupItem> ToDependencyGroups(Package package)
private static IReadOnlyList<DependencyGroupItem> ToDependencyGroups(Package package)
{
return package.Dependencies
.GroupBy(d => d.TargetFramework)
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Core/PackageDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public async Task<bool> HardDeletePackageAsync(string id, NuGetVersion version,
var package = await _context.Packages
.Where(p => p.Id == id)
.Where(p => p.NormalizedVersionString == version.ToNormalizedString())
.FirstOrDefaultAsync();
.FirstOrDefaultAsync(cancellationToken);

if (package != null)
{
Expand Down
4 changes: 2 additions & 2 deletions src/BaGet.Core/Search/DatabaseSearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public async Task<DependentsResponse> FindDependentsAsync(string packageId, Canc
return _searchBuilder.BuildDependents(dependents);
}

private IQueryable<Package> ApplySearchQuery(IQueryable<Package> query, string search)
private static IQueryable<Package> ApplySearchQuery(IQueryable<Package> query, string search)
{
if (string.IsNullOrEmpty(search))
{
Expand All @@ -157,7 +157,7 @@ private IQueryable<Package> ApplySearchQuery(IQueryable<Package> query, string s
return query.Where(p => p.Id.ToLower().Contains(search));
}

private IQueryable<Package> ApplySearchFilters(
private static IQueryable<Package> ApplySearchFilters(
IQueryable<Package> query,
bool includePrerelease,
bool includeSemVer2,
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Core/ServiceIndex/BaGetServiceIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public BaGetServiceIndex(IUrlGenerator url)
_url = url ?? throw new ArgumentNullException(nameof(url));
}

private IEnumerable<ServiceIndexItem> BuildResource(string name, string url, params string[] versions)
private static IEnumerable<ServiceIndexItem> BuildResource(string name, string url, params string[] versions)
{
foreach (var version in versions)
{
Expand Down
8 changes: 4 additions & 4 deletions src/BaGet.Core/Storage/SymbolStorageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,20 @@ public async Task<Stream> GetPortablePdbContentStreamOrNullAsync(string filename
}
}

private string GetPathForKey(string filename, string key)
private static string GetPathForKey(string filename, string key)
{
// Ensure the filename doesn't try to escape out of the current directory.
var tempPath = Path.GetDirectoryName(Path.GetTempPath());
var expandedPath = Path.GetDirectoryName(Path.Combine(tempPath, filename));

if (expandedPath != tempPath)
{
throw new ArgumentException(nameof(filename));
throw new ArgumentException($"Invalid file name: \"{filename}\" (can't escape the current directory)", nameof(filename));
}

if (!key.All(char.IsLetterOrDigit))
{
throw new ArgumentException(nameof(key));
throw new ArgumentException($"Invalid key: \"{key}\" (must contain exclusively letters and digits)", nameof(key));
}

// The key's first 32 characters are the GUID, the remaining characters are the age.
Expand Down
8 changes: 6 additions & 2 deletions src/BaGet.Core/Upstream/Clients/V2UpstreamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,11 @@ public async Task<IReadOnlyList<NuGetVersion>> ListPackageVersionsAsync(string i
}
}

public void Dispose() => _cache.Dispose();
public void Dispose()
{
_cache.Dispose();
GC.SuppressFinalize(this);
}

private Package ToPackage(IPackageSearchMetadata package)
{
Expand Down Expand Up @@ -157,7 +161,7 @@ private Package ToPackage(IPackageSearchMetadata package)
};
}

private string[] ParseAuthors(string authors)
private static string[] ParseAuthors(string authors)
{
if (string.IsNullOrEmpty(authors)) return Array.Empty<string>();

Expand Down
4 changes: 2 additions & 2 deletions src/BaGet.Core/Upstream/Clients/V3UpstreamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private Package ToPackage(PackageMetadata metadata)
};
}

private Uri ParseUri(string uriString)
private static Uri ParseUri(string uriString)
{
if (uriString == null) return null;

Expand All @@ -129,7 +129,7 @@ private Uri ParseUri(string uriString)
return uri;
}

private string[] ParseAuthors(string authors)
private static string[] ParseAuthors(string authors)
{
if (string.IsNullOrEmpty(authors)) return Array.Empty<string>();

Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Core/Upstream/DownloadsImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class DownloadsImporter
public async Task ImportAsync(CancellationToken cancellationToken)
{
var packageDownloads = await _downloadsSource.GetPackageDownloadsAsync();
var packages = await _context.Packages.CountAsync();
var packages = await _context.Packages.CountAsync(cancellationToken);
var batches = (packages / BatchSize) + 1;

for (var batch = 0; batch < batches; batch++)
Expand Down
6 changes: 3 additions & 3 deletions src/BaGet.Protocol/Catalog/CatalogProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private async Task<bool> ProcessIndexAsync(DateTimeOffset minCommitTimestamp, Ca

if (newCursor.HasValue && success)
{
await _cursor.SetAsync(newCursor.Value);
await _cursor.SetAsync(newCursor.Value, cancellationToken);
}

return success;
Expand All @@ -146,12 +146,12 @@ private async Task<bool> ProcessLeafAsync(CatalogLeafItem leafItem, Cancellation
{
if (leafItem.IsPackageDelete())
{
var packageDelete = await _client.GetPackageDeleteLeafAsync(leafItem.CatalogLeafUrl);
var packageDelete = await _client.GetPackageDeleteLeafAsync(leafItem.CatalogLeafUrl, cancellationToken);
success = await _leafProcessor.ProcessPackageDeleteAsync(packageDelete, cancellationToken);
}
else if (leafItem.IsPackageDetails())
{
var packageDetails = await _client.GetPackageDetailsLeafAsync(leafItem.CatalogLeafUrl);
var packageDetails = await _client.GetPackageDetailsLeafAsync(leafItem.CatalogLeafUrl, cancellationToken);
success = await _leafProcessor.ProcessPackageDetailsAsync(packageDetails, cancellationToken);
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/BaGet.Protocol/Search/SearchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public SearchClient(NuGetClientFactory clientFactory)
// See: https://github.com/loic-sharma/BaGet/issues/314
var client = await _clientfactory.GetSearchClientAsync(cancellationToken);

return await client.SearchAsync(query, skip, take, includePrerelease, includeSemVer2);
return await client.SearchAsync(query, skip, take, includePrerelease, includeSemVer2, cancellationToken);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/BaGet.Web/BaGetEndpointBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System.Diagnostics.CodeAnalysis;
using BaGet.Web;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints;

namespace BaGet
{
[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Would be a breaking change since it's part of the public API")]
public class BaGetEndpointBuilder
{
public void MapEndpoints(IEndpointRouteBuilder endpoints)
Expand Down
6 changes: 3 additions & 3 deletions src/BaGet.Web/Pages/Package.cshtml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public async Task OnGetAsync(string id, string version, CancellationToken cancel
PackageDownloadUrl = _url.GetPackageDownloadUrl(Package.Id, packageVersion);
}

private IReadOnlyList<DependencyGroupModel> ToDependencyGroups(Package package)
private static IReadOnlyList<DependencyGroupModel> ToDependencyGroups(Package package)
{
return package
.Dependencies
Expand All @@ -135,7 +135,7 @@ private IReadOnlyList<DependencyGroupModel> ToDependencyGroups(Package package)
.ToList();
}

private string PrettifyTargetFramework(string targetFramework)
private static string PrettifyTargetFramework(string targetFramework)
{
if (targetFramework == null) return "All Frameworks";

Expand Down Expand Up @@ -179,7 +179,7 @@ private string PrettifyTargetFramework(string targetFramework)
return $"{frameworkName} {frameworkVersion}";
}

private IReadOnlyList<VersionModel> ToVersions(IReadOnlyList<Package> packages, NuGetVersion selectedVersion)
private static IReadOnlyList<VersionModel> ToVersions(IReadOnlyList<Package> packages, NuGetVersion selectedVersion)
{
return packages
.Select(p => new VersionModel
Expand Down
6 changes: 6 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

<!-- .NET source code analysis https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview -->
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest-Minimum</AnalysisLevel>
</PropertyGroup>

<!-- Debugging properties -->
<PropertyGroup>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
Expand Down