From 5b3c1a2a89b57a5f49be1404a492a0de1acbaaff Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 03:01:19 +0300
Subject: [PATCH 01/21] Replace `/users/me` with `/me` in middleware.
---
.../Http/UriReplacementHandlerTests.cs | 52 +++++++++
.../Http/UriReplacementHandler.cs | 106 ++++++++++++++++++
.../IO/GraphCliClientFactory.cs | 3 +
src/sample/Program.cs | 13 +++
4 files changed, 174 insertions(+)
create mode 100644 src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs
create mode 100644 src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
diff --git a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs
new file mode 100644
index 00000000..a95eb961
--- /dev/null
+++ b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs
@@ -0,0 +1,52 @@
+using System;
+using Microsoft.Graph.Cli.Core.Http;
+using Xunit;
+
+namespace Microsoft.Graph.Cli.Core.Tests.Http;
+
+public class MeUriReplacementTests
+{
+ [Fact]
+ public void Returns_Null_When_Given_A_Null_Url()
+ {
+ var replacement = new MeUriReplacement();
+
+ Assert.Null(replacement.Replace(null));
+ }
+
+ [Fact]
+ public void Returns_Original_Uri_When_No_Match_Is_Found()
+ {
+ var uri = new Uri("http://example.com/test");
+ var replacement = new MeUriReplacement();
+
+ Assert.Equal(uri, replacement.Replace(uri));
+
+ uri = new Uri("http://example.com/users/messages");
+ Assert.Equal(uri, replacement.Replace(uri));
+
+ uri = new Uri("http://example.com/v1.0/users/messages");
+ Assert.Equal(uri, replacement.Replace(uri));
+
+ uri = new Uri("http://example.com/users/test/me");
+ Assert.Equal(uri, replacement.Replace(uri));
+
+ uri = new Uri("http://example.com/a/b/users/test/me");
+ Assert.Equal(uri, replacement.Replace(uri));
+ }
+
+ [Fact]
+ public void Returns_A_New_Url_When_A_Match_Is_Found()
+ {
+ var replacement = new MeUriReplacement();
+
+ var uri = new Uri("http://example.com/v1.0/users/me/messages");
+ Assert.Equal("http://example.com/v1.0/me/messages", replacement.Replace(uri)!.ToString());
+
+ uri = new Uri("http://example.com/v1.0/users/me");
+ Assert.Equal("http://example.com/v1.0/me", replacement.Replace(uri)!.ToString());
+
+ uri = new Uri("http://example.com/v1.0/users/me?a=b");
+ Assert.Equal("http://example.com/v1.0/me?a=b", replacement.Replace(uri)!.ToString());
+ }
+}
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
new file mode 100644
index 00000000..f581233f
--- /dev/null
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+namespace Microsoft.Graph.Cli.Core.Http;
+
+///
+/// Interface for making URI replacements.
+///
+public interface IUriReplacement
+{
+ ///
+ /// Accepts a URI and returns a new URI with all replacements applied.
+ ///
+ /// The URI to apply replacements to
+ /// A new URI with all replacements applied.
+ Uri? Replace(Uri? original);
+}
+
+///
+/// Specialized replacement for /[version]/users/me with /[version]/me
+///
+public struct MeUriReplacement : IUriReplacement
+{
+ ///
+ /// If a URI path starts with /[version]/users/me, replace it with /[version]/me
+ ///
+ /// The original URI
+ /// A URI with /[version]/users/me replaced with /[version]/me
+ /// This method assumes that the first segment after the root is a version segment to match Microsoft Graph API's format.
+ public readonly Uri? Replace(Uri? original)
+ {
+ if (original is null)
+ {
+ return null;
+ }
+
+ if (original.Segments.Length < 4)
+ {
+ // Must have at least segments "/", "[version]/", "users/", "me"
+ return original;
+ }
+
+ var separator = new ReadOnlySpan('/');
+ var matchUsers = new ReadOnlySpan(new char[] { 'u', 's', 'e', 'r', 's' });
+ var matchMe = new ReadOnlySpan(new char[] { 'm', 'e' });
+
+ var maybeUsersSegment = original.Segments[2].AsSpan();
+ if (!maybeUsersSegment[..(maybeUsersSegment.Length - 1)].SequenceEqual(matchUsers))
+ {
+ return original;
+ }
+
+ var maybeMeSegment = original.Segments[3].AsSpan();
+ if (!maybeMeSegment[..(maybeMeSegment.EndsWith(separator) ? maybeMeSegment.Length - 1 : maybeMeSegment.Length)].SequenceEqual(matchMe))
+ {
+ return original;
+ }
+
+ var newUrl = new UriBuilder(original);
+ var versionSegment = original.Segments[1].AsSpan();
+ const int USERS_ME_LENGTH = 9;
+ var length = versionSegment.Length + USERS_ME_LENGTH;
+ 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;
+ }
+}
+
+///
+/// Replaces a portion of the URL.
+///
+public partial class UriReplacementHandler : DelegatingHandler
+{
+ private readonly IUriReplacement urlReplacement;
+
+ ///
+ /// Creates a new UriReplacementHandler.
+ ///
+ public UriReplacementHandler(IUriReplacement urlReplacement)
+ {
+ this.urlReplacement = urlReplacement;
+ }
+
+ ///
+ protected override async Task SendAsync(
+ HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
+ {
+ request.RequestUri = urlReplacement.Replace(request.RequestUri);
+ return await base.SendAsync(request, cancellationToken);
+ }
+}
diff --git a/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs b/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
index 67ae7c05..f7b992bd 100644
--- a/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
+++ b/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
@@ -38,6 +38,9 @@ public static HttpClient GetDefaultClient(GraphClientOptions? options = null, st
m.AddRange(middlewares);
+ // Add replacement handler for /users/me to /me
+ m.Add(new UriReplacementHandler(new MeUriReplacement()));
+
// Add logging handler.
if (loggingHandler is LoggingHandler lh)
{
diff --git a/src/sample/Program.cs b/src/sample/Program.cs
index 48a1805f..aeece85f 100644
--- a/src/sample/Program.cs
+++ b/src/sample/Program.cs
@@ -42,6 +42,19 @@ class Program
static async Task Main(string[] args)
{
+ // Replace `me ...` with `users ... --user-id me`
+ if (args[0] == "me") {
+ var newArgs = new string[args.Length + 2];
+ newArgs[0] = "users";
+ for (int i = 1; i < args.Length; i++)
+ {
+ newArgs[i] = args[i];
+ }
+ newArgs[args.Length] = "--user-id";
+ newArgs[args.Length + 1] = "me";
+ args = newArgs;
+ }
+
var builder = BuildCommandLine()
.UseDefaults()
.UseHost(CreateHostBuilder)
From 1a0f0e9091c23ea984abd0a9e100ce19800ddb4a Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 03:11:37 +0300
Subject: [PATCH 02/21] Update args replacement
---
src/sample/Program.cs | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/src/sample/Program.cs b/src/sample/Program.cs
index aeece85f..07fe45c2 100644
--- a/src/sample/Program.cs
+++ b/src/sample/Program.cs
@@ -6,6 +6,7 @@
using System.CommandLine.Parsing;
using System.Diagnostics.Tracing;
using System.IO;
+using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
@@ -43,16 +44,21 @@ class Program
static async Task Main(string[] args)
{
// Replace `me ...` with `users ... --user-id me`
- if (args[0] == "me") {
- var newArgs = new string[args.Length + 2];
+ if (args[0] == "me")
+ {
+ var hasHelp = args.Any(static x => x.Contains("-h") || x.Contains("/?"));
+ var newArgs = hasHelp ? args : new string[args.Length + 2];
newArgs[0] = "users";
for (int i = 1; i < args.Length; i++)
{
newArgs[i] = args[i];
}
- newArgs[args.Length] = "--user-id";
- newArgs[args.Length + 1] = "me";
- args = newArgs;
+ if (newArgs.Length > args.Length)
+ {
+ newArgs[args.Length] = "--user-id";
+ newArgs[args.Length + 1] = "me";
+ args = newArgs;
+ }
}
var builder = BuildCommandLine()
From 93877ea97c97682c9615c6a6f80c458888192d80 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 03:59:23 +0300
Subject: [PATCH 03/21] Refactor `UriReplacementHandler` to use generics, thus
eliminating `MeUriReplacement` boxing allocations.
Cleanup code.
---
.../Http/LoggingHandler.cs | 21 ++------------
.../Http/UriReplacementHandler.cs | 28 +++++++++++++------
.../IO/GraphCliClientFactory.cs | 19 ++++++-------
src/sample/Program.cs | 2 +-
4 files changed, 32 insertions(+), 38 deletions(-)
diff --git a/src/Microsoft.Graph.Cli.Core/Http/LoggingHandler.cs b/src/Microsoft.Graph.Cli.Core/Http/LoggingHandler.cs
index 66900383..60b79797 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/LoggingHandler.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/LoggingHandler.cs
@@ -45,12 +45,6 @@ protected override async Task SendAsync(
return response;
}
- ///
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
- }
-
private static string HeadersToString(in HttpHeaders headers, in HttpContentHeaders? contentHeaders)
{
if (!headers.Any() && contentHeaders?.Any() == false) return string.Empty;
@@ -61,7 +55,7 @@ static string selector(KeyValuePair> h)
{
value = "[PROTECTED]";
}
- return string.Format("{0}: {1}\n", h.Key, value);
+ return $"{h.Key}: {value}\n";
};
static string aggregator(string a, string b)
@@ -95,17 +89,8 @@ private static async Task ContentToStringAsync(HttpContent? content, Can
{
return await content.ReadAsStringAsync(cancellationToken);
}
- else
- {
- if (content.Headers.ContentLength > 0)
- {
- return $"[...<{content.Headers.ContentLength} byte data stream>...]";
- }
- else
- {
- return "[......]";
- }
- }
+
+ return content.Headers.ContentLength > 0 ? $"[...<{content.Headers.ContentLength} byte data stream>...]" : "[......]";
}
[LoggerMessage(EventId = 1, Level = LogLevel.Debug, Message = "\nRequest:\n\n{RequestMethod} {RequestUri} HTTP/{HttpVersion}\n{Headers}\n{RequestContent}\n")]
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
index f581233f..7dedd8a2 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
@@ -41,12 +41,22 @@ public struct MeUriReplacement : IUriReplacement
return original;
}
- var separator = new ReadOnlySpan('/');
- var matchUsers = new ReadOnlySpan(new char[] { 'u', 's', 'e', 'r', 's' });
- var matchMe = new ReadOnlySpan(new char[] { 'm', 'e' });
+ Span toMatch = stackalloc char[9];
+ toMatch[0] = '/';
+ toMatch[1] = 'u';
+ toMatch[2] = 's';
+ toMatch[3] = 'e';
+ toMatch[4] = 'r';
+ toMatch[5] = 's';
+ toMatch[6] = '/';
+ toMatch[7] = 'm';
+ toMatch[8] = 'e';
+ var separator = toMatch[..1];
+ var matchUsers = toMatch[1..6];
+ var matchMe = toMatch[7..];
var maybeUsersSegment = original.Segments[2].AsSpan();
- if (!maybeUsersSegment[..(maybeUsersSegment.Length - 1)].SequenceEqual(matchUsers))
+ if (!maybeUsersSegment[..^1].SequenceEqual(matchUsers))
{
return original;
}
@@ -59,8 +69,8 @@ public struct MeUriReplacement : IUriReplacement
var newUrl = new UriBuilder(original);
var versionSegment = original.Segments[1].AsSpan();
- const int USERS_ME_LENGTH = 9;
- var length = versionSegment.Length + USERS_ME_LENGTH;
+ const int usersMeLength = 9;
+ var length = versionSegment.Length + usersMeLength;
if (newUrl.Path.Length == length)
{
// Matched /[version]/users/me
@@ -84,14 +94,14 @@ public struct MeUriReplacement : IUriReplacement
///
/// Replaces a portion of the URL.
///
-public partial class UriReplacementHandler : DelegatingHandler
+public class UriReplacementHandler : DelegatingHandler where TUriReplacement: IUriReplacement
{
- private readonly IUriReplacement urlReplacement;
+ private readonly TUriReplacement urlReplacement;
///
/// Creates a new UriReplacementHandler.
///
- public UriReplacementHandler(IUriReplacement urlReplacement)
+ public UriReplacementHandler(TUriReplacement urlReplacement)
{
this.urlReplacement = urlReplacement;
}
diff --git a/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs b/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
index f7b992bd..cd3e0387 100644
--- a/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
+++ b/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
@@ -39,10 +39,10 @@ public static HttpClient GetDefaultClient(GraphClientOptions? options = null, st
m.AddRange(middlewares);
// Add replacement handler for /users/me to /me
- m.Add(new UriReplacementHandler(new MeUriReplacement()));
+ m.Add(new UriReplacementHandler(new MeUriReplacement()));
// Add logging handler.
- if (loggingHandler is LoggingHandler lh)
+ if (loggingHandler is { } lh)
{
m.Add(lh);
}
@@ -50,20 +50,19 @@ public static HttpClient GetDefaultClient(GraphClientOptions? options = null, st
// Set compression handler to be last (Allows logging handler to log request body)
m.Sort((a, b) =>
{
- var a_match = a is Kiota.Http.HttpClientLibrary.Middleware.CompressionHandler;
- var b_match = b is Kiota.Http.HttpClientLibrary.Middleware.CompressionHandler;
- if (a_match && !b_match)
+ var aMatch = a is Kiota.Http.HttpClientLibrary.Middleware.CompressionHandler;
+ var bMatch = b is Kiota.Http.HttpClientLibrary.Middleware.CompressionHandler;
+ if (aMatch && !bMatch)
{
return 1;
}
- else if (b_match && !a_match)
+
+ if (bMatch && !aMatch)
{
return -1;
}
- else
- {
- return 0;
- }
+
+ return 0;
});
return GraphClientFactory.Create(version: version, nationalCloud: nationalCloud, finalHandler: finalHandler, handlers: m);
diff --git a/src/sample/Program.cs b/src/sample/Program.cs
index 07fe45c2..addfb44c 100644
--- a/src/sample/Program.cs
+++ b/src/sample/Program.cs
@@ -49,7 +49,7 @@ static async Task Main(string[] args)
var hasHelp = args.Any(static x => x.Contains("-h") || x.Contains("/?"));
var newArgs = hasHelp ? args : new string[args.Length + 2];
newArgs[0] = "users";
- for (int i = 1; i < args.Length; i++)
+ for (var i = 1; i < args.Length; i++)
{
newArgs[i] = args[i];
}
From 687e9758a0fc54c2af60265e94cb7f92c17b7a46 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 04:08:10 +0300
Subject: [PATCH 04/21] Use from end indexing shorthand
---
src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
index 7dedd8a2..2aed76e3 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
@@ -62,7 +62,7 @@ public struct MeUriReplacement : IUriReplacement
}
var maybeMeSegment = original.Segments[3].AsSpan();
- if (!maybeMeSegment[..(maybeMeSegment.EndsWith(separator) ? maybeMeSegment.Length - 1 : maybeMeSegment.Length)].SequenceEqual(matchMe))
+ if (!maybeMeSegment[..(maybeMeSegment.EndsWith(separator) ? ^1 : ^0)].SequenceEqual(matchMe))
{
return original;
}
From 04fd9bbfd5aad9e69de811c51695d6b87f920685 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 04:17:12 +0300
Subject: [PATCH 05/21] Use explicit help detection
---
src/sample/Program.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sample/Program.cs b/src/sample/Program.cs
index addfb44c..23ec893b 100644
--- a/src/sample/Program.cs
+++ b/src/sample/Program.cs
@@ -46,7 +46,7 @@ static async Task Main(string[] args)
// Replace `me ...` with `users ... --user-id me`
if (args[0] == "me")
{
- var hasHelp = args.Any(static x => x.Contains("-h") || x.Contains("/?"));
+ var hasHelp = args.Any(static x => x == "--help" || x == "-h" || x == "/?");
var newArgs = hasHelp ? args : new string[args.Length + 2];
newArgs[0] = "users";
for (var i = 1; i < args.Length; i++)
From 0622cb24ea5f76eaefa28f65c5b1740bb163a1fb Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 16:31:45 +0300
Subject: [PATCH 06/21] Move UriReplacement to kiota cli commons
---
.github/workflows/sonarcloud.yml | 78 +++++++++++++++++++
.../MeUriReplacementTests.cs} | 4 +-
.../MeUrlReplacement.cs} | 43 +---------
.../Microsoft.Graph.Cli.Core.csproj | 2 +-
4 files changed, 82 insertions(+), 45 deletions(-)
create mode 100644 .github/workflows/sonarcloud.yml
rename src/Microsoft.Graph.Cli.Core.Tests/Http/{UriReplacementHandlerTests.cs => UriReplacement/MeUriReplacementTests.cs} (93%)
rename src/Microsoft.Graph.Cli.Core/Http/{UriReplacementHandler.cs => UriReplacement/MeUrlReplacement.cs} (65%)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
new file mode 100644
index 00000000..79a5b9b3
--- /dev/null
+++ b/.github/workflows/sonarcloud.yml
@@ -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:"microsoft_kiota-cli-commons" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
+ dotnet workload restore
+ dotnet build
+ dotnet test Microsoft.Kiota.Cli.Commons.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
+ ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
diff --git a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
similarity index 93%
rename from src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs
rename to src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
index a95eb961..00d3b565 100644
--- a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacementHandlerTests.cs
+++ b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
@@ -1,8 +1,8 @@
using System;
-using Microsoft.Graph.Cli.Core.Http;
+using Microsoft.Graph.Cli.Core.Http.UriReplacement;
using Xunit;
-namespace Microsoft.Graph.Cli.Core.Tests.Http;
+namespace Microsoft.Graph.Cli.Core.Tests.Http.UriReplacement;
public class MeUriReplacementTests
{
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
similarity index 65%
rename from src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
rename to src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
index 2aed76e3..14524d3b 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/UriReplacementHandler.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
@@ -1,21 +1,4 @@
-using System;
-using System.Net.Http;
-using System.Threading.Tasks;
-
-namespace Microsoft.Graph.Cli.Core.Http;
-
-///
-/// Interface for making URI replacements.
-///
-public interface IUriReplacement
-{
- ///
- /// Accepts a URI and returns a new URI with all replacements applied.
- ///
- /// The URI to apply replacements to
- /// A new URI with all replacements applied.
- Uri? Replace(Uri? original);
-}
+namespace Microsoft.Graph.Cli.Core.Http.UriReplacement;
///
/// Specialized replacement for /[version]/users/me with /[version]/me
@@ -90,27 +73,3 @@ public struct MeUriReplacement : IUriReplacement
return newUrl.Uri;
}
}
-
-///
-/// Replaces a portion of the URL.
-///
-public class UriReplacementHandler : DelegatingHandler where TUriReplacement: IUriReplacement
-{
- private readonly TUriReplacement urlReplacement;
-
- ///
- /// Creates a new UriReplacementHandler.
- ///
- public UriReplacementHandler(TUriReplacement urlReplacement)
- {
- this.urlReplacement = urlReplacement;
- }
-
- ///
- protected override async Task SendAsync(
- HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
- {
- request.RequestUri = urlReplacement.Replace(request.RequestUri);
- return await base.SendAsync(request, cancellationToken);
- }
-}
diff --git a/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj b/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
index e06bca93..478a919d 100644
--- a/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
+++ b/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
@@ -44,7 +44,7 @@
-
+
From 40bd0f8a04651520ee237986dc02ea279ee92000 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 16:39:02 +0300
Subject: [PATCH 07/21] Remove redundant pipeline
---
.github/workflows/release-package.yml | 58 ---------------------------
1 file changed, 58 deletions(-)
delete mode 100644 .github/workflows/release-package.yml
diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml
deleted file mode 100644
index c26b0650..00000000
--- a/.github/workflows/release-package.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-name: Release solution
-
-on:
- workflow_dispatch:
- push:
- # paths: ['src/**', '.github/workflows/**', 'msgraph-cli-core.sln']
-
-jobs:
- build:
- runs-on: ubuntu-latest
- env:
- MS_NUGET_URL: https://nuget.pkg.github.com/microsoft/index.json
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Setup .NET Core SDK 6
- uses: actions/setup-dotnet@v3.2.0
- with:
- dotnet-version: 7.x
- - uses: actions/cache@v3
- with:
- path: ~/.nuget/packages
- # Look to see if there is a cache hit for the corresponding requirements file
- key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
- restore-keys: |
- ${{ runner.os }}-nuget
- - name: Install dependencies
- run: dotnet restore
- - name: Test
- run: dotnet test --no-restore
- - id: publish
- name: Publish
- if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- run: dotnet publish --no-restore --verbosity normal -c Release
- - id: pack
- name: Pack
- if: ${{ steps.publish.outcome == 'success' }}
- run: dotnet pack --no-restore --no-build --verbosity normal -c Release
- - name: Upload Nuget Package
- if: ${{ steps.pack.outcome == 'success' }}
- uses: actions/upload-artifact@v3
- with:
- name: drop
- path: |
- ./src/Microsoft.Graph.Cli.Core/bin/Release/*.nupkg
- deploy:
- if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- runs-on: ubuntu-latest
- needs: [build]
- steps:
- - name: Setup .NET
- uses: actions/setup-dotnet@v3.2.0
- with:
- dotnet-version: 7.x
- - uses: actions/download-artifact@v3
- with:
- name: drop
- - run: dotnet nuget push "*.nupkg" --skip-duplicate -s https://nuget.pkg.github.com/microsoftgraph/index.json -k ${{ secrets.GITHUB_TOKEN }}
From 5075616c8d1572f098d6b3d80cafe4b355905963 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 16:46:46 +0300
Subject: [PATCH 08/21] Revert: Remove redundant pipeline
---
.github/workflows/release-package.yml | 58 +++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
create mode 100644 .github/workflows/release-package.yml
diff --git a/.github/workflows/release-package.yml b/.github/workflows/release-package.yml
new file mode 100644
index 00000000..c26b0650
--- /dev/null
+++ b/.github/workflows/release-package.yml
@@ -0,0 +1,58 @@
+name: Release solution
+
+on:
+ workflow_dispatch:
+ push:
+ # paths: ['src/**', '.github/workflows/**', 'msgraph-cli-core.sln']
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ env:
+ MS_NUGET_URL: https://nuget.pkg.github.com/microsoft/index.json
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Setup .NET Core SDK 6
+ uses: actions/setup-dotnet@v3.2.0
+ with:
+ dotnet-version: 7.x
+ - uses: actions/cache@v3
+ with:
+ path: ~/.nuget/packages
+ # Look to see if there is a cache hit for the corresponding requirements file
+ key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-nuget
+ - name: Install dependencies
+ run: dotnet restore
+ - name: Test
+ run: dotnet test --no-restore
+ - id: publish
+ name: Publish
+ if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
+ run: dotnet publish --no-restore --verbosity normal -c Release
+ - id: pack
+ name: Pack
+ if: ${{ steps.publish.outcome == 'success' }}
+ run: dotnet pack --no-restore --no-build --verbosity normal -c Release
+ - name: Upload Nuget Package
+ if: ${{ steps.pack.outcome == 'success' }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: drop
+ path: |
+ ./src/Microsoft.Graph.Cli.Core/bin/Release/*.nupkg
+ deploy:
+ if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
+ runs-on: ubuntu-latest
+ needs: [build]
+ steps:
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3.2.0
+ with:
+ dotnet-version: 7.x
+ - uses: actions/download-artifact@v3
+ with:
+ name: drop
+ - run: dotnet nuget push "*.nupkg" --skip-duplicate -s https://nuget.pkg.github.com/microsoftgraph/index.json -k ${{ secrets.GITHUB_TOKEN }}
From 8fe974bc972b76067835625d113927e12d59dc76 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Wed, 1 Nov 2023 19:19:37 +0300
Subject: [PATCH 09/21] Simplify stackalloc initialization
---
.../Http/UriReplacement/MeUrlReplacement.cs | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
index 14524d3b..7f7c3abc 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
@@ -1,3 +1,5 @@
+using System;
+
namespace Microsoft.Graph.Cli.Core.Http.UriReplacement;
///
@@ -24,16 +26,7 @@ public struct MeUriReplacement : IUriReplacement
return original;
}
- Span toMatch = stackalloc char[9];
- toMatch[0] = '/';
- toMatch[1] = 'u';
- toMatch[2] = 's';
- toMatch[3] = 'e';
- toMatch[4] = 'r';
- toMatch[5] = 's';
- toMatch[6] = '/';
- toMatch[7] = 'm';
- toMatch[8] = 'e';
+ Span toMatch = stackalloc char[] { '/', 'u', 's', 'e', 'r', 's', '/', 'm', 'e' };
var separator = toMatch[..1];
var matchUsers = toMatch[1..6];
var matchMe = toMatch[7..];
From d0eefa2d0058e2685763499a0f2a852d49b94d4c Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Thu, 2 Nov 2023 02:52:40 +0300
Subject: [PATCH 10/21] Update
src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
Co-authored-by: Peter Ombwa
---
.../UriReplacement/MeUriReplacementTests.cs | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
index 00d3b565..038ca53a 100644
--- a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
+++ b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
@@ -35,18 +35,15 @@ public void Returns_Original_Uri_When_No_Match_Is_Found()
Assert.Equal(uri, replacement.Replace(uri));
}
- [Fact]
- public void Returns_A_New_Url_When_A_Match_Is_Found()
+ [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 MeUriReplacement();
- var uri = new Uri("http://example.com/v1.0/users/me/messages");
- Assert.Equal("http://example.com/v1.0/me/messages", replacement.Replace(uri)!.ToString());
-
- uri = new Uri("http://example.com/v1.0/users/me");
- Assert.Equal("http://example.com/v1.0/me", replacement.Replace(uri)!.ToString());
-
- uri = new Uri("http://example.com/v1.0/users/me?a=b");
- Assert.Equal("http://example.com/v1.0/me?a=b", replacement.Replace(uri)!.ToString());
+ var uri = new Uri(inputUri);
+ Assert.Equal(expectedUri, replacement.Replace(uri)!.ToString());
}
}
From 51d1fa1d34d074dee84fa9c2b1f3f94a02f27e83 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Thu, 2 Nov 2023 02:53:02 +0300
Subject: [PATCH 11/21] Update
src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
Co-authored-by: Peter Ombwa
---
.../UriReplacement/MeUriReplacementTests.cs | 23 +++++++------------
1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
index 038ca53a..b3e90c77 100644
--- a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
+++ b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
@@ -14,25 +14,18 @@ public void Returns_Null_When_Given_A_Null_Url()
Assert.Null(replacement.Replace(null));
}
- [Fact]
- public void Returns_Original_Uri_When_No_Match_Is_Found()
+ [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("http://example.com/test");
+ var uri = new Uri(inputUri);
var replacement = new MeUriReplacement();
Assert.Equal(uri, replacement.Replace(uri));
-
- uri = new Uri("http://example.com/users/messages");
- Assert.Equal(uri, replacement.Replace(uri));
-
- uri = new Uri("http://example.com/v1.0/users/messages");
- Assert.Equal(uri, replacement.Replace(uri));
-
- uri = new Uri("http://example.com/users/test/me");
- Assert.Equal(uri, replacement.Replace(uri));
-
- uri = new Uri("http://example.com/a/b/users/test/me");
- Assert.Equal(uri, replacement.Replace(uri));
}
[Theory]
From 702e488a593e4ac764d04664e183e70f6d4768a9 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Thu, 2 Nov 2023 20:47:34 +0300
Subject: [PATCH 12/21] Update MeUriReplacementOption
---
...ests.cs => MeUriReplacementOptionTests.cs} | 8 +++----
...placement.cs => MeUriReplacementOption.cs} | 22 +++++++++++++++++--
.../IO/GraphCliClientFactory.cs | 4 +++-
.../Microsoft.Graph.Cli.Core.csproj | 4 ++--
4 files changed, 29 insertions(+), 9 deletions(-)
rename src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/{MeUriReplacementTests.cs => MeUriReplacementOptionTests.cs} (87%)
rename src/Microsoft.Graph.Cli.Core/Http/UriReplacement/{MeUrlReplacement.cs => MeUriReplacementOption.cs} (80%)
diff --git a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementOptionTests.cs
similarity index 87%
rename from src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
rename to src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementOptionTests.cs
index 00d3b565..0c3b4ff1 100644
--- a/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementTests.cs
+++ b/src/Microsoft.Graph.Cli.Core.Tests/Http/UriReplacement/MeUriReplacementOptionTests.cs
@@ -4,12 +4,12 @@
namespace Microsoft.Graph.Cli.Core.Tests.Http.UriReplacement;
-public class MeUriReplacementTests
+public class MeUriReplacementOptionTests
{
[Fact]
public void Returns_Null_When_Given_A_Null_Url()
{
- var replacement = new MeUriReplacement();
+ var replacement = new MeUriReplacementOption();
Assert.Null(replacement.Replace(null));
}
@@ -18,7 +18,7 @@ public void Returns_Null_When_Given_A_Null_Url()
public void Returns_Original_Uri_When_No_Match_Is_Found()
{
var uri = new Uri("http://example.com/test");
- var replacement = new MeUriReplacement();
+ var replacement = new MeUriReplacementOption();
Assert.Equal(uri, replacement.Replace(uri));
@@ -38,7 +38,7 @@ public void Returns_Original_Uri_When_No_Match_Is_Found()
[Fact]
public void Returns_A_New_Url_When_A_Match_Is_Found()
{
- var replacement = new MeUriReplacement();
+ var replacement = new MeUriReplacementOption();
var uri = new Uri("http://example.com/v1.0/users/me/messages");
Assert.Equal("http://example.com/v1.0/me/messages", replacement.Replace(uri)!.ToString());
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
similarity index 80%
rename from src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
rename to src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
index 7f7c3abc..e50d50bd 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUrlReplacement.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
@@ -1,12 +1,30 @@
using System;
+using Microsoft.Kiota.Http.HttpClientLibrary.Middleware.Options;
namespace Microsoft.Graph.Cli.Core.Http.UriReplacement;
///
/// Specialized replacement for /[version]/users/me with /[version]/me
///
-public struct MeUriReplacement : IUriReplacement
+public readonly struct MeUriReplacementOption : IUriReplacementHandlerOption
{
+ private readonly bool isEnabled;
+
+ ///
+ /// Create new MeUriReplacement
+ ///
+ ///
+ public MeUriReplacementOption(bool isEnabled = true)
+ {
+ this.isEnabled = isEnabled;
+ }
+
+ ///
+ public readonly bool IsEnabled()
+ {
+ return isEnabled;
+ }
+
///
/// If a URI path starts with /[version]/users/me, replace it with /[version]/me
///
@@ -20,7 +38,7 @@ public struct MeUriReplacement : IUriReplacement
return null;
}
- if (original.Segments.Length < 4)
+ if (!isEnabled || original.Segments.Length < 4)
{
// Must have at least segments "/", "[version]/", "users/", "me"
return original;
diff --git a/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs b/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
index cd3e0387..2a1d3cff 100644
--- a/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
+++ b/src/Microsoft.Graph.Cli.Core/IO/GraphCliClientFactory.cs
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.Graph.Cli.Core.Http;
+using Microsoft.Graph.Cli.Core.Http.UriReplacement;
+using Microsoft.Kiota.Http.HttpClientLibrary.Middleware;
namespace Microsoft.Graph.Cli.Core.IO;
@@ -39,7 +41,7 @@ public static HttpClient GetDefaultClient(GraphClientOptions? options = null, st
m.AddRange(middlewares);
// Add replacement handler for /users/me to /me
- m.Add(new UriReplacementHandler(new MeUriReplacement()));
+ m.Add(new UriReplacementHandler(new MeUriReplacementOption()));
// Add logging handler.
if (loggingHandler is { } lh)
diff --git a/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj b/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
index 478a919d..7dc12f56 100644
--- a/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
+++ b/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
@@ -44,8 +44,8 @@
-
-
+
+
From 35338c340c885644f552a62e08835a24236e096e Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Thu, 2 Nov 2023 21:01:25 +0300
Subject: [PATCH 13/21] Update MeUriReplacement to use kiota http handler
---
.../Http/UriReplacement/MeUriReplacementOption.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
index e50d50bd..eb69ed3d 100644
--- a/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
+++ b/src/Microsoft.Graph.Cli.Core/Http/UriReplacement/MeUriReplacementOption.cs
@@ -6,21 +6,21 @@ namespace Microsoft.Graph.Cli.Core.Http.UriReplacement;
///
/// Specialized replacement for /[version]/users/me with /[version]/me
///
-public readonly struct MeUriReplacementOption : IUriReplacementHandlerOption
+public class MeUriReplacementOption : IUriReplacementHandlerOption
{
private readonly bool isEnabled;
///
- /// Create new MeUriReplacement
+ /// Create new MeUriReplacementOption
///
- ///
+ /// Whether the uri replacement is enabled.
public MeUriReplacementOption(bool isEnabled = true)
{
this.isEnabled = isEnabled;
}
///
- public readonly bool IsEnabled()
+ public bool IsEnabled()
{
return isEnabled;
}
@@ -31,7 +31,7 @@ public readonly bool IsEnabled()
/// The original URI
/// A URI with /[version]/users/me replaced with /[version]/me
/// This method assumes that the first segment after the root is a version segment to match Microsoft Graph API's format.
- public readonly Uri? Replace(Uri? original)
+ public Uri? Replace(Uri? original)
{
if (original is null)
{
From 90a2d00c137f841627f37fa701adea40d2c9ed4e Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Thu, 2 Nov 2023 22:21:30 +0300
Subject: [PATCH 14/21] Update sonarcloud
---
.github/workflows/sonarcloud.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index 79a5b9b3..f671e5cf 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -71,8 +71,8 @@ jobs:
CoverletOutputFormat: 'opencover' # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682
shell: pwsh
run: |
- ./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoft_kiota-cli-commons" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
+ ./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoft_graph-cli-core" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
dotnet workload restore
dotnet build
- dotnet test Microsoft.Kiota.Cli.Commons.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
+ 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 }}"
From c780b78a6b44a2e05063db1ec747d0896b81b254 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Fri, 3 Nov 2023 03:26:42 +0300
Subject: [PATCH 15/21] Update .github/workflows/sonarcloud.yml
Co-authored-by: Peter Ombwa
---
.github/workflows/sonarcloud.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index f671e5cf..069cf02c 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -71,7 +71,7 @@ jobs:
CoverletOutputFormat: 'opencover' # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682
shell: pwsh
run: |
- ./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoft_graph-cli-core" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
+ ./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoftgraph_msgraph-cli-core" /o:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
dotnet workload restore
dotnet build
dotnet test msgraph-cli-core.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
From 35d0ce06498bdcd8ffce4f0eb7866308d2069c51 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Fri, 3 Nov 2023 03:35:49 +0300
Subject: [PATCH 16/21] Update sonar org.
---
.github/workflows/sonarcloud.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index 069cf02c..accf14f2 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -71,7 +71,7 @@ jobs:
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:"microsoft" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
+ ./.sonar/scanner/dotnet-sonarscanner begin /k:"microsoftgraph_msgraph-cli-core" /o:"microsoftgraph" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
dotnet workload restore
dotnet build
dotnet test msgraph-cli-core.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
From 08cf7e9646e4e30f139a6ccba2668837a02dc345 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Fri, 3 Nov 2023 18:20:58 +0300
Subject: [PATCH 17/21] Update sonarcloud org name
---
.github/workflows/sonarcloud.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index accf14f2..07438f09 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -71,7 +71,7 @@ jobs:
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:"microsoftgraph" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="**/*.Tests/**/coverage.opencover.xml"
+ ./.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"
dotnet workload restore
dotnet build
dotnet test msgraph-cli-core.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
From f0a533f939c33b2cfa9b94099040d24df3972033 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Fri, 3 Nov 2023 18:58:15 +0300
Subject: [PATCH 18/21] Fix code smell
---
src/sample/Program.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/sample/Program.cs b/src/sample/Program.cs
index 23ec893b..8d741376 100644
--- a/src/sample/Program.cs
+++ b/src/sample/Program.cs
@@ -46,7 +46,7 @@ static async Task Main(string[] args)
// Replace `me ...` with `users ... --user-id me`
if (args[0] == "me")
{
- var hasHelp = args.Any(static x => x == "--help" || x == "-h" || x == "/?");
+ var hasHelp = Array.Exists(args, static x => x == "--help" || x == "-h" || x == "/?");
var newArgs = hasHelp ? args : new string[args.Length + 2];
newArgs[0] = "users";
for (var i = 1; i < args.Length; i++)
From ecb667ba4666b130ea1797a513e8766b8d0c92bd Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Mon, 6 Nov 2023 11:09:09 +0300
Subject: [PATCH 19/21] Add coverlet msbuild for coverage reporting
---
.../Microsoft.Graph.Cli.Core.Tests.csproj | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/src/Microsoft.Graph.Cli.Core.Tests/Microsoft.Graph.Cli.Core.Tests.csproj b/src/Microsoft.Graph.Cli.Core.Tests/Microsoft.Graph.Cli.Core.Tests.csproj
index f0f2f0dd..4a01a512 100644
--- a/src/Microsoft.Graph.Cli.Core.Tests/Microsoft.Graph.Cli.Core.Tests.csproj
+++ b/src/Microsoft.Graph.Cli.Core.Tests/Microsoft.Graph.Cli.Core.Tests.csproj
@@ -19,14 +19,11 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
+
-
\ No newline at end of file
+
From 852b0b7e61660c9aaaa7ae4c4bd5525e72d61337 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Mon, 6 Nov 2023 11:39:55 +0300
Subject: [PATCH 20/21] Exclude sample project from sonarcloud exclusions.
---
.github/workflows/sonarcloud.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index 07438f09..f76ff9bd 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -71,7 +71,7 @@ jobs:
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"
+ ./.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
From e147e822666653792ee1e8f83aabf23a9b1bc065 Mon Sep 17 00:00:00 2001
From: Caleb Kiage <747955+calebkiage@users.noreply.github.com>
Date: Mon, 6 Nov 2023 12:58:47 +0300
Subject: [PATCH 21/21] Add a me alias to users to show in help
---
src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj | 2 +-
src/sample/Program.cs | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj b/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
index 7dc12f56..1c302bf9 100644
--- a/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
+++ b/src/Microsoft.Graph.Cli.Core/Microsoft.Graph.Cli.Core.csproj
@@ -25,7 +25,7 @@
../35MSSharedLib1024.snk
false
false
- true
+ false
true
diff --git a/src/sample/Program.cs b/src/sample/Program.cs
index 8d741376..412b4f56 100644
--- a/src/sample/Program.cs
+++ b/src/sample/Program.cs
@@ -146,6 +146,11 @@ static CommandLineBuilder BuildCommandLine()
rootCommand.Add(new LoginCommand(builder));
rootCommand.AddGlobalOption(debugOption);
+ if (rootCommand.Subcommands.FirstOrDefault(static c => c.Name == "users") is {} usersCmd)
+ {
+ usersCmd.AddAlias("me");
+ }
+
return builder;
}