Skip to content

Commit 66dd7ad

Browse files
committed
feat(Sections): adds breaking changes
Closes #5
1 parent bace209 commit 66dd7ad

File tree

4 files changed

+79
-15
lines changed

4 files changed

+79
-15
lines changed

src/clog.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ pub struct Clog {
6969
pub regex: Regex,
7070
/// The regex used to get closes issue links
7171
pub closes_regex: Regex,
72+
/// The regex used to get closes issue links
73+
pub breaks_regex: Regex,
74+
pub breaking_regex: Regex,
7275
/// The format to output the changelog in (Defaults to Markdown)
7376
pub out_format: ChangelogFormat
7477
}
@@ -92,6 +95,8 @@ impl fmt::Debug for Clog {
9295
git_work_tree: {:?}
9396
regex: {:?}
9497
closes_regex: {:?}
98+
breaks_regex: {:?}
99+
breaking_regex: {:?}
95100
out_format: {:?}
96101
}}",
97102
self.grep,
@@ -110,6 +115,8 @@ impl fmt::Debug for Clog {
110115
self.git_work_tree,
111116
self.regex,
112117
self.closes_regex,
118+
self.breaks_regex,
119+
self.breaking_regex,
113120
self.out_format,
114121
)
115122
}
@@ -124,7 +131,7 @@ impl Clog {
124131
sections.insert("Bug Fixes".to_owned(), vec!["fx".to_owned(), "fix".to_owned()]);
125132
sections.insert("Performance".to_owned(), vec!["perf".to_owned()]);
126133
sections.insert("Unknown".to_owned(), vec!["unk".to_owned()]);
127-
sections.insert("Breaks".to_owned(), vec![]);
134+
sections.insert("Breaking Changes".to_owned(), vec!["breaks".to_owned()]);
128135

129136
Clog {
130137
grep: format!("{}BREAKING'",
@@ -150,7 +157,9 @@ impl Clog {
150157
git_dir: None,
151158
git_work_tree: None,
152159
regex: regex!(r"^([^:\(]+?)(?:\(([^:\)]*?)?\))?:(.*)"),
153-
closes_regex: regex!(r"(?:Closes|Fixes|Resolves)\s((?:#(\d+)(?:,\s)?)+)")
160+
closes_regex: regex!(r"(?:Closes|Fixes|Resolves)\s((?:#(\d+)(?:,\s)?)+)"),
161+
breaks_regex: regex!(r"(?:Breaks|Broke)\s((?:#(\d+)(?:,\s)?)+)"),
162+
breaking_regex: regex!(r"(?i:breaking)")
154163
}
155164
}
156165

@@ -774,7 +783,7 @@ impl Clog {
774783
}
775784

776785
fn parse_raw_commit(&self, commit_str: &str) -> Commit {
777-
let mut lines = commit_str.split('\n');
786+
let mut lines = commit_str.lines();
778787

779788
let hash = lines.next().unwrap_or("").to_owned();
780789

@@ -789,16 +798,29 @@ impl Clog {
789798
}
790799
None => (Some(""), Some(""), self.section_for("unk").clone()),
791800
};
792-
let closes = lines.filter_map(|line| self.closes_regex.captures(line))
793-
.map(|caps| caps.at(2).unwrap_or("").to_owned())
794-
.collect();
801+
let mut closes = vec![];
802+
let mut breaks = vec![];
803+
for line in lines {
804+
if let Some(caps) = self.closes_regex.captures(line) {
805+
if let Some(cap) = caps.at(2) {
806+
closes.push(cap.to_owned());
807+
}
808+
}
809+
if let Some(caps) = self.breaks_regex.captures(line) {
810+
if let Some(cap) = caps.at(2) {
811+
breaks.push(cap.to_owned());
812+
}
813+
} else if self.breaking_regex.captures(line).is_some() {
814+
breaks.push("".to_owned());
815+
}
816+
}
795817

796818
Commit {
797819
hash: hash,
798820
subject: subject.unwrap().to_owned(),
799821
component: component.unwrap_or("").to_owned(),
800822
closes: closes,
801-
breaks: vec![],
823+
breaks: breaks,
802824
commit_type: commit_type
803825
}
804826
}

src/fmt/json_writer.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'a> JsonWriter<'a> {
124124
.commit_link(&*entry.hash, &*options.repo)
125125
).unwrap();
126126

127-
if entry.closes.len() > 0 {
127+
if !entry.closes.is_empty() {
128128
write!(self.0, "[").unwrap();
129129
let mut c_it = entry.closes.iter().peekable();
130130
while let Some(issue) = c_it.next() {
@@ -140,9 +140,31 @@ impl<'a> JsonWriter<'a> {
140140
debugln!("There are no more close commits, no comma required");
141141
}
142142
}
143+
write!(self.0,
144+
"],").unwrap();
145+
} else {
146+
write!(self.0, "null,").unwrap();
147+
}
148+
write!(self.0 , "\"breaks\":").unwrap();
149+
if !entry.breaks.is_empty() {
150+
write!(self.0, "[").unwrap();
151+
let mut c_it = entry.closes.iter().peekable();
152+
while let Some(issue) = c_it.next() {
153+
write!(self.0,
154+
"{{\"issue\":{},\"issue_link\":{:?}}}",
155+
issue,
156+
options.link_style.issue_link(issue, &options.repo)
157+
).unwrap();
158+
if c_it.peek().is_some() {
159+
debugln!("There are more breaks commits, adding comma");
160+
write!(self.0, ",").unwrap();
161+
} else {
162+
debugln!("There are no more breaks commits, no comma required");
163+
}
164+
}
143165
write!(self.0,
144166
"]}}").unwrap();
145-
} else {
167+
} else {
146168
write!(self.0, "null}}").unwrap();
147169
}
148170
if e_it.peek().is_some() {

src/fmt/md_writer.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<'a> MarkdownWriter<'a> {
133133
return Err(Error::WriteErr);
134134
}
135135

136-
if entry.closes.len() > 0 {
136+
if !entry.closes.is_empty() {
137137
let closes_string = entry.closes.iter()
138138
.map(|s| format!("[#{}]({})",
139139
&*s,
@@ -145,6 +145,21 @@ impl<'a> MarkdownWriter<'a> {
145145
return Err(Error::WriteErr);
146146
}
147147
}
148+
if !entry.breaks.is_empty() {
149+
let breaks_string = entry.breaks.iter()
150+
.map(|s| format!("[#{}]({})",
151+
&*s,
152+
options.link_style.issue_link(&*s, &options.repo)))
153+
.collect::<Vec<String>>()
154+
.join(", ");
155+
156+
// 5 = "[#]()" i.e. a commit message that only said "BREAKING"
157+
if breaks_string.len() != 5 {
158+
if let Err(..) = write!(self.0 , ", breaks {}", breaks_string) {
159+
return Err(Error::WriteErr);
160+
}
161+
}
162+
}
148163

149164
if let Err(..) = write!(self.0 , ")\n") {
150165
return Err(Error::WriteErr);

src/sectionmap.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ impl SectionMap {
2121
/// # use std::fs::File;
2222
/// # use clog::{Clog, SectionMap};
2323
/// # use clog::fmt::{FormatWriter, MarkdownWriter};
24-
/// let clog = Clog::new().unwrap_or_else(|e| {
24+
/// let clog = Clog::new().unwrap_or_else(|e| {
2525
/// e.exit();
2626
/// });
2727
///
@@ -34,9 +34,9 @@ impl SectionMap {
3434
///
3535
/// // Create the MarkdownWriter
3636
/// let mut writer = MarkdownWriter::new(&mut file);
37-
///
37+
///
3838
/// // Use the MarkdownWriter to write the changelog
39-
/// clog.write_changelog_with(&mut writer).unwrap_or_else(|e| {
39+
/// clog.write_changelog_with(&mut writer).unwrap_or_else(|e| {
4040
/// e.exit();
4141
/// });
4242
/// ```
@@ -45,11 +45,16 @@ impl SectionMap {
4545
sections: HashMap::new()
4646
};
4747

48-
commits.into_iter().map(|entry| {
48+
for entry in commits {
49+
if !entry.breaks.is_empty() {
50+
let comp_map = sm.sections.entry("Breaking Changes".to_owned()).or_insert(BTreeMap::new());
51+
let sec_map = comp_map.entry(entry.component.clone()).or_insert(vec![]);
52+
sec_map.push(entry.clone());
53+
}
4954
let comp_map = sm.sections.entry(entry.commit_type.clone()).or_insert(BTreeMap::new());
5055
let sec_map = comp_map.entry(entry.component.clone()).or_insert(vec![]);
5156
sec_map.push(entry);
52-
}).collect::<Vec<_>>();
57+
}
5358

5459
sm
5560
}

0 commit comments

Comments
 (0)