@@ -6,6 +6,7 @@ use std::{collections::BTreeSet, path::PathBuf};
66use anyhow:: Context ;
77use regex:: Regex ;
88
9+ use crate :: gh:: IssueId ;
910use crate :: re:: USERNAME ;
1011use crate :: team:: { self , TeamName } ;
1112use crate :: util:: { commas, markdown_files} ;
@@ -15,6 +16,7 @@ use crate::{
1516} ;
1617
1718/// Data parsed from a goal file in the expected format
19+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord ) ]
1820pub struct GoalDocument {
1921 /// Path relative to the current directory (`book.toml`)
2022 pub path : PathBuf ,
@@ -37,17 +39,21 @@ pub struct GoalDocument {
3739}
3840
3941/// Metadata loaded from the goal header
40- #[ derive( Debug ) ]
42+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord ) ]
4143pub struct Metadata {
4244 #[ allow( unused) ]
4345 pub title : String ,
4446 pub short_title : String ,
4547 pub owners : String ,
4648 pub status : Status ,
49+ pub tracking_issue : Option < IssueId > ,
50+ pub table : Table ,
4751}
4852
53+ pub const TRACKING_ISSUE_ROW : & str = "Tracking issue" ;
54+
4955/// Identifies a particular ask for a set of Rust teams
50- #[ derive( Debug ) ]
56+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord ) ]
5157pub struct PlanItem {
5258 pub text : String ,
5359 pub owners : String ,
@@ -66,7 +72,7 @@ pub enum ParsedOwners {
6672}
6773
6874/// Identifies a particular ask for a set of Rust teams
69- #[ derive( Debug ) ]
75+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord ) ]
7076pub struct TeamAsk {
7177 /// Path to the markdown file containing this ask (appropriate for a link)
7278 pub link_path : Arc < PathBuf > ,
@@ -153,6 +159,16 @@ impl GoalDocument {
153159 Status :: NotAccepted => false ,
154160 }
155161 }
162+
163+ /// Modify the goal document on disk to link to the given issue number in the metadata.
164+ pub ( crate ) fn link_issue ( & self , number : IssueId ) -> anyhow:: Result < ( ) > {
165+ let mut metadata_table = self . metadata . table . clone ( ) ;
166+ metadata_table. add_key_value_row ( TRACKING_ISSUE_ROW , & number) ;
167+ self . metadata
168+ . table
169+ . overwrite_in_path ( & self . path , & metadata_table) ?;
170+ Ok ( ( ) )
171+ }
156172}
157173
158174/// Format a set of team asks into a table, with asks separated by team and grouped by kind.
@@ -240,7 +256,7 @@ pub fn format_goal_table(goals: &[&GoalDocument]) -> anyhow::Result<String> {
240256 Ok ( util:: format_table ( & table) )
241257}
242258
243- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
259+ #[ derive( Debug , PartialEq , Eq , PartialOrd , Ord , Copy , Clone ) ]
244260pub enum Status {
245261 Flagship ,
246262 Accepted ,
@@ -308,6 +324,15 @@ fn extract_metadata(sections: &[Section]) -> anyhow::Result<Option<Metadata>> {
308324
309325 let status = Status :: try_from ( status_row[ 1 ] . as_str ( ) ) ?;
310326
327+ let issue = match first_table
328+ . rows
329+ . iter ( )
330+ . find ( |row| row[ 0 ] == TRACKING_ISSUE_ROW )
331+ {
332+ Some ( r) => Some ( r[ 1 ] . parse ( ) ?) ,
333+ None => None ,
334+ } ;
335+
311336 Ok ( Some ( Metadata {
312337 title : title. to_string ( ) ,
313338 short_title : if let Some ( row) = short_title_row {
@@ -317,6 +342,8 @@ fn extract_metadata(sections: &[Section]) -> anyhow::Result<Option<Metadata>> {
317342 } ,
318343 owners : owners_row[ 1 ] . to_string ( ) ,
319344 status,
345+ tracking_issue : issue,
346+ table : first_table. clone ( ) ,
320347 } ) )
321348}
322349
0 commit comments