Skip to content

Commit

Permalink
Added .NET 9 support (#282)
Browse files Browse the repository at this point in the history
* Add .NET 9 support
* Update dotnet-tools
* Update github actions in pipeline
* Update dependabot.yaml

---------

Signed-off-by: David Perfors <[email protected]>
  • Loading branch information
dnperfors authored Nov 15, 2024
1 parent 0913eb2 commit 8c33d36
Show file tree
Hide file tree
Showing 19 changed files with 118 additions and 73 deletions.
2 changes: 1 addition & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-sonarscanner": {
"version": "8.0.3",
"version": "9.0.0",
"commands": [
"dotnet-sonarscanner"
],
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ A clear and concise description of what you expected to happen.

**Background (please complete the following information):**
- Version of library: [e.g. 0.10]
- Version of .NET: [e.g. 7.0]
- Version of .NET: [e.g. 8.0]

**Additional context**
Add any other context about the problem here.
11 changes: 9 additions & 2 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ updates:
directory: "/"
groups:
all-dependencies:
patterns: "*"
patterns:
- "*"
schedule:
interval: "daily"
reviewers:
- "dnperfors"
- "dnperfors"
- package-ecosystem: "github-actions"
directory: ".github/"
schedule:
interval: "daily"
reviewers:
- "dnperfors"
22 changes: 13 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,21 @@ jobs:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Update Java SDK for SonarQube
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'microsoft'
java-version: '21'
- name: Setup .NET versions
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
include-prerelease: true
- name: Dump .NET info
run: dotnet --info
Expand All @@ -52,6 +54,7 @@ jobs:
run: dotnet sonarscanner end -d:sonar.token=${{env.SONAR_TOKEN}}
- name: Check source file format
run: dotnet format --no-restore --verify-no-changes
continue-on-error: true
- name: Pack
run: dotnet pack --output ./artifacts --configuration Release --no-build
- uses: actions/upload-artifact@v4
Expand All @@ -70,15 +73,16 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Fetch all history for all tags and branches
run: git fetch --prune --unshallow
- name: Setup .NET versions
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
8.0.x
9.0.x
include-prerelease: true
- name: Dump .NET info
run: dotnet --info
Expand All @@ -95,12 +99,12 @@ jobs:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup .NET versions
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
9.0.x
include-prerelease: true
- uses: actions/download-artifact@v4
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
9.0.x
include-prerelease: true
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
Expand All @@ -37,6 +37,6 @@ jobs:
languages: csharp
config-file: ./.github/codeql-config.yml
- name: Build source code
run: dotnet build --configuration Release --framework net6.0
run: dotnet build --configuration Release --framework net8.0
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.12] - unplanned
### Added
- Support for .NET 9.0

## [0.11] - 2024-06-15
### Removed
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<LangVersion>12.0</LangVersion>
<LangVersion>13.0</LangVersion>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020-2022 David Perfors
Copyright (c) 2020-2024 David Perfors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ The following versions are being actively tested and thus supported:
- .NET Framework 4.6, 4.7 and 4.8
- .NET 6.0
- .NET 8.0
- .NET 9.0

These versions are supported as long as Microsoft supports them, we do our best to test and support newer versions as soon as possible.

Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.100",
"version": "9.0.100",
"allowPrerelease": false,
"rollForward": "latestMajor"
}
Expand Down
5 changes: 3 additions & 2 deletions src/TestableHttpClient/TestableHttpClient.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net6.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -33,7 +33,8 @@

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.Json" Version="4.6.0" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="System.Text.Encodings.Web" Version="4.7.2" />
<PackageReference Include="Perfors.UnreachableException" Version="1.0.0" />
<PackageReference Include="PolyKit.Embedded" Version="3.0.9" />
</ItemGroup>
Expand Down
4 changes: 1 addition & 3 deletions src/TestableHttpClient/TestableHttpMessageHandlerOptions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Diagnostics.CodeAnalysis;

namespace TestableHttpClient;
namespace TestableHttpClient;

public sealed class TestableHttpMessageHandlerOptions
{
Expand Down
85 changes: 50 additions & 35 deletions src/TestableHttpClient/Utils/UriPatternParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,49 +75,64 @@ private static UriPattern ParsePattern(ReadOnlySpan<char> patternSpan)
Query = ParseQuery(queryPattern)
};

static Value ParseScheme(ReadOnlySpan<char> scheme) => scheme switch
static Value ParseScheme(ReadOnlySpan<char> scheme)
{
[] => Value.Any(),
['*'] => Value.Any(),
_ when scheme.IndexOf('*') != -1 => Value.Pattern(scheme.ToString()),
_ => Value.Exact(scheme.ToString())
};
return scheme switch
{
[] => Value.Any(),
['*'] => Value.Any(),
_ when scheme.IndexOf('*') != -1 => Value.Pattern(scheme.ToString()),
_ => Value.Exact(scheme.ToString())
};
}

static Value ParseHost(ReadOnlySpan<char> host) => host switch
static Value ParseHost(ReadOnlySpan<char> host)
{
[] => Value.Any(),
['*'] => Value.Any(),
_ when host.IndexOf('*') != -1 => Value.Pattern(host.ToString()),
_ => Value.Exact(host.ToString())
};
return host switch
{
[] => Value.Any(),
['*'] => Value.Any(),
_ when host.IndexOf('*') != -1 => Value.Pattern(host.ToString()),
_ => Value.Exact(host.ToString())
};
}

static Value ParsePort(ReadOnlySpan<char> port) => port switch
static Value ParsePort(ReadOnlySpan<char> port)
{
[] => Value.Any(),
[':'] => throw new UriPatternParserException("Invalid port"),
[':', '*'] => Value.Any(),
[':', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()),
[':', .. var rest] => Value.Exact(rest.ToString()),
_ => throw new UnreachableException()
};
return port switch
{
[] => Value.Any(),
[':'] => throw new UriPatternParserException("Invalid port"),
[':', '*'] => Value.Any(),
[':', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()),
[':', .. var rest] => Value.Exact(rest.ToString()),
_ => throw new UnreachableException()
};
}

static Value ParsePath(ReadOnlySpan<char> path) => path switch
static Value ParsePath(ReadOnlySpan<char> path)
{
[] => Value.Any(),
['/', '*'] => Value.Any(),
['/', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(path.ToString()),
['/', ..] => Value.Exact(path.ToString()),
_ => throw new UnreachableException()
};
return path switch
{
[] => Value.Any(),
['/', '*'] => Value.Any(),
['/', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(path.ToString()),
['/', ..] => Value.Exact(path.ToString()),
_ => throw new UnreachableException()
};
}

static Value ParseQuery(ReadOnlySpan<char> query) => query switch
static Value ParseQuery(ReadOnlySpan<char> query)
{
[] => Value.Any(),
['?'] => Value.Any(),
['?', '*'] => Value.Any(),
['?', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()),
['?', .. var rest] => Value.Exact(rest.ToString()),
_ => throw new UnreachableException()
};
return query switch
{
[] => Value.Any(),
['?'] => Value.Any(),
['?', '*'] => Value.Any(),
['?', .. var rest] when rest.IndexOf('*') != -1 => Value.Pattern(rest.ToString()),
['?', .. var rest] => Value.Exact(rest.ToString()),
_ => throw new UnreachableException()
};
}
}
}
6 changes: 6 additions & 0 deletions test/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ dotnet_diagnostic.CA2007.severity = silent

# CA2234: Pass system uri objects instead of strings
dotnet_diagnostic.CA2234.severity = silent

# CA1515: Because an application's API isn't typically referenced from outside the assembly, types can be made internal
dotnet_diagnostic.CA1515.severity = silent

# IDE0058: Expression value is never used
dotnet_diagnostic.IDE0058.severity = silent
14 changes: 9 additions & 5 deletions test/TestableHttpClient.IntegrationTests/ConfigureResponses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,16 @@ public async Task UsingTestHandlerWithCustomResponseFactory_AllowsForAdvancedUse
{
using TestableHttpMessageHandler testHandler = new();

static IResponse PathBasedResponse(HttpResponseContext context) => context.HttpRequestMessage switch
static IResponse PathBasedResponse(HttpResponseContext context)
{
_ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/200" => StatusCode(HttpStatusCode.OK),
_ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/400" => StatusCode(HttpStatusCode.BadRequest),
_ => StatusCode(HttpStatusCode.NotFound)
};
return context.HttpRequestMessage switch
{
_ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/200" => StatusCode(HttpStatusCode.OK),
_ when context.HttpRequestMessage.RequestUri?.AbsolutePath == "/status/400" => StatusCode(HttpStatusCode.BadRequest),
_ => StatusCode(HttpStatusCode.NotFound)
};
}

testHandler.RespondWith(SelectResponse(PathBasedResponse));

using HttpClient httpClient = new(testHandler);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net462;net47;net48;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net47;net48;net6.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<PackageReference Include="System.Net.Http.Json" Version="[3.1.*,5.0.0)" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Net.Http.Json" Version="[8.0.*,)" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
Expand All @@ -15,11 +16,17 @@
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="[8.0.*,)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="[8.0.*,)" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="[8.0.*,)" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="[8.0.*,9.0.0)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="[8.0.*,9.0.0)" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="[8.0.*,9.0.0)" />
</ItemGroup>


<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="[9.0.*,)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="[9.0.*,)" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="[9.0.*,)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\TestableHttpClient\TestableHttpClient.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests;

public static class Args
internal static class Args
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Non-substitutable member", "NS1004:Argument matcher used with a non-virtual member of a class.", Justification = "This is a custom matcher.")]
public static ref Func<HttpRequestMessage, bool> AnyPredicate() => ref Arg.Any<Func<HttpRequestMessage, bool>>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace TestableHttpClient.Tests.Response;

public static class ResponseTestHelpers
internal static class ResponseTestHelpers
{
public static Task<HttpResponseMessage> TestAsync(this IResponse response) => TestAsync(response, "http://httpbin.org");
public static Task<HttpResponseMessage> TestAsync(this IResponse response, string url)
Expand Down
4 changes: 2 additions & 2 deletions test/TestableHttpClient.Tests/TestableHttpClient.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net462;net47;net48;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net462;net47;net48;net6.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<PackageReference Include="System.Net.Http.Json" Version="6.0.1" />
<PackageReference Include="System.Net.Http.Json" Version="6.0.2" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit 8c33d36

Please sign in to comment.