Skip to content

Commit 3c4f8d7

Browse files
committed
(#113) Collect all invalid issues together
When there are issues that contain invalid issues, rather than throw a single exception for the first problem, throw an exception that contains information about all the problematic issues. This saves the end user from having to run GRM multiple times, fixing one issue at a time.
1 parent 1763077 commit 3c4f8d7

File tree

2 files changed

+72
-29
lines changed

2 files changed

+72
-29
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace GitReleaseManager.Core.Exceptions
5+
{
6+
[Serializable]
7+
public class InvalidIssuesException : Exception
8+
{
9+
public InvalidIssuesException()
10+
{
11+
}
12+
13+
public InvalidIssuesException(List<string> errors)
14+
: base(string.Join(Environment.NewLine, errors))
15+
{
16+
Errors = errors;
17+
}
18+
19+
public InvalidIssuesException(List<string> errors, string message)
20+
: base(message)
21+
{
22+
Errors = errors;
23+
}
24+
25+
public InvalidIssuesException(List<string> errors, string message, Exception inner)
26+
: base(message, inner)
27+
{
28+
Errors = errors;
29+
}
30+
31+
public List<string> Errors { get; set; }
32+
33+
protected InvalidIssuesException(
34+
System.Runtime.Serialization.SerializationInfo info,
35+
System.Runtime.Serialization.StreamingContext context)
36+
: base(info, context) { }
37+
}
38+
}

src/GitReleaseManager.Core/ReleaseNotes/ReleaseNotesBuilder.cs

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Threading.Tasks;
66
using GitReleaseManager.Core.Configuration;
7+
using GitReleaseManager.Core.Exceptions;
78
using GitReleaseManager.Core.Helpers;
89
using GitReleaseManager.Core.Model;
910
using GitReleaseManager.Core.Provider;
@@ -124,36 +125,43 @@ private string GetValidLabel(string label, int issuesCount)
124125
return newLabel;
125126
}
126127

127-
private bool CheckForValidLabels(Issue issue)
128+
private (List<Issue> IssuesWithValidLabel, List<string> Errors) CheckIssuesForValidLabels(IEnumerable<Issue> issues)
128129
{
129-
var includedIssuesCount = 0;
130-
var excludedIssuesCount = 0;
130+
var validIssues = new List<Issue>();
131+
var errors = new List<string>();
131132

132-
foreach (var issueLabel in issue.Labels)
133+
foreach (var issue in issues)
133134
{
134-
includedIssuesCount += _configuration.IssueLabelsInclude.Count(issueToInclude => issueLabel.Name.ToUpperInvariant() == issueToInclude.ToUpperInvariant());
135+
var includedIssuesCount = 0;
136+
var excludedIssuesCount = 0;
135137

136-
excludedIssuesCount += _configuration.IssueLabelsExclude.Count(issueToExclude => issueLabel.Name.ToUpperInvariant() == issueToExclude.ToUpperInvariant());
137-
}
138+
foreach (var issueLabel in issue.Labels)
139+
{
140+
includedIssuesCount += _configuration.IssueLabelsInclude.Count(issueToInclude => issueLabel.Name.ToUpperInvariant() == issueToInclude.ToUpperInvariant());
138141

139-
if (includedIssuesCount + excludedIssuesCount != 1)
140-
{
141-
var allIssueLabels = _configuration.IssueLabelsInclude.Union(_configuration.IssueLabelsExclude).ToList();
142-
var allIssuesExceptLast = allIssueLabels.Take(allIssueLabels.Count - 1);
143-
var lastLabel = allIssueLabels.Last();
142+
excludedIssuesCount += _configuration.IssueLabelsExclude.Count(issueToExclude => issueLabel.Name.ToUpperInvariant() == issueToExclude.ToUpperInvariant());
143+
}
144144

145-
var allIssuesExceptLastString = string.Join(", ", allIssuesExceptLast);
145+
if (includedIssuesCount + excludedIssuesCount != 1)
146+
{
147+
var allIssueLabels = _configuration.IssueLabelsInclude.Union(_configuration.IssueLabelsExclude).ToList();
148+
var allIssuesExceptLast = allIssueLabels.Take(allIssueLabels.Count - 1);
149+
var lastLabel = allIssueLabels.Last();
146150

147-
var message = string.Format(CultureInfo.InvariantCulture, "Bad Issue {0} expected to find a single label with either {1} or {2}.", issue.HtmlUrl, allIssuesExceptLastString, lastLabel);
148-
throw new InvalidOperationException(message);
149-
}
151+
var allIssuesExceptLastString = string.Join(", ", allIssuesExceptLast);
150152

151-
if (includedIssuesCount > 0)
152-
{
153-
return true;
153+
var message = string.Format(CultureInfo.InvariantCulture, "Bad Issue {0} expected to find a single label with either {1} or {2}.", issue.HtmlUrl, allIssuesExceptLastString, lastLabel);
154+
errors.Add(message);
155+
continue;
156+
}
157+
158+
if (includedIssuesCount > 0)
159+
{
160+
validIssues.Add(issue);
161+
}
154162
}
155163

156-
return false;
164+
return (validIssues, errors);
157165
}
158166

159167
private Milestone GetPreviousMilestone()
@@ -173,28 +181,25 @@ private async Task LoadMilestonesAsync()
173181

174182
private async Task<List<Issue>> GetIssuesAsync(Milestone milestone)
175183
{
176-
var issues = await _vcsProvider.GetIssuesAsync(_user, _repository, milestone.Number, ItemStateFilter.Closed).ConfigureAwait(false);
184+
var allIssues = await _vcsProvider.GetIssuesAsync(_user, _repository, milestone.Number, ItemStateFilter.Closed).ConfigureAwait(false);
177185

178-
var hasIncludedIssues = false;
186+
var result = CheckIssuesForValidLabels(allIssues);
179187

180-
foreach (var issue in issues)
188+
if (result.Errors.Count > 0)
181189
{
182-
if (CheckForValidLabels(issue))
183-
{
184-
hasIncludedIssues = true;
185-
}
190+
throw new InvalidIssuesException(result.Errors);
186191
}
187192

188193
// If there are no issues assigned to the milestone that have a label that is part
189194
// of the labels to include array, then that is essentially the same as having no
190195
// closed issues assigned to the milestone. In this scenario, we want to raise an
191196
// error, so return an emtpy issues list.
192-
if (!hasIncludedIssues)
197+
if (!result.IssuesWithValidLabel.Any())
193198
{
194199
return new List<Issue>();
195200
}
196201

197-
return issues.ToList();
202+
return allIssues.ToList();
198203
}
199204

200205
private void GetTargetMilestone()

0 commit comments

Comments
 (0)