@@ -14,7 +14,7 @@ use crate::{
14
14
gh:: {
15
15
issue_id:: Repository ,
16
16
issues:: {
17
- count_issues_matching_search, list_issue_titles_in_milestone, CountIssues ,
17
+ count_issues_matching_search, fetch_issue , list_issue_titles_in_milestone, CountIssues ,
18
18
ExistingGithubComment , ExistingGithubIssue , ExistingIssueState ,
19
19
} ,
20
20
} ,
@@ -131,38 +131,66 @@ struct TrackingIssueUpdate {
131
131
///
132
132
/// Returns a tuple (completed, total) with the number of completed items and the total number of items.
133
133
fn checkboxes ( issue : & ExistingGithubIssue ) -> anyhow:: Result < Progress > {
134
- let mut checkboxes = None ;
135
- let mut issues = None ;
134
+ let mut completed = 0 ;
135
+ let mut total = 0 ;
136
136
137
137
for line in issue. body . lines ( ) {
138
138
// Does this match TRACKED_ISSUES?
139
139
if let Some ( c) = re:: TRACKED_ISSUES_QUERY . captures ( line) {
140
- let repo = Repository :: from_str ( & c[ 1 ] ) ?;
141
- let query = & c[ 2 ] ;
142
-
143
- if issues. is_some ( ) {
144
- anyhow:: bail!( "found multiple search queries for Tracked Issues" ) ;
145
- }
140
+ let repo = Repository :: from_str ( & c[ "repo" ] ) ?;
141
+ let query = & c[ "query" ] ;
146
142
147
143
let CountIssues { open, closed } = count_issues_matching_search ( & repo, query) ?;
148
- issues = Some ( ( closed, open + closed) ) ;
144
+ completed += closed;
145
+ total += open + closed;
146
+ continue ;
149
147
}
150
148
151
- let ( checked, total) = checkboxes. unwrap_or ( ( 0 , 0 ) ) ;
149
+ if let Some ( c) = re:: SEE_ALSO_QUERY . captures ( line) {
150
+ let issue_urls = c[ "issues" ] . split ( & [ ',' , ' ' ] ) . filter ( |s| !s. is_empty ( ) ) ;
151
+
152
+ for issue_url in issue_urls {
153
+ let Some ( c) = re:: SEE_ALSO_ISSUE . captures ( issue_url) else {
154
+ anyhow:: bail!( "invalid issue URL `{issue_url}`" )
155
+ } ;
156
+ let repository = Repository :: new ( & c[ "org" ] , & c[ "repo" ] ) ;
157
+ let issue_number = c[ "issue" ] . parse :: < u64 > ( ) ?;
158
+ let issue = fetch_issue ( & repository, issue_number) ?;
159
+ match checkboxes ( & issue) ? {
160
+ Progress :: Binary => {
161
+ if issue. state == ExistingIssueState :: Closed {
162
+ completed += 1 ;
163
+ }
164
+ total += 1 ;
165
+ }
166
+
167
+ Progress :: Tracked {
168
+ completed : c,
169
+ total : t,
170
+ } => {
171
+ completed += c;
172
+ total += t;
173
+ }
174
+
175
+ Progress :: Error { message } => {
176
+ anyhow:: bail!( "error parsing {repository}#{issue_number}: {message}" )
177
+ }
178
+ }
179
+ }
180
+ }
152
181
153
182
if re:: CHECKED_CHECKBOX . is_match ( line) {
154
- checkboxes = Some ( ( checked + 1 , total + 1 ) ) ;
183
+ total += 1 ;
184
+ completed += 1 ;
155
185
} else if re:: CHECKBOX . is_match ( line) {
156
- checkboxes = Some ( ( checked , total + 1 ) ) ;
186
+ total += 1 ;
157
187
}
158
188
}
159
189
160
- match ( checkboxes, issues) {
161
- ( Some ( ( completed, total) ) , None ) | ( None , Some ( ( completed, total) ) ) => {
162
- Ok ( Progress :: Tracked { completed, total } )
163
- }
164
- ( None , None ) => Ok ( Progress :: Binary ) ,
165
- ( Some ( _) , Some ( _) ) => anyhow:: bail!( "found both Tracked Issues and checkboxes" ) ,
190
+ if total == 0 && completed == 0 {
191
+ Ok ( Progress :: Binary )
192
+ } else {
193
+ Ok ( Progress :: Tracked { completed, total } )
166
194
}
167
195
}
168
196
0 commit comments