Skip to content

Merge master (v5.0.3) into openapi branch #1186

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

Merged
merged 20 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
770b848
Enable running code cleanup locally only on files changed since the s…
bkoelman Jul 31, 2022
02d19b5
Adapts marking many-to-many relationships as tracked so it no longer …
bkoelman Aug 3, 2022
6825c83
Added test for removing from many-to-many relationship with composite…
bkoelman Aug 6, 2022
0fe0c59
Use C# 10, which enables static lambdas to guard against accidentally…
bkoelman Aug 7, 2022
549586b
Write "auto-generated" header comment, to prevent 3rd party analyzers…
bkoelman Aug 9, 2022
826f290
Minor fixes
bkoelman Jul 17, 2022
9634009
Reduce duplication in JSON:API type hierarchy by using JsonPropertyOr…
bkoelman Jul 17, 2022
792ab16
Tweak benchmarks
bkoelman Aug 21, 2022
a00ab50
Use System.Text.Json source generator (see https://devblogs.microsoft…
bkoelman Jul 18, 2022
f760e8f
Revert "Use System.Text.Json source generator (see https://devblogs.m…
bkoelman Aug 21, 2022
3069341
Merge pull request #1170 from json-api-dotnet/json-sourcegen
maurei Sep 6, 2022
aedb164
Package updates
bkoelman Sep 3, 2022
206ca38
Merge pull request #1173 from json-api-dotnet/cleanupcode-diff
maurei Sep 6, 2022
eed2ab1
Merge pull request #1176 from json-api-dotnet/replace-ef-26779-switch
maurei Sep 6, 2022
ca14796
Merge pull request #1178 from json-api-dotnet/source-generator-tweaks
maurei Sep 7, 2022
98c90ad
Merge pull request #1183 from json-api-dotnet/package-updates
maurei Sep 7, 2022
e4020c6
Increment version number (used for pre-release builds from ci)
bkoelman Sep 7, 2022
4c36105
Merge branch 'master' into merge-master-v503-into-openapi
bkoelman Sep 7, 2022
0413d6d
Fix build warning: duplicate package reference
bkoelman Sep 7, 2022
47320f0
Package updates, centralize versions, address breaking changes
bkoelman Sep 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
]
},
"regitlint": {
"version": "6.0.8",
"version": "6.1.1",
"commands": [
"regitlint"
]
Expand Down
4 changes: 2 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ Please follow these steps to have your contribution considered by the maintainer

We use [CSharpGuidelines](https://csharpcodingguidelines.com/) as our coding standard (with a few minor exceptions). Coding style is validated during PR build, where we inject an extra settings layer that promotes various suggestions to warning level. This ensures a high-quality codebase without interfering too much when editing code.
You can run the following [PowerShell scripts](https://github.com/PowerShell/PowerShell/releases) locally:
- `pwsh inspectcode.ps1`: Scans the code for style violations and opens the result in your web browser.
- `pwsh cleanupcode.ps1`: Reformats the entire codebase to match with our configured style.
- `pwsh ./inspectcode.ps1`: Scans the code for style violations and opens the result in your web browser.
- `pwsh ./cleanupcode.ps1 [branch-name-or-commit-hash]`: Reformats the codebase to match with our configured style, optionally only changed files since the specified branch (usually master).

Code inspection violations can be addressed in several ways, depending on the situation:
- Types that are reported to be never instantiated (because the IoC container creates them dynamically) should be decorated with `[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]`.
Expand Down
17 changes: 11 additions & 6 deletions Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,21 @@ function RunCleanupCode {
# When running in cibuild for a pull request, this reformats only the files changed in the PR and fails if the reformat produces changes.

if ($env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT) {
Write-Output "Running code cleanup on changed files in pull request"

# In the past, we used $env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT for the merge commit hash. That is the pinned hash at the time the build is enqueued.
# When a force-push happens after that, while the build hasn't yet started, this hash becomes invalid during the build, resulting in a lookup error.
# To prevent failing the build for unobvious reasons we use HEAD, which is always the latest version.
$mergeCommitHash = git rev-parse "HEAD"
$targetCommitHash = git rev-parse "$env:APPVEYOR_REPO_BRANCH"
# To prevent failing the build for unobvious reasons we use HEAD, which is always a detached head (the PR merge result).

$headCommitHash = git rev-parse HEAD
CheckLastExitCode

dotnet regitlint -s JsonApiDotNetCore.sln --print-command --disable-jb-path-hack --jb --profile='\"JADNC Full Cleanup\"' --jb --properties:Configuration=Release --jb --verbosity=WARN -f commits -a $mergeCommitHash -b $targetCommitHash --fail-on-diff --print-diff
$baseCommitHash = git rev-parse "$env:APPVEYOR_REPO_BRANCH"
CheckLastExitCode

if ($baseCommitHash -ne $headCommitHash) {
Write-Output "Running code cleanup on commit range $baseCommitHash..$headCommitHash in pull request."
dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f commits -a $headCommitHash -b $baseCommitHash --fail-on-diff --print-diff
CheckLastExitCode
}
}
}

Expand Down
15 changes: 9 additions & 6 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
<AspNetVersion>6.0.*</AspNetVersion>
<EFCoreVersion>6.0.*</EFCoreVersion>
<EFCorePostgresVersion>6.0.*</EFCorePostgresVersion>
<MicrosoftCodeAnalysisVersion>4.2.*</MicrosoftCodeAnalysisVersion>
<MicrosoftCodeAnalysisVersion>4.3.*</MicrosoftCodeAnalysisVersion>
<HumanizerVersion>2.14.1</HumanizerVersion>
<SwashbuckleVersion>6.2.*</SwashbuckleVersion>
<JsonApiDotNetCoreVersionPrefix>5.0.3</JsonApiDotNetCoreVersionPrefix>
<SwashbuckleVersion>6.4.*</SwashbuckleVersion>
<NSwagApiClientVersion>13.16.*</NSwagApiClientVersion>
<MicrosoftApiClientVersion>6.0.*</MicrosoftApiClientVersion>
<NewtonsoftJsonVersion>13.0.*</NewtonsoftJsonVersion>
<JsonApiDotNetCoreVersionPrefix>5.0.4</JsonApiDotNetCoreVersionPrefix>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodingGuidelines.ruleset</CodeAnalysisRuleSet>
<WarningLevel>9999</WarningLevel>
<Nullable>enable</Nullable>
Expand All @@ -18,7 +21,7 @@

<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.1.0" PrivateAssets="All" />
<PackageReference Include="CSharpGuidelinesAnalyzer" Version="3.8.1" PrivateAssets="All" />
<PackageReference Include="CSharpGuidelinesAnalyzer" Version="3.8.2" PrivateAssets="All" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CSharpGuidelinesAnalyzer.config" Visible="False" />
</ItemGroup>

Expand All @@ -35,7 +38,7 @@
<!-- Test Project Dependencies -->
<PropertyGroup>
<CoverletVersion>3.1.2</CoverletVersion>
<MoqVersion>4.18.1</MoqVersion>
<TestSdkVersion>17.2.0</TestSdkVersion>
<MoqVersion>4.18.2</MoqVersion>
<TestSdkVersion>17.3.1</TestSdkVersion>
</PropertyGroup>
</Project>
1 change: 1 addition & 0 deletions JsonApiDotNetCore.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$, $NAME$);</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceUsingStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EnforceWhileStatementBraces/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=EventNeverSubscribedTo_002ELocal/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LambdaExpressionMustBeStatic/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LocalizableElement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBePartlyConvertedToQuery/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeInternal/@EntryIndexedValue">SUGGESTION</s:String>
Expand Down
7 changes: 5 additions & 2 deletions benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>$(TargetFrameworkName)</TargetFramework>
<ServerGarbageCollection>true</ServerGarbageCollection>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\src\JsonApiDotNetCore\JsonApiDotNetCore.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="Moq" Version="$(MoqVersion)" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisVersion)" PrivateAssets="all">
<!-- This reference solely exists to prevent build warnings for conflicting versions of Microsoft.CodeAnalysis. -->
</PackageReference>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Benchmarks.Deserialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class OperationsDeserializationBenchmarks : DeserializationBenchmarkBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
namespace Benchmarks.Deserialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class ResourceDeserializationBenchmarks : DeserializationBenchmarkBase
{
Expand Down
31 changes: 4 additions & 27 deletions benchmarks/QueryString/QueryStringParserBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System.ComponentModel.Design;
using BenchmarkDotNet.Attributes;
using Benchmarks.Tools;
using JsonApiDotNetCore;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.QueryStrings;
using JsonApiDotNetCore.QueryStrings.Internal;
using JsonApiDotNetCore.Resources;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging.Abstractions;

namespace Benchmarks.QueryString;
Expand Down Expand Up @@ -71,31 +70,9 @@ public void DescendingSort()
[Benchmark]
public void ComplexQuery()
{
Run(100, () =>
{
const string queryString =
"?filter[alt-attr-name]=abc,eq:abc&sort=-alt-attr-name&include=child&page[size]=1&fields[alt-resource-name]=alt-attr-name";

_queryStringAccessor.SetQueryString(queryString);
_queryStringReader.ReadAll(null);
});
}

private void Run(int iterations, Action action)
{
for (int index = 0; index < iterations; index++)
{
action();
}
}

private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor
{
public IQueryCollection Query { get; private set; } = new QueryCollection();
const string queryString = "?filter[alt-attr-name]=abc,eq:abc&sort=-alt-attr-name&include=child&page[size]=1&fields[alt-resource-name]=alt-attr-name";

public void SetQueryString(string queryString)
{
Query = new QueryCollection(QueryHelpers.ParseQuery(queryString));
}
_queryStringAccessor.SetQueryString(queryString);
_queryStringReader.ReadAll(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Benchmarks.Serialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class OperationsSerializationBenchmarks : SerializationBenchmarkBase
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Benchmarks.Serialization;

[MarkdownExporter]
[MemoryDiagnoser]
// ReSharper disable once ClassCanBeSealed.Global
public class ResourceSerializationBenchmarks : SerializationBenchmarkBase
{
Expand Down
147 changes: 3 additions & 144 deletions benchmarks/Serialization/SerializationBenchmarkBase.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using System.Collections.Immutable;
using System.Text.Json;
using System.Text.Json.Serialization;
using Benchmarks.Tools;
using JetBrains.Annotations;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.Queries;
using JsonApiDotNetCore.Queries.Expressions;
using JsonApiDotNetCore.Queries.Internal;
using JsonApiDotNetCore.QueryStrings;
using JsonApiDotNetCore.Resources;
using JsonApiDotNetCore.Resources.Annotations;
using JsonApiDotNetCore.Serialization.Objects;
using JsonApiDotNetCore.Serialization.Response;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging.Abstractions;

namespace Benchmarks.Serialization;
Expand Down Expand Up @@ -45,9 +41,9 @@ protected SerializationBenchmarkBase()
// ReSharper restore VirtualMemberCallInConstructor

var linkBuilder = new FakeLinkBuilder();
var metaBuilder = new FakeMetaBuilder();
var metaBuilder = new NoMetaBuilder();
IQueryConstraintProvider[] constraintProviders = Array.Empty<IQueryConstraintProvider>();
var resourceDefinitionAccessor = new FakeResourceDefinitionAccessor();
var resourceDefinitionAccessor = new NeverResourceDefinitionAccessor();
var sparseFieldSetCache = new SparseFieldSetCache(constraintProviders, resourceDefinitionAccessor);
var requestQueryStringAccessor = new FakeRequestQueryStringAccessor();

Expand Down Expand Up @@ -122,141 +118,4 @@ public sealed class OutgoingResource : Identifiable<int>
[HasMany]
public ISet<OutgoingResource> Multi5 { get; set; } = null!;
}

private sealed class FakeResourceDefinitionAccessor : IResourceDefinitionAccessor
{
public IImmutableSet<IncludeElementExpression> OnApplyIncludes(ResourceType resourceType, IImmutableSet<IncludeElementExpression> existingIncludes)
{
return existingIncludes;
}

public FilterExpression? OnApplyFilter(ResourceType resourceType, FilterExpression? existingFilter)
{
return existingFilter;
}

public SortExpression? OnApplySort(ResourceType resourceType, SortExpression? existingSort)
{
return existingSort;
}

public PaginationExpression? OnApplyPagination(ResourceType resourceType, PaginationExpression? existingPagination)
{
return existingPagination;
}

public SparseFieldSetExpression? OnApplySparseFieldSet(ResourceType resourceType, SparseFieldSetExpression? existingSparseFieldSet)
{
return existingSparseFieldSet;
}

public object? GetQueryableHandlerForQueryStringParameter(Type resourceClrType, string parameterName)
{
return null;
}

public IDictionary<string, object?>? GetMeta(ResourceType resourceType, IIdentifiable resourceInstance)
{
return null;
}

public Task OnPrepareWriteAsync<TResource>(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task<IIdentifiable?> OnSetToOneRelationshipAsync<TResource>(TResource leftResource, HasOneAttribute hasOneRelationship,
IIdentifiable? rightResourceId, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.FromResult(rightResourceId);
}

public Task OnSetToManyRelationshipAsync<TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds,
WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnAddToRelationshipAsync<TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnRemoveFromRelationshipAsync<TResource>(TResource leftResource, HasManyAttribute hasManyRelationship, ISet<IIdentifiable> rightResourceIds,
CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnWritingAsync<TResource>(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public Task OnWriteSucceededAsync<TResource>(TResource resource, WriteOperationKind writeOperation, CancellationToken cancellationToken)
where TResource : class, IIdentifiable
{
return Task.CompletedTask;
}

public void OnDeserialize(IIdentifiable resource)
{
}

public void OnSerialize(IIdentifiable resource)
{
}
}

private sealed class FakeLinkBuilder : ILinkBuilder
{
public TopLevelLinks GetTopLevelLinks()
{
return new TopLevelLinks
{
Self = "TopLevel:Self"
};
}

public ResourceLinks GetResourceLinks(ResourceType resourceType, IIdentifiable resource)
{
return new ResourceLinks
{
Self = "Resource:Self"
};
}

public RelationshipLinks GetRelationshipLinks(RelationshipAttribute relationship, IIdentifiable leftResource)
{
return new RelationshipLinks
{
Self = "Relationship:Self",
Related = "Relationship:Related"
};
}
}

private sealed class FakeMetaBuilder : IMetaBuilder
{
public void Add(IDictionary<string, object?> values)
{
}

public IDictionary<string, object?>? Build()
{
return null;
}
}

private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor
{
public IQueryCollection Query { get; } = new QueryCollection(0);
}
}
Loading