From 7b245b90995482415f367b8896da0ba7653d48f4 Mon Sep 17 00:00:00 2001 From: "gitauto-ai[bot]" <161652217+gitauto-ai[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 17:28:10 +0100 Subject: [PATCH] GitAuto: [FEATURE] Implement JIRA Ticket Number Extraction from Branch Name (#64) * Update Src/AiCommitMessage/Utilities/JiraTicketExtractor.cs. * Update Tests/AiCommitMessage.Tests/Utilities/JiraTicketExtractorTests.cs. * type - add Jira ticket extraction functionality and tests. * refactor - Improve code comments in BranchNameUtility.cs. * type - refactor code for improved string case handling. --------- Co-authored-by: gitauto-ai[bot] <161652217+gitauto-ai[bot]@users.noreply.github.com> Co-authored-by: gstraccini[bot] <150967461+gstraccini[bot]@users.noreply.github.com> Co-authored-by: Guilherme Branco Stracini --- .../Services/GenerateCommitMessageService.cs | 10 ++++- .../Utility/BranchNameUtility.cs | 39 ++++++++++++++++++- .../Utility/BranchNameUtilityTests.cs | 34 ++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Src/AiCommitMessage/Services/GenerateCommitMessageService.cs b/Src/AiCommitMessage/Services/GenerateCommitMessageService.cs index c47f389b..e49d0748 100644 --- a/Src/AiCommitMessage/Services/GenerateCommitMessageService.cs +++ b/Src/AiCommitMessage/Services/GenerateCommitMessageService.cs @@ -63,11 +63,19 @@ public string GenerateCommitMessage(GenerateCommitMessageOptions options) if (provider == GitProvider.GitHub) { var issueNumber = BranchNameUtility.ExtractIssueNumber(options.Branch); - if (!string.IsNullOrEmpty(issueNumber)) + if (!string.IsNullOrWhiteSpace(issueNumber)) { text = $"#{issueNumber} {text}"; } } + else + { + var jiraTicketNumber = BranchNameUtility.ExtractJiraTicket(options.Branch); + if (!string.IsNullOrWhiteSpace(jiraTicketNumber)) + { + text = $"[{jiraTicketNumber}] {text}"; + } + } if (!options.Debug) { diff --git a/Src/AiCommitMessage/Utility/BranchNameUtility.cs b/Src/AiCommitMessage/Utility/BranchNameUtility.cs index 90837050..f14290f3 100644 --- a/Src/AiCommitMessage/Utility/BranchNameUtility.cs +++ b/Src/AiCommitMessage/Utility/BranchNameUtility.cs @@ -2,9 +2,20 @@ namespace AiCommitMessage.Utility; +/// +/// Class BranchNameUtility. +/// public static class BranchNameUtility { - private const string Pattern = @"(?:issue)?[-/]?(\d+)"; + /// + /// The GitHub issue pattern. + /// + private const string GitHubIssuePattern = @"(?:issue)?[-/]?(\d+)"; + + /// + /// The Jira ticket pattern. + /// + private const string JiraTicketPattern = @"(?i)([A-Z]+)-?(\d+)"; /// /// Extracts the GitHub issue number from a branch name. @@ -15,11 +26,35 @@ public static string ExtractIssueNumber(string branchName) { var match = Regex.Match( branchName, - Pattern, + GitHubIssuePattern, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase, TimeSpan.FromSeconds(5) ); return match.Success ? match.Groups[1].Value : string.Empty; } + + /// + /// Extracts the JIRA ticket number from a given branch name. + /// + /// The branch name to extract the JIRA ticket from. + /// The extracted JIRA ticket number in uppercase, or an empty string if not found. + public static string ExtractJiraTicket(string branchName) + { + var match = Regex.Match( + branchName, + JiraTicketPattern, + RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase, + TimeSpan.FromSeconds(5) + ); + + if (!match.Success) + { + return string.Empty; + } + + var projectKey = match.Groups[1].Value.ToUpperInvariant(); + var issueNumber = match.Groups[2].Value; + return $"{projectKey}-{issueNumber}"; + } } diff --git a/Tests/AiCommitMessage.Tests/Utility/BranchNameUtilityTests.cs b/Tests/AiCommitMessage.Tests/Utility/BranchNameUtilityTests.cs index dfa07065..3cc99a2d 100644 --- a/Tests/AiCommitMessage.Tests/Utility/BranchNameUtilityTests.cs +++ b/Tests/AiCommitMessage.Tests/Utility/BranchNameUtilityTests.cs @@ -37,4 +37,38 @@ public void ExtractIssueNumber_ShouldReturnEmptyString(string branchName) // Assert result.Should().BeEmpty(); } + + [Theory] + [InlineData("feature/XPTO-1234-some-branch-name_with_description", "XPTO-1234")] + [InlineData("feature/XPTO1234-some-branch-name_with_description", "XPTO-1234")] + [InlineData("XPTO1234-some-branch-name_with_description", "XPTO-1234")] + [InlineData("XPTO-1234-some-branch-name_with_description", "XPTO-1234")] + [InlineData("bugfix/XPTO-1234--some-branch-name_with_description", "XPTO-1234")] + [InlineData("hotfix/xpto-1234-some-branch-name", "XPTO-1234")] + [InlineData("release/XPTO1234", "XPTO-1234")] + [InlineData("XPTO-1234", "XPTO-1234")] + [InlineData("xpto1234", "XPTO-1234")] + public void ExtractJiraTicket_ShouldReturnExpectedResult( + string branchName, + string expectedTicket + ) + { + // Act + var result = BranchNameUtility.ExtractJiraTicket(branchName); + + // Assert + result.Should().NotBeEmpty(); + result.Should().Be(expectedTicket); + } + + [Theory] + [InlineData("chore/no-ticket-branch")] + public void ExtractJiraTicket_ShouldReturnEmptyString(string branchName) + { + // Act + var result = BranchNameUtility.ExtractJiraTicket(branchName); + + // Assert + result.Should().BeEmpty(); + } }