Skip to content

Commit a5fb023

Browse files
mrewoolfg
authored andcommitted
handle start and end date in output
1 parent ea60627 commit a5fb023

File tree

4 files changed

+76
-21
lines changed

4 files changed

+76
-21
lines changed

src/bin/analyzer/main.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ fn main() -> Result<()> {
3131
committer,
3232
} => {
3333
print!("Analyzing commits in current repository...");
34-
let input = count_commits(before, after, author, committer).context(
34+
let input = count_commits(&before, &after, author, committer).context(
3535
"Cannot read project history. Make sure there is no typo in the command",
3636
)?;
3737
let mut parser = Parser::new(input);
38+
if let Some(before) = before {
39+
parser.set_before(before)?;
40+
}
41+
if let Some(after) = after {
42+
parser.set_after(after)?;
43+
}
3844
let timeline = parser.parse()?;
3945
let output = serde_json::to_string_pretty(&timeline)?;
4046
fs::write(OUTPUT_FILE, output)?;

src/git.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use anyhow::Result;
1+
use anyhow::{Context, Result};
2+
use chrono::NaiveDate;
23
use duct::cmd;
34

45
/// Get the count of commits for each day from the git logs
56
pub fn count_commits(
6-
before: Option<String>,
7-
after: Option<String>,
7+
before: &Option<String>,
8+
after: &Option<String>,
89
authors: Vec<String>,
910
committers: Vec<String>,
1011
) -> Result<String> {
@@ -28,3 +29,13 @@ pub fn count_commits(
2829
let commits = cmd("git", &args).read()?;
2930
Ok(commits)
3031
}
32+
33+
// Parse a date from the git log
34+
pub fn parse_date(line: &str) -> Result<Option<NaiveDate>> {
35+
if line.trim().is_empty() {
36+
// Empty lines are allowed, but skipped
37+
return Ok(None);
38+
}
39+
let date: NaiveDate = line.parse().context(format!("Invalid date {}", line))?;
40+
Ok(Some(date))
41+
}

src/merge.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::convert::TryFrom;
22

3-
use crate::{parser::ParseState, types::Timeline};
3+
use crate::{git, parser::ParseState, types::Timeline};
44
use anyhow::Result;
55

66
/// Merger merges multiple timelines into one
@@ -19,7 +19,7 @@ impl Merger {
1919
fn merge_timeline(&mut self, timeline: &Timeline) -> Result<()> {
2020
for contribution in &timeline.contributions {
2121
let date = contribution.date.clone();
22-
let date = self.state.parse_date(&date)?;
22+
let date = git::parse_date(&date)?;
2323
let count = contribution.count;
2424

2525
if let Some(date) = date {

src/parser.rs

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,38 @@
1-
use crate::quartiles::quartiles;
21
use crate::types::{Contribution, Contributions, Range, Timeline, Year};
3-
use anyhow::{Context, Result};
2+
use crate::{git, quartiles::quartiles};
3+
use anyhow::Result;
44
use chrono::prelude::*;
5-
use std::{collections::HashMap, convert::TryFrom};
5+
use std::{cmp::{max, min}, collections::HashMap, convert::TryFrom};
66

77
/// The internal state of the parser
88
#[derive(Debug, Default)]
99
pub struct ParseState {
1010
years_map: HashMap<i32, Year>,
1111
days: HashMap<NaiveDate, usize>,
12+
before: Option<NaiveDate>,
13+
after: Option<NaiveDate>,
1214
}
1315

1416
impl ParseState {
1517
/// Add a single day to the map of years
1618
pub fn update_years(&mut self, date: NaiveDate) {
1719
let y = date.year();
20+
let start = match self.before {
21+
Some(before) => max(before, date),
22+
None => date,
23+
};
24+
let end = match self.after {
25+
Some(after) => min(after, date),
26+
None => date,
27+
};
1828
let mut year = self.years_map.entry(y).or_insert(Year {
1929
year: y.to_string(),
2030
total: 0,
2131
// range: Range::default,
2232
// Always show full year
2333
range: Range {
24-
start: format!("{}-01-01", y),
25-
end: format!("{}-12-31", y),
34+
start: start.format("%y-%m-%d").to_string(),
35+
end: end.format("%y-%m-%d").to_string(),
2636
},
2737
});
2838
year.total += 1;
@@ -40,15 +50,6 @@ impl ParseState {
4050
pub fn update_days(&mut self, date: NaiveDate) {
4151
*self.days.entry(date).or_insert(0) += 1;
4252
}
43-
44-
pub fn parse_date(&self, line: &str) -> Result<Option<NaiveDate>> {
45-
if line.trim().is_empty() {
46-
// Empty lines are allowed, but skipped
47-
return Ok(None);
48-
}
49-
let date: NaiveDate = line.parse().context(format!("Invalid date {}", line))?;
50-
Ok(Some(date))
51-
}
5253
}
5354

5455
/// Backfill missing days with zero commits
@@ -155,12 +156,49 @@ impl Parser {
155156
}
156157
}
157158

159+
/// Set the minimum date of the timeline. Commits older than the given date
160+
/// will not be counted and won't be in the final output
161+
pub fn set_before(&mut self, before: String) -> Result<&mut Self> {
162+
let before = git::parse_date(&before)?;
163+
if let Some(before) = before {
164+
self.state.before = Some(before);
165+
}
166+
Ok(self)
167+
}
168+
169+
/// Set the maximum date of the timeline. Commits newer than the given date
170+
/// will not be counted and won't be in the final output
171+
pub fn set_after(&mut self, after: String) -> Result<&mut Self> {
172+
let after = git::parse_date(&after)?;
173+
if let Some(after) = after {
174+
self.state.after = Some(after);
175+
}
176+
Ok(self)
177+
}
178+
179+
fn outside_date_range(&self, day: NaiveDate) -> bool {
180+
if let Some(before) = self.state.before {
181+
if day < before {
182+
return true;
183+
}
184+
}
185+
if let Some(after) = self.state.after {
186+
if day > after {
187+
return true;
188+
}
189+
}
190+
false
191+
}
192+
158193
/// Execute the parsing step
159194
pub fn parse(&mut self) -> Result<Timeline> {
160195
let input = self.input.clone();
161196
for line in input.lines() {
162-
let day = self.state.parse_date(&line)?;
197+
let day = git::parse_date(&line)?;
163198
if let Some(d) = day {
199+
if self.outside_date_range(d) {
200+
continue;
201+
}
164202
self.state.update_days(d);
165203
self.state.update_years(d);
166204
}

0 commit comments

Comments
 (0)