44using System . Linq ;
55using System . Text . RegularExpressions ;
66using System . Threading . Tasks ;
7+ using GitHubReleaseNotes . Logic . Extensions ;
78using GitHubReleaseNotes . Logic . Models ;
8- using LibGit2Sharp ;
99using Octokit ;
1010
1111namespace GitHubReleaseNotes . Logic ;
@@ -26,29 +26,31 @@ public RepositoryHelper(IConfiguration configuration)
2626 internal async Task < IEnumerable < ReleaseInfo > > GetReleaseInfoAsync ( )
2727 {
2828 var repository = new LibGit2Sharp . Repository ( _configuration . RepositoryPath ) ;
29- string origin = repository . Network . Remotes . First ( r => r . Name == "origin" ) . Url ;
30- string url = ! origin . EndsWith ( ".git" ) ? $ "{ origin } .git" : origin ;
29+ var originUrl = repository . Network . Remotes . First ( r => r . Name == "origin" ) . Url ;
30+ var gitUrl = ! originUrl . EndsWith ( ".git" ) ? $ "{ originUrl } .git" : originUrl ;
31+ var headBranchName = repository . Head . FriendlyName ;
3132
3233 Console . WriteLine ( $ "Analyzing Git Repository at '{ new FileInfo ( _configuration . RepositoryPath ) . FullName } '") ;
33- var orderedReleaseInfos = GetOrderedReleaseInfos ( repository ) ;
34+ var orderedReleaseInfos = repository . GetOrderedReleaseInfos ( _configuration . Version ) ;
3435
35- Console . WriteLine ( $ "Getting Issues and Pull Requests from '{ url } '") ;
36- var result = await GetAllIssuesAndPullRequestsAsync ( url ) . ConfigureAwait ( false ) ;
36+ Console . WriteLine ( $ "Getting Issues and Pull Requests from '{ gitUrl } '") ;
37+ var result = await GetAllIssuesAndPullRequestsAsync ( gitUrl , headBranchName ) . ConfigureAwait ( false ) ;
3738
3839 bool IssueTimeIsLessThenReleaseTime ( DateTimeOffset releaseTime , DateTimeOffset ? issueClosedTime )
3940 => issueClosedTime < releaseTime . AddSeconds ( DeltaSeconds ) ;
4041
41- bool IssueTimeIsGreaterThenPreviousReleaseTime ( int idx , DateTimeOffset ? issueClosedTime ) =>
42- idx <= 0 || issueClosedTime > orderedReleaseInfos [ idx - 1 ] . When . AddSeconds ( DeltaSeconds ) ;
42+ bool IssueTimeIsGreaterThenPreviousReleaseTime ( IReadOnlyList < ReleaseInfo > releaseInfos , int idx , DateTimeOffset ? issueClosedTime ) =>
43+ idx <= 0 || issueClosedTime > releaseInfos [ idx - 1 ] . When . AddSeconds ( DeltaSeconds ) ;
4344
44- bool IssueLinkedToRelease ( int idx , ReleaseInfo releaseInfo , DateTimeOffset ? issueClosedAtTime ) =>
45- IssueTimeIsLessThenReleaseTime ( releaseInfo . When , issueClosedAtTime ) && IssueTimeIsGreaterThenPreviousReleaseTime ( idx , issueClosedAtTime ) ;
45+ bool IssueLinkedToRelease ( IReadOnlyList < ReleaseInfo > releaseInfos , int idx , ReleaseInfo releaseInfo , DateTimeOffset ? issueClosedAtTime ) =>
46+ IssueTimeIsLessThenReleaseTime ( releaseInfo . When , issueClosedAtTime ) && IssueTimeIsGreaterThenPreviousReleaseTime ( releaseInfos , idx , issueClosedAtTime ) ;
4647
4748 // Loop all orderedReleaseInfos and add the correct Pull Requests and Issues
4849 foreach ( var x in orderedReleaseInfos . Select ( ( releaseInfo , index ) => new { index , releaseInfo } ) )
4950 {
5051 // Process only Issues
51- var issuesForThisTag = result . Issues . Where ( issue => issue . PullRequest == null && IssueLinkedToRelease ( x . index , x . releaseInfo , issue . ClosedAt ) ) ;
52+ var releaseInfos = orderedReleaseInfos ; // Fix: "Captured variable is modified in outer scope"
53+ var issuesForThisTag = result . Issues . Where ( issue => issue . PullRequest == null && IssueLinkedToRelease ( releaseInfos , x . index , x . releaseInfo , issue . ClosedAt ) ) ;
5254 var issueInfos = issuesForThisTag . Select ( issue => new IssueInfo
5355 {
5456 Number = issue . Number ,
@@ -61,7 +63,7 @@ bool IssueLinkedToRelease(int idx, ReleaseInfo releaseInfo, DateTimeOffset? issu
6163 } ) ;
6264
6365 // Process PullRequests
64- var pullsForThisTag = result . PullRequests . Where ( pullRequest => IssueLinkedToRelease ( x . index , x . releaseInfo , pullRequest . ClosedAt ) ) ;
66+ var pullsForThisTag = result . PullRequests . Where ( pullRequest => IssueLinkedToRelease ( releaseInfos , x . index , x . releaseInfo , pullRequest . ClosedAt ) ) ;
6567 var pullInfos = pullsForThisTag . Select ( pull => new IssueInfo
6668 {
6769 Number = pull . Number ,
@@ -94,50 +96,18 @@ bool ExcludeIssue(string[] labels) => _configuration.ExcludeLabels != null &&
9496 return orderedReleaseInfos . OrderByDescending ( r => r . Version ) ;
9597 }
9698
97- private List < ReleaseInfo > GetOrderedReleaseInfos ( IRepository repo )
99+ private async Task < IssuesAndPullRequestsModel > GetAllIssuesAndPullRequestsAsync ( string gitUrl , string headBranchName )
98100 {
99- var orderedReleaseInfos = repo . Tags
100-
101- // Convert Tag into ReleaseInfo
102- . Select ( tag => new ReleaseInfo
103- {
104- Version = GetVersionAsLong ( tag . FriendlyName ) ?? 0 ,
105- FriendlyName = tag . FriendlyName ,
106- When = tag . Target is LibGit2Sharp . Commit commit ? commit . Committer . When : DateTimeOffset . MinValue
107- } )
108-
109- // Skip invalid versions
110- . Where ( tag => tag . Version > 0 )
111-
112- // Order by the version
113- . OrderBy ( tag => tag . Version )
114- . ToList ( ) ;
115-
116- // Add the `next` version
117- orderedReleaseInfos . Add ( new ReleaseInfo
118- {
119- Version = long . MaxValue ,
120- FriendlyName = _configuration . Version ,
121- When = DateTimeOffset . Now
122- } ) ;
123-
124- return orderedReleaseInfos ;
125- }
126-
127- private async Task < IssuesAndPullRequestsModel > GetAllIssuesAndPullRequestsAsync ( string url )
128- {
129- GetOwnerAndProject ( url , out var owner , out var project ) ;
130-
131- var client = GitHubClientFactory . CreateClient ( _configuration , owner ) ;
101+ GetRepositorySettingsOrThrowException ( gitUrl , headBranchName , out var repositorySettings ) ;
132102
133103 //var miscellaneousRateLimit = await client.Miscellaneous.GetRateLimits();
134104 //if (miscellaneousRateLimit.Resources.Core.Remaining < 21)
135105 //{
136106 // throw new Exception($"You have only {miscellaneousRateLimit.Resources.Core.Remaining} Core Requests remaining.");
137107 //}
138108
139- var issuesTask = GetIssuesForRepositoryAsync ( client , owner , project ) ;
140- var pullRequestsTask = GetMergedPullRequestsForRepositoryAsync ( client , owner , project ) ;
109+ var issuesTask = GetIssuesForRepositoryAsync ( repositorySettings ) ;
110+ var pullRequestsTask = GetMergedPullRequestsForRepositoryAsync ( repositorySettings ) ;
141111
142112 await Task . WhenAll ( issuesTask , pullRequestsTask ) . ConfigureAwait ( false ) ;
143113
@@ -148,8 +118,10 @@ private async Task<IssuesAndPullRequestsModel> GetAllIssuesAndPullRequestsAsync(
148118 } ;
149119 }
150120
151- private static async Task < ICollection < Issue > > GetIssuesForRepositoryAsync ( IGitHubClient client , string owner , string name )
121+ private async Task < ICollection < Issue > > GetIssuesForRepositoryAsync ( RepositorySettings repositorySettings )
152122 {
123+ var client = GitHubClientFactory . CreateClient ( _configuration , repositorySettings . Owner ) ;
124+
153125 // Do a request to GitHub using Octokit.GitHubClient to get all Closed Issues (this does also include Closed and Merged Pull Requests)
154126 var closedIssuesRequest = new RepositoryIssueRequest
155127 {
@@ -158,45 +130,42 @@ private static async Task<ICollection<Issue>> GetIssuesForRepositoryAsync(IGitHu
158130 } ;
159131
160132 // Return all Closed issues
161- return ( await client . Issue . GetAllForRepository ( owner , name , closedIssuesRequest ) . ConfigureAwait ( false ) ) . OrderBy ( i => i . Id ) . ToList ( ) . AsReadOnly ( ) ;
133+ return ( await client . Issue . GetAllForRepository ( repositorySettings . Owner , repositorySettings . Name , closedIssuesRequest ) . ConfigureAwait ( false ) )
134+ . OrderBy ( i => i . Id )
135+ . ToList ( )
136+ . AsReadOnly ( ) ;
162137 }
163138
164- private static async Task < ICollection < PullRequest > > GetMergedPullRequestsForRepositoryAsync ( IGitHubClient client , string owner , string name )
139+ private async Task < ICollection < PullRequest > > GetMergedPullRequestsForRepositoryAsync ( RepositorySettings repositorySettings )
165140 {
141+ var client = GitHubClientFactory . CreateClient ( _configuration , repositorySettings . Owner ) ;
142+
166143 // Do a request to GitHub using Octokit.GitHubClient to get all Closed Pull Requests
167144 var closedPullRequestsRequest = new PullRequestRequest
168145 {
169146 //SortDirection = SortDirection.Ascending,
170- State = ItemStateFilter . Closed
147+ State = ItemStateFilter . Closed ,
148+ Base = repositorySettings . HeadBranch
171149 } ;
172150
173- // Return only Closes and Merged PullRequests
174- return ( await client . PullRequest . GetAllForRepository ( owner , name , closedPullRequestsRequest ) . ConfigureAwait ( false ) )
151+ // Return only Closed and Merged PullRequests
152+ return ( await client . PullRequest . GetAllForRepository ( repositorySettings . Owner , repositorySettings . Name , closedPullRequestsRequest ) . ConfigureAwait ( false ) )
175153 . Where ( pull => pull . Merged )
176154 . OrderBy ( pull => pull . Id )
177155 . ToList ( )
178156 . AsReadOnly ( ) ;
179157 }
180158
181- private static void GetOwnerAndProject ( string url , out string owner , out string project )
159+ private static void GetRepositorySettingsOrThrowException ( string url , string headBranchName , out RepositorySettings repositorySettings )
182160 {
183161 var groups = OwnerAndProjectRegex . Match ( url ) . Groups ;
184162
185- if ( ! TryGetValue ( groups , "ownerHttps" , "ownerSSH" , out owner ) || ! TryGetValue ( groups , "projectHttps" , "projectSSH" , out project ) )
163+ if ( ! TryGetValue ( groups , "ownerHttps" , "ownerSSH" , out var owner ) || ! TryGetValue ( groups , "projectHttps" , "projectSSH" , out var project ) )
186164 {
187165 throw new UriFormatException ( $ "The url '{ url } ' is not a valid GitHub url, the Owner and or Project are not present.") ;
188166 }
189- }
190-
191- private static long ? GetVersionAsLong ( string friendlyName )
192- {
193- var versionAsString = new string ( friendlyName . Where ( c => char . IsDigit ( c ) || c == '.' ) . ToArray ( ) ) ;
194- if ( System . Version . TryParse ( versionAsString , out var version ) )
195- {
196- return version . Major * 1000000000L + version . Minor * 1000000L + ( version . Build > 0 ? version . Build : 0 ) * 1000L + ( version . Revision > 0 ? version . Revision : 0 ) ;
197- }
198167
199- return null ;
168+ repositorySettings = new RepositorySettings ( owner , project , headBranchName ) ;
200169 }
201170
202171 private static bool TryGetValue ( GroupCollection groups , string groupName1 , string groupName2 , out string value )
0 commit comments