-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Replace `/users/me` with `/me` in middleware. * Update args replacement * Refactor `UriReplacementHandler` to use generics, thus eliminating `MeUriReplacement` boxing allocations. Cleanup code. * Use from end indexing shorthand * Use explicit help detection * Move UriReplacement to kiota cli commons * Remove redundant pipeline * Revert: Remove redundant pipeline * Simplify stackalloc initialization * Update src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs Co-authored-by: Peter Ombwa <[email protected]> * Update src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs Co-authored-by: Peter Ombwa <[email protected]> * Update MeUriReplacementOption * Update MeUriReplacement to use kiota http handler * Update sonarcloud * Update .github/workflows/sonarcloud.yml Co-authored-by: Peter Ombwa <[email protected]> * Update sonar org. * Update sonarcloud org name * Fix code smell * Add coverlet msbuild for coverage reporting * Exclude sample project from sonarcloud exclusions. * Add a me alias to users to show in help --------- Co-authored-by: Peter Ombwa <[email protected]>
- Loading branch information
1 parent
d8c1014
commit 6fffc18
Showing
8 changed files
with
249 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
name: Sonarcloud | ||
on: | ||
workflow_dispatch: | ||
push: | ||
branches: | ||
- main | ||
paths-ignore: ['**.md', '.vscode/**', '**.svg'] | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
paths-ignore: ['**.md', '.vscode/**', '**.svg'] | ||
|
||
env: | ||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
|
||
jobs: | ||
checksecret: | ||
name: check if SONAR_TOKEN is set in github secrets | ||
runs-on: ubuntu-latest | ||
outputs: | ||
is_SONAR_TOKEN_set: ${{ steps.checksecret_job.outputs.is_SONAR_TOKEN_set }} | ||
steps: | ||
- name: Check whether unity activation requests should be done | ||
id: checksecret_job | ||
run: | | ||
echo "is_SONAR_TOKEN_set=${{ env.SONAR_TOKEN != '' }}" >> $GITHUB_OUTPUT | ||
build: | ||
needs: [checksecret] | ||
if: needs.checksecret.outputs.is_SONAR_TOKEN_set == 'true' | ||
name: Build | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Set up JDK 17 | ||
uses: actions/setup-java@v3 | ||
with: | ||
distribution: 'adopt' | ||
java-version: 17 | ||
- name: Setup .NET 5 # At the moment the scanner requires dotnet 5 https://www.nuget.org/packages/dotnet-sonarscanner | ||
uses: actions/setup-dotnet@v3 | ||
with: | ||
dotnet-version: 5.0.x | ||
- name: Setup .NET | ||
uses: actions/setup-dotnet@v3 | ||
with: | ||
dotnet-version: 7.0.x | ||
- uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis | ||
- name: Cache SonarCloud packages | ||
uses: actions/cache@v3 | ||
with: | ||
path: ~/.sonar/cache | ||
key: ${{ runner.os }}-sonar | ||
restore-keys: ${{ runner.os }}-sonar | ||
- name: Cache SonarCloud scanner | ||
id: cache-sonar-scanner | ||
uses: actions/cache@v3 | ||
with: | ||
path: ./.sonar/scanner | ||
key: ${{ runner.os }}-sonar-scanner | ||
restore-keys: ${{ runner.os }}-sonar-scanner | ||
- name: Install SonarCloud scanner | ||
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' | ||
shell: pwsh | ||
run: | | ||
New-Item -Path ./.sonar/scanner -ItemType Directory | ||
dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner | ||
- name: Build and analyze | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any | ||
CollectCoverage: true | ||
CoverletOutputFormat: 'opencover' # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682 | ||
shell: pwsh | ||
run: | | ||
./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoftgraph_msgraph-cli-core" /o:"microsoftgraph2" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml" /d:sonar.coverage.exclusions="src/sample/**" | ||
dotnet workload restore | ||
dotnet build | ||
dotnet test msgraph-cli-core.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover | ||
./.sonar/scanner/dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" |
42 changes: 42 additions & 0 deletions
42
src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementOptionTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System; | ||
using Microsoft.Graph.Cli.Core.Http.UriReplacement; | ||
using Xunit; | ||
|
||
namespace Microsoft.Graph.Cli.Core.Tests.Http.UriReplacement; | ||
|
||
public class MeUriReplacementOptionTests | ||
{ | ||
[Fact] | ||
public void Returns_Null_When_Given_A_Null_Url() | ||
{ | ||
var replacement = new MeUriReplacementOption(); | ||
|
||
Assert.Null(replacement.Replace(null)); | ||
} | ||
|
||
[Theory] | ||
[InlineData("http://example.com/test")] | ||
[InlineData("http://example.com/users/messages")] | ||
[InlineData("http://example.com/v1.0/users/messages")] | ||
[InlineData("http://example.com/users/test/me")] | ||
[InlineData("http://example.com/a/b/users/test/me")] | ||
public void Returns_Original_Uri_When_No_Match_Is_Found(string inputUri) | ||
{ | ||
var uri = new Uri(inputUri); | ||
var replacement = new MeUriReplacementOption(); | ||
|
||
Assert.Equal(uri, replacement.Replace(uri)); | ||
} | ||
|
||
[Theory] | ||
[InlineData("http://example.com/v1.0/users/me/messages", "http://example.com/v1.0/me/messages")] | ||
[InlineData("http://example.com/v1.0/users/me", "http://example.com/v1.0/me")] | ||
[InlineData("http://example.com/v1.0/users/me?a=b", "http://example.com/v1.0/me?a=b")] | ||
public void Returns_A_New_Url_When_A_Match_Is_Found(string inputUri, string expectedUri) | ||
{ | ||
var replacement = new MeUriReplacementOption(); | ||
|
||
var uri = new Uri(inputUri); | ||
Assert.Equal(expectedUri, replacement.Replace(uri)!.ToString()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
using System; | ||
using Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options; | ||
|
||
namespace Microsoft.Graph.Cli.Core.Http.UriReplacement; | ||
|
||
/// <summary> | ||
/// Specialized replacement for /[version]/users/me with /[version]/me | ||
/// </summary> | ||
public class MeUriReplacementOption : IUriReplacementHandlerOption | ||
{ | ||
private readonly bool isEnabled; | ||
|
||
/// <summary> | ||
/// Create new MeUriReplacementOption | ||
/// </summary> | ||
/// <param name="isEnabled">Whether the uri replacement is enabled.</param> | ||
public MeUriReplacementOption(bool isEnabled = true) | ||
{ | ||
this.isEnabled = isEnabled; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public bool IsEnabled() | ||
{ | ||
return isEnabled; | ||
} | ||
|
||
/// <summary> | ||
/// If a URI path starts with /[version]/users/me, replace it with /[version]/me | ||
/// </summary> | ||
/// <param name="original">The original URI</param> | ||
/// <returns>A URI with /[version]/users/me replaced with /[version]/me</returns> | ||
/// <remarks>This method assumes that the first segment after the root is a version segment to match Microsoft Graph API's format.</remarks> | ||
public Uri? Replace(Uri? original) | ||
{ | ||
if (original is null) | ||
{ | ||
return null; | ||
} | ||
|
||
if (!isEnabled || original.Segments.Length < 4) | ||
{ | ||
// Must have at least segments "/", "[version]/", "users/", "me" | ||
return original; | ||
} | ||
|
||
Span<char> toMatch = stackalloc char[] { '/', 'u', 's', 'e', 'r', 's', '/', 'm', 'e' }; | ||
var separator = toMatch[..1]; | ||
var matchUsers = toMatch[1..6]; | ||
var matchMe = toMatch[7..]; | ||
|
||
var maybeUsersSegment = original.Segments[2].AsSpan(); | ||
if (!maybeUsersSegment[..^1].SequenceEqual(matchUsers)) | ||
{ | ||
return original; | ||
} | ||
|
||
var maybeMeSegment = original.Segments[3].AsSpan(); | ||
if (!maybeMeSegment[..(maybeMeSegment.EndsWith(separator) ? ^1 : ^0)].SequenceEqual(matchMe)) | ||
{ | ||
return original; | ||
} | ||
|
||
var newUrl = new UriBuilder(original); | ||
var versionSegment = original.Segments[1].AsSpan(); | ||
const int usersMeLength = 9; | ||
var length = versionSegment.Length + usersMeLength; | ||
if (newUrl.Path.Length == length) | ||
{ | ||
// Matched /[version]/users/me | ||
newUrl.Path = string.Concat(separator, versionSegment, matchMe); | ||
} | ||
else | ||
{ | ||
// Maybe matched /[version]/users/me... | ||
// Logic to make sure we don't match paths like /users/messages | ||
var span = newUrl.Path.AsSpan(length); | ||
if (span[0] == '/') | ||
{ | ||
newUrl.Path = string.Concat(separator, versionSegment, matchMe, span); | ||
} | ||
} | ||
|
||
return newUrl.Uri; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters