From a8b8cb8beb80d1b70e6835c12a2e459cebc11f42 Mon Sep 17 00:00:00 2001 From: John Korsnes Date: Sun, 16 Feb 2025 16:57:40 +0100 Subject: [PATCH] .NET 9 - Upgrade build scripts - Deprecate .NET 7 - Formatting +semver:major --- .github/workflows/ci.yml | 6 +- .github/workflows/prerelease.yml | 4 +- .github/workflows/release.yml | 4 +- .gitignore | 2 + Dockerfile | 2 +- build.cake | 57 ------ source/.editorconfig | 162 ++++++++++++++++++ source/dotnet-pr.tests/ToolTests.cs | 24 +-- source/dotnet-pr.tests/dotnet-pr.tests.csproj | 35 ++-- source/dotnet-pr/AppOptions.cs | 8 +- source/dotnet-pr/Application.cs | 17 +- source/dotnet-pr/Browser.cs | 2 +- source/dotnet-pr/GitContext.cs | 6 +- source/dotnet-pr/GitRepositoryLocator.cs | 13 +- source/dotnet-pr/PRTools/AzureDevOps.cs | 3 +- source/dotnet-pr/PRTools/AzureDevOpsBase.cs | 2 +- .../dotnet-pr/PRTools/AzureDevOpsPrivate.cs | 5 +- source/dotnet-pr/PRTools/BitBucketOrg.cs | 9 +- .../dotnet-pr/PRTools/BitBucketSelfHosted.cs | 29 ++-- source/dotnet-pr/PRTools/GitHub.cs | 11 +- source/dotnet-pr/PRTools/Gitlab.cs | 14 +- source/dotnet-pr/Program.cs | 18 +- source/dotnet-pr/dotnet-pr.csproj | 29 ++-- source/source.sln | 1 + source/source.sln.DotSettings.user | 7 +- 25 files changed, 293 insertions(+), 177 deletions(-) delete mode 100644 build.cake create mode 100644 source/.editorconfig diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 042ff71..368aa07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.0.x" + dotnet-version: "9.0.x" - name: Test run: dotnet test source/dotnet-pr.tests --logger "GitHubActions;report-warnings=false" - name: Run tool in docker diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 7094d2b..dfe1107 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -12,9 +12,9 @@ jobs: with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - run: echo "ACTIONS_ALLOW_UNSECURE_COMMANDS=true" >> $GITHUB_ENV - name: Install GitVersion uses: gittools/actions/gitversion/setup@v0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 372cc63..db90e51 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,9 +12,9 @@ jobs: with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - run: echo "ACTIONS_ALLOW_UNSECURE_COMMANDS=true" >> $GITHUB_ENV - name: Install GitVersion uses: gittools/actions/gitversion/setup@v0.9.7 diff --git a/.gitignore b/.gitignore index 3e759b7..4e2a6af 100644 --- a/.gitignore +++ b/.gitignore @@ -328,3 +328,5 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ + +.DS_Store diff --git a/Dockerfile b/Dockerfile index 0eb67be..995b071 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build-env WORKDIR / COPY ./ ./therepo diff --git a/build.cake b/build.cake deleted file mode 100644 index a491a23..0000000 --- a/build.cake +++ /dev/null @@ -1,57 +0,0 @@ -var target = Argument("target", "Pack"); -var project = "dotnet-pr"; -var version = GetBuildVersion("2.0.0"); -var outputDir = $"./builds/{project}"; - -Task("Test") - .Does(() => { - var settings = new DotNetCoreTestSettings - { - Configuration = "Release", - ArgumentCustomization = args=>args.Append($"--logger console;verbosity=detailed") - }; - DotNetCoreTest("./source/dotnet-pr.tests/dotnet-pr.tests.csproj", settings); -}); - -Task("Pack") - .IsDependentOn("Test") - .Does(() => { - var publishSettings = new DotNetCorePackSettings{ - OutputDirectory = outputDir, - Configuration = "Release" - }; - - publishSettings.MSBuildSettings = new DotNetCoreMSBuildSettings() - .WithProperty("Version", new[] { version }); - - DotNetCorePack($"./source/{project}/{project}.csproj", publishSettings); -}); - -Task("Publish") - .IsDependentOn("Pack") - .Does(() => { - var settings = new DotNetCoreNuGetPushSettings - { - Source = "https://api.nuget.org/v3/index.json", - ApiKey = EnvironmentVariable("NUGET_API_KEY") - }; - - DotNetCoreNuGetPush($"{outputDir}/{project}.{version}.nupkg", settings); -}); - -private string GetBuildVersion(string productVersion) -{ - var now = DateTime.Now.ToString("yyyyMMddHHmmss"); - var shipit = Argument("shipit", "0") != "0"; - - if(shipit) - { - return $"{productVersion}"; - } - else - { - return $"{productVersion}-beta{now}"; - } -} - -RunTarget(target); diff --git a/source/.editorconfig b/source/.editorconfig new file mode 100644 index 0000000..5c801f2 --- /dev/null +++ b/source/.editorconfig @@ -0,0 +1,162 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +[*] +charset = utf-8 +insert_final_newline = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +insert_final_newline = true +trim_trailing_whitespace = true + + +#### .NET Coding Conventions #### + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:warning +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_property = false:warning + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning + +# Expression-level preferences +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:suggestion + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = true:silent +csharp_style_var_for_built_in_types = true:silent +csharp_style_var_when_type_is_apparent = true:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async + +# Code-block preferences +csharp_prefer_braces = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# C# 10 +csharp_style_namespace_declarations = file_scoped:error +csharp_style_prefer_primary_constructors = true +dotnet_diagnostic.IDE0290.severity = error + + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + + +[*.csproj] +indent_size = 2 +indent_style = space +tab_width = 2 diff --git a/source/dotnet-pr.tests/ToolTests.cs b/source/dotnet-pr.tests/ToolTests.cs index a3438aa..c18bb74 100644 --- a/source/dotnet-pr.tests/ToolTests.cs +++ b/source/dotnet-pr.tests/ToolTests.cs @@ -1,19 +1,11 @@ using PR; using PR.PRTools; using Xunit; -using Xunit.Abstractions; namespace dotnet_pr.tests; -public class ToolTests +public class ToolTests(ITestOutputHelper testOutputHelper) { - private readonly ITestOutputHelper _testOutputHelper; - - public ToolTests(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - } - private void TestAzureDevops(string remoteUrl, string expectedUrl, IPRTool tool) { var org = "someorg"; @@ -23,16 +15,14 @@ private void TestAzureDevops(string remoteUrl, string expectedUrl, IPRTool tool) var context = new GitContext { - RemoteUrl = remoteUrlFormatted, - SourceBranch = "feature", - TargetBranch = "master" + RemoteUrl = remoteUrlFormatted, SourceBranch = "feature", TargetBranch = "master" }; Assert.True(tool.IsMatch(remoteUrlFormatted)); var prUrl = tool.BuildUrl(context); - _testOutputHelper.WriteLine($"{remoteUrlFormatted} => {prUrl}"); + testOutputHelper.WriteLine($"{remoteUrlFormatted} => {prUrl}"); Assert.Equal(expectedUrl, prUrl); } @@ -42,7 +32,9 @@ private void TestAzureDevops(string remoteUrl, string expectedUrl, IPRTool tool) [InlineData("https://{0}@dev.azure.com/{0}/{1}/_git/{2}")] public void AzureDevOpsPublicTests(string remoteUrl) { - TestAzureDevops(remoteUrl, "https://dev.azure.com/someorg/someproj/_git/somerepo/pullrequestcreate?targetRef=master&sourceRef=feature", new AzureDevOps()); + TestAzureDevops(remoteUrl, + "https://dev.azure.com/someorg/someproj/_git/somerepo/pullrequestcreate?targetRef=master&sourceRef=feature", + new AzureDevOps()); } [Theory] @@ -50,6 +42,8 @@ public void AzureDevOpsPublicTests(string remoteUrl) [InlineData("{0}@vs-ssh.visualstudio.com:v3/{0}/{1}/{2}")] public void AzureDevOpsPrivateTests(string remoteUrl) { - TestAzureDevops(remoteUrl, "https://someorg.visualstudio.com/someproj/_git/somerepo/pullrequestcreate?targetRef=master&sourceRef=feature", new AzureDevOpsPrivate()); + TestAzureDevops(remoteUrl, + "https://someorg.visualstudio.com/someproj/_git/somerepo/pullrequestcreate?targetRef=master&sourceRef=feature", + new AzureDevOpsPrivate()); } } diff --git a/source/dotnet-pr.tests/dotnet-pr.tests.csproj b/source/dotnet-pr.tests/dotnet-pr.tests.csproj index 4f22901..28c0e66 100644 --- a/source/dotnet-pr.tests/dotnet-pr.tests.csproj +++ b/source/dotnet-pr.tests/dotnet-pr.tests.csproj @@ -1,21 +1,26 @@ - - net8.0;net7.0 - dotnet_pr.tests - enable - false - + + net8.0;net9.0 + Exe + dotnet_pr.tests + enable + enable + false + true + true + - - - - - - + + + + + + + - - - + + + diff --git a/source/dotnet-pr/AppOptions.cs b/source/dotnet-pr/AppOptions.cs index 8a1623e..782709e 100644 --- a/source/dotnet-pr/AppOptions.cs +++ b/source/dotnet-pr/AppOptions.cs @@ -2,7 +2,7 @@ namespace PR; internal class AppOptions { - public bool EnableDebug { get; set; } - - public string TargetBranch { get; set; } -} \ No newline at end of file + public bool EnableDebug { get; init; } + + public required string TargetBranch { get; init; } +} diff --git a/source/dotnet-pr/Application.cs b/source/dotnet-pr/Application.cs index 98fdf33..3d060f4 100644 --- a/source/dotnet-pr/Application.cs +++ b/source/dotnet-pr/Application.cs @@ -3,11 +3,13 @@ namespace PR; -internal class Application(GitRepositoryLocator repositoryLocator, +internal class Application( + GitRepositoryLocator repositoryLocator, GitRemoteGuesser remoteGuesser, IEnumerable tools, AppOptions options, - Browser browser, ILoggerFactory logFactory) + Browser browser, + ILoggerFactory logFactory) { public void OpenToolInBrowser() { @@ -17,7 +19,7 @@ public void OpenToolInBrowser() { var logger = logFactory.CreateLogger(s.GetType()); var isMatch = s.IsMatch(remote.Url); - logger.LogDebug(isMatch ? $"Match" : "No match"); + logger.LogDebug(isMatch ? "Match" : "No match"); return isMatch; }); @@ -26,16 +28,15 @@ public void OpenToolInBrowser() var supportedList = tools .OrderBy(t => t.GetType().Name) .Select(c => $"\n* {c.GetType().Name.ToString()}") - .Aggregate((x,y) => x + y); + .Aggregate((x, y) => x + y); - throw new ApplicationException($"Unknown PR tool. Could not open PR for the `{remote.Name}` remote. \nSupported tools : {supportedList}"); + throw new ApplicationException( + $"Unknown PR tool. Could not open PR for the `{remote.Name}` remote. \nSupported tools : {supportedList}"); } var prUrl = prTool.BuildUrl(new GitContext { - RemoteUrl = remote.Url, - SourceBranch = repo.Head.FriendlyName, - TargetBranch = options.TargetBranch + RemoteUrl = remote.Url, SourceBranch = repo.Head.FriendlyName, TargetBranch = options.TargetBranch }); browser.Open(prUrl); diff --git a/source/dotnet-pr/Browser.cs b/source/dotnet-pr/Browser.cs index 5a0a67e..ed1f5e0 100644 --- a/source/dotnet-pr/Browser.cs +++ b/source/dotnet-pr/Browser.cs @@ -36,7 +36,7 @@ private static void OpenBrowserAt(string url) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { url = url.Replace("&", "^&"); - Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") {CreateNoWindow = true}); + Process.Start(new ProcessStartInfo("cmd", $"/c start {url}") { CreateNoWindow = true }); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { diff --git a/source/dotnet-pr/GitContext.cs b/source/dotnet-pr/GitContext.cs index 2403889..8c1b077 100644 --- a/source/dotnet-pr/GitContext.cs +++ b/source/dotnet-pr/GitContext.cs @@ -2,7 +2,7 @@ namespace PR; public class GitContext { - public string RemoteUrl { get; set; } - public string SourceBranch { get; set; } - public string TargetBranch { get; set; } + public required string RemoteUrl { get; init; } + public required string SourceBranch { get; init; } + public required string TargetBranch { get; init; } } diff --git a/source/dotnet-pr/GitRepositoryLocator.cs b/source/dotnet-pr/GitRepositoryLocator.cs index 5861b2a..305884c 100644 --- a/source/dotnet-pr/GitRepositoryLocator.cs +++ b/source/dotnet-pr/GitRepositoryLocator.cs @@ -18,7 +18,7 @@ public Repository LocateRepository() return repository; } - private Repository LocateRepository(string currentDirectory) + private Repository? LocateRepository(string currentDirectory) { logger.LogDebug("Searching for git repo in " + currentDirectory); @@ -26,26 +26,27 @@ private Repository LocateRepository(string currentDirectory) { return new Repository(currentDirectory); } - catch(RepositoryNotFoundException) + catch (RepositoryNotFoundException) { + var currentDir = Directory.GetParent(currentDirectory); try { - if (Directory.GetParent(currentDirectory) == null) + if (currentDir == null) { return null; } - if(!Directory.GetParent(currentDirectory).Exists) + if (!currentDir.Exists) { return null; } } - catch(Exception) + catch (Exception) { return null; } - var parentDir = Directory.GetParent(currentDirectory).FullName; + var parentDir = currentDir.FullName; return LocateRepository(parentDir); } } diff --git a/source/dotnet-pr/PRTools/AzureDevOps.cs b/source/dotnet-pr/PRTools/AzureDevOps.cs index 89eca45..df8baf0 100644 --- a/source/dotnet-pr/PRTools/AzureDevOps.cs +++ b/source/dotnet-pr/PRTools/AzureDevOps.cs @@ -8,7 +8,8 @@ public class AzureDevOps : AzureDevOpsBase protected override string BuildUrl(string org, string project, string repo, GitContext gitContext) { - return $"https://dev.azure.com/{org}/{project}/_git/{repo}/pullrequestcreate?targetRef={gitContext.TargetBranch}&sourceRef={gitContext.SourceBranch}"; + return + $"https://dev.azure.com/{org}/{project}/_git/{repo}/pullrequestcreate?targetRef={gitContext.TargetBranch}&sourceRef={gitContext.SourceBranch}"; } protected override string GetOrganizationHttp(string gitRemoteUrl) diff --git a/source/dotnet-pr/PRTools/AzureDevOpsBase.cs b/source/dotnet-pr/PRTools/AzureDevOpsBase.cs index bfb70ac..e116834 100644 --- a/source/dotnet-pr/PRTools/AzureDevOpsBase.cs +++ b/source/dotnet-pr/PRTools/AzureDevOpsBase.cs @@ -70,4 +70,4 @@ private string GetRepo(string gitRemoteUrl) var repo = gitUrl.Split('/')[3].Replace(".git", ""); return repo; } -} \ No newline at end of file +} diff --git a/source/dotnet-pr/PRTools/AzureDevOpsPrivate.cs b/source/dotnet-pr/PRTools/AzureDevOpsPrivate.cs index e032a5f..a15e47d 100644 --- a/source/dotnet-pr/PRTools/AzureDevOpsPrivate.cs +++ b/source/dotnet-pr/PRTools/AzureDevOpsPrivate.cs @@ -8,7 +8,8 @@ public class AzureDevOpsPrivate : AzureDevOpsBase protected override string BuildUrl(string org, string project, string repo, GitContext gitContext) { - return $"https://{org}.visualstudio.com/{project}/_git/{repo}/pullrequestcreate?targetRef={gitContext.TargetBranch}&sourceRef={gitContext.SourceBranch}"; + return + $"https://{org}.visualstudio.com/{project}/_git/{repo}/pullrequestcreate?targetRef={gitContext.TargetBranch}&sourceRef={gitContext.SourceBranch}"; } protected override string GetOrganizationHttp(string gitRemoteUrl) @@ -20,4 +21,4 @@ protected override string GetOrganizationHttp(string gitRemoteUrl) var org = gitRemoteUrlWithoutScheme.Substring(0, orgIdx); return org; } -} \ No newline at end of file +} diff --git a/source/dotnet-pr/PRTools/BitBucketOrg.cs b/source/dotnet-pr/PRTools/BitBucketOrg.cs index 3012a20..923237b 100644 --- a/source/dotnet-pr/PRTools/BitBucketOrg.cs +++ b/source/dotnet-pr/PRTools/BitBucketOrg.cs @@ -3,8 +3,8 @@ namespace PR.PRTools; internal class BitBucketOrg : IPRTool { /// - /// https://johnkors@bitbucket.org/johnkors/dotnet-pr.git - /// git@bitbucket.org:johnkors/dotnet-pr.git + /// https://johnkors@bitbucket.org/johnkors/dotnet-pr.git + /// git@bitbucket.org:johnkors/dotnet-pr.git /// public bool IsMatch(string remoteUrl) { @@ -20,14 +20,15 @@ public string BuildUrl(GitContext gitContext) var repo = accountAndRepo.Split("/")[1].Replace(".git", ""); return PrUrl(account, repo, gitContext.SourceBranch, gitContext.TargetBranch); } + var accountAndRepoSsh = gitContext.RemoteUrl.Split("bitbucket.org:")[1]; var accountSsh = accountAndRepoSsh.Split("/")[0]; var repoSsh = accountAndRepoSsh.Split("/")[1].Replace(".git", ""); return PrUrl(accountSsh, repoSsh, gitContext.SourceBranch, gitContext.TargetBranch); } - + private static string PrUrl(string account, string repo, string sourceBranch, string target) { return $"https://bitbucket.org/{account}/{repo}/pull-requests/new?source={sourceBranch}&dest={target}&t=1"; } -} \ No newline at end of file +} diff --git a/source/dotnet-pr/PRTools/BitBucketSelfHosted.cs b/source/dotnet-pr/PRTools/BitBucketSelfHosted.cs index 70b94f2..5f4b224 100644 --- a/source/dotnet-pr/PRTools/BitBucketSelfHosted.cs +++ b/source/dotnet-pr/PRTools/BitBucketSelfHosted.cs @@ -3,8 +3,8 @@ namespace PR.PRTools; internal class BitBucketSelfHosted : IPRTool { /// - /// http://bitbucket/scm/do/cmdline-utilities.git/ - /// ssh://git@bitbucket:7999/do/cmdline-utilities.git + /// http://bitbucket/scm/do/cmdline-utilities.git/ + /// ssh://git@bitbucket:7999/do/cmdline-utilities.git /// public bool IsMatch(string remoteUrl) { @@ -18,33 +18,40 @@ public string BuildUrl(GitContext gitContext) var uri = new Uri(gitContext.RemoteUrl); if (uri.Scheme == "ssh") { - return PrUrl(gitContext.SourceBranch, uri, ParseProjectFromSSHUri, ParseRepoFromSSHUri, gitContext.TargetBranch); + return PrUrl(gitContext.SourceBranch, uri, ParseProjectFromSSHUri, ParseRepoFromSSHUri, + gitContext.TargetBranch); } - return PrUrl(gitContext.SourceBranch, uri, ParseProjectFromHttpUri, ParseRepoFromHttpUri, gitContext.TargetBranch); + + return PrUrl(gitContext.SourceBranch, uri, ParseProjectFromHttpUri, ParseRepoFromHttpUri, + gitContext.TargetBranch); } - private static string PrUrl(string branch, Uri uri, Func ProjectFetcher, Func RepoFetcher, string targetBranch) + private static string PrUrl(string branch, Uri uri, Func ProjectFetcher, Func RepoFetcher, + string targetBranch) { - return $"http://{uri.Host}/projects/{ProjectFetcher(uri)}/repos/{RepoFetcher(uri)}/compare/diff?sourceBranch={branch}&targetBranch={targetBranch}"; + return + $"http://{uri.Host}/projects/{ProjectFetcher(uri)}/repos/{RepoFetcher(uri)}/compare/diff?sourceBranch={branch}&targetBranch={targetBranch}"; } private static string ParseRepoFromSSHUri(Uri uri) { - return uri.Segments[2].Replace(".git", "",StringComparison.InvariantCultureIgnoreCase).TrimStart('/').TrimEnd('/'); + return uri.Segments[2].Replace(".git", "", StringComparison.InvariantCultureIgnoreCase).TrimStart('/') + .TrimEnd('/'); } private static string ParseProjectFromSSHUri(Uri uri) { return uri.Segments[1].TrimStart('/').TrimEnd('/'); } - + private static string ParseProjectFromHttpUri(Uri uri) { return uri.Segments[2].TrimStart('/').TrimEnd('/'); } - + private static string ParseRepoFromHttpUri(Uri uri) { - return uri.Segments[3].Replace(".git", "",StringComparison.InvariantCultureIgnoreCase).TrimStart('/').TrimEnd('/'); + return uri.Segments[3].Replace(".git", "", StringComparison.InvariantCultureIgnoreCase).TrimStart('/') + .TrimEnd('/'); } -} \ No newline at end of file +} diff --git a/source/dotnet-pr/PRTools/GitHub.cs b/source/dotnet-pr/PRTools/GitHub.cs index ff01571..0cbcd0d 100644 --- a/source/dotnet-pr/PRTools/GitHub.cs +++ b/source/dotnet-pr/PRTools/GitHub.cs @@ -3,14 +3,14 @@ namespace PR.PRTools; internal class GitHub : IPRTool { /// - /// https://github.com/johnkors/dotnet-pr.git - /// git@github.com:johnkors/dotnet-pr.git + /// https://github.com/johnkors/dotnet-pr.git + /// git@github.com:johnkors/dotnet-pr.git /// public bool IsMatch(string remoteUrl) { return remoteUrl.Contains("github.com"); } - + public string BuildUrl(GitContext gitContext) { if (gitContext.RemoteUrl.StartsWith("http")) @@ -20,14 +20,15 @@ public string BuildUrl(GitContext gitContext) var repo = accountAndRepo.Split("/")[1].Replace(".git", ""); return PrUrl(account, repo, gitContext.TargetBranch, gitContext.SourceBranch); } + var accountAndRepoSsh = gitContext.RemoteUrl.Split("github.com:")[1]; var accountSsh = accountAndRepoSsh.Split("/")[0]; var repoSsh = accountAndRepoSsh.Split("/")[1].Replace(".git", ""); return PrUrl(accountSsh, repoSsh, gitContext.TargetBranch, gitContext.SourceBranch); } - + private static string PrUrl(string account, string repo, string targetBranch, string sourceBranch) { return $"https://github.com/{account}/{repo}/compare/{targetBranch}...{sourceBranch}"; } -} \ No newline at end of file +} diff --git a/source/dotnet-pr/PRTools/Gitlab.cs b/source/dotnet-pr/PRTools/Gitlab.cs index 907ac0b..ba7ad60 100644 --- a/source/dotnet-pr/PRTools/Gitlab.cs +++ b/source/dotnet-pr/PRTools/Gitlab.cs @@ -3,8 +3,8 @@ namespace PR.PRTools; internal class Gitlab : IPRTool { /// - /// https://gitlab.com/johnkors/dotnet-pr.git - /// git@gitlab.com:johnkors/dotnet-pr.git + /// https://gitlab.com/johnkors/dotnet-pr.git + /// git@gitlab.com:johnkors/dotnet-pr.git /// public bool IsMatch(string remoteUrl) { @@ -20,15 +20,17 @@ public string BuildUrl(GitContext gitContext) var repo = accountAndRepo.Split("/")[1].Replace(".git", ""); return PrUrl(account, repo, gitContext.SourceBranch, gitContext.TargetBranch); } + var accountAndRepoSsh = gitContext.RemoteUrl.Split("gitlab.com:")[1]; var accountSsh = accountAndRepoSsh.Split("/")[0]; var repoSsh = accountAndRepoSsh.Split("/")[1].Replace(".git", ""); - + return PrUrl(accountSsh, repoSsh, gitContext.SourceBranch, gitContext.TargetBranch); } - + private static string PrUrl(string account, string repo, string sourceBranch, object targetBranch) { - return $"https://gitlab.com/{account}/{repo}/merge_requests/new?merge_request%5Bsource_branch%5D={sourceBranch}&merge_request%5Btarget_branch%5D={targetBranch}"; + return + $"https://gitlab.com/{account}/{repo}/merge_requests/new?merge_request%5Bsource_branch%5D={sourceBranch}&merge_request%5Btarget_branch%5D={targetBranch}"; } -} \ No newline at end of file +} diff --git a/source/dotnet-pr/Program.cs b/source/dotnet-pr/Program.cs index f8eba60..fa73f6e 100644 --- a/source/dotnet-pr/Program.cs +++ b/source/dotnet-pr/Program.cs @@ -4,7 +4,7 @@ using PR.PRTools; using var serviceProvider = Bootstrap(args); -var runner = serviceProvider.GetService(); +var runner = serviceProvider.GetRequiredService(); try { @@ -12,19 +12,21 @@ } catch (ApplicationException ae) { - var logger = serviceProvider.GetService>(); + var logger = serviceProvider.GetRequiredService>(); logger.LogError($"¯\\_(ツ)_/¯ \n{ae.Message}"); } catch (Exception e) { - var logger = serviceProvider.GetService>(); + var logger = serviceProvider.GetRequiredService>(); logger.LogError($"¯\\_(ツ)_/¯ \n{e.Message}"); } +return; + ServiceProvider Bootstrap(string[] args) { var enableDebug = args.Contains("--debug"); - var targetBranch = string.Empty; + string targetBranch; if (args.Length > 0) { var restOfArgs = args.ToList(); @@ -35,11 +37,8 @@ ServiceProvider Bootstrap(string[] args) { targetBranch = "main"; } - var debugOptions = new AppOptions - { - EnableDebug = enableDebug, - TargetBranch = targetBranch - }; + + var debugOptions = new AppOptions { EnableDebug = enableDebug, TargetBranch = targetBranch }; var services = new ServiceCollection() .AddLogging(c => @@ -54,7 +53,6 @@ ServiceProvider Bootstrap(string[] args) { c.SetMinimumLevel(LogLevel.Warning); } - }) .AddSingleton(debugOptions) .AddSingleton() diff --git a/source/dotnet-pr/dotnet-pr.csproj b/source/dotnet-pr/dotnet-pr.csproj index 4503598..7ca84ce 100644 --- a/source/dotnet-pr/dotnet-pr.csproj +++ b/source/dotnet-pr/dotnet-pr.csproj @@ -1,7 +1,7 @@  Exe - net8.0;net7.0 + net8.0;net9.0 dotnet-pr pr John Korsnes @@ -15,29 +15,20 @@ icon.512x512.png readme.md git - Preview enable + enable - - + - - - - - + + + + - - - - - + + + - - - - - diff --git a/source/source.sln b/source/source.sln index a0c35df..ffe5d81 100644 --- a/source/source.sln +++ b/source/source.sln @@ -12,6 +12,7 @@ ProjectSection(SolutionItems) = preProject ..\CI.yml = ..\.github\workflows\CI.yml ..\Release.yml = ..\.github\workflows\Release.yml ..\PreRelease.yml = ..\.github\workflows\PreRelease.yml + .editorconfig = .editorconfig EndProjectSection EndProject Global diff --git a/source/source.sln.DotSettings.user b/source/source.sln.DotSettings.user index 99e3685..290e0a2 100644 --- a/source/source.sln.DotSettings.user +++ b/source/source.sln.DotSettings.user @@ -1,3 +1,8 @@  True - True \ No newline at end of file + True + <SessionState ContinuousTestingMode="0" IsActive="True" Name="ToolTests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <TestAncestor> + <TestId>xUnit::C77D5223-41F1-4B4A-BD8D-6F58877D3C4D::net8.0::dotnet_pr.tests.ToolTests</TestId> + </TestAncestor> +</SessionState> \ No newline at end of file