Skip to content

Commit

Permalink
Support configurable timestamps in git blame output (dandavison#1157)
Browse files Browse the repository at this point in the history
New CLI/config option is introduced: blame-timestamp-output-format.

Fixes dandavison#1157.
  • Loading branch information
mliszcz committed Aug 12, 2022
1 parent d103b2b commit c03600e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 3 deletions.
7 changes: 7 additions & 0 deletions manual/src/full---help-output.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ OPTIONS:
[default: "%Y-%m-%d %H:%M:%S %z"]
--blame-timestamp-output-format <FMT>
Format string for git blame timestamp output.
This string is used for formatting the timestamps in git blame output. It must follow the `strftime` format syntax specification. If it is not present, the timestamps will be formatted in a human-friendly but possibly less accurate form.
See: (https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
--color-only
Do not alter the input structurally in any way.
Expand Down
10 changes: 10 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,16 @@ pub struct Opt {
/// Format of `git blame` timestamp in raw git output received by delta.
pub blame_timestamp_format: String,

#[clap(long = "blame-timestamp-output-format", value_name = "FMT")]
/// Format string for git blame timestamp output.
///
/// This string is used for formatting the timestamps in git blame output. It must follow
/// the `strftime` format syntax specification. If it is not present, the timestamps will
/// be formatted in a human-friendly but possibly less accurate form.
///
/// See: (https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
pub blame_timestamp_output_format: Option<String>,

#[clap(long = "color-only")]
/// Do not alter the input structurally in any way.
///
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub struct Config {
pub blame_palette: Vec<String>,
pub blame_separator_style: Option<Style>,
pub blame_timestamp_format: String,
pub blame_timestamp_output_format: Option<String>,
pub color_only: bool,
pub commit_regex: Regex,
pub commit_style: Style,
Expand Down Expand Up @@ -240,6 +241,7 @@ impl From<cli::Opt> for Config {
blame_separator_format: parse_blame_line_numbers(&opt.blame_separator_format),
blame_separator_style: styles.remove("blame-separator-style"),
blame_timestamp_format: opt.blame_timestamp_format,
blame_timestamp_output_format: opt.blame_timestamp_output_format,
commit_style: styles["commit-style"],
color_only: opt.color_only,
commit_regex,
Expand Down
47 changes: 44 additions & 3 deletions src/handlers/blame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,12 @@ pub fn format_blame_metadata(
let width = placeholder.width.unwrap_or(15);

let field = match placeholder.placeholder {
Some(Placeholder::Str("timestamp")) => Some(Cow::from(
chrono_humanize::HumanTime::from(blame.time).to_string(),
)),
Some(Placeholder::Str("timestamp")) => {
Some(Cow::from(match &config.blame_timestamp_output_format {
Some(time_format) => blame.time.format(time_format).to_string(),
None => chrono_humanize::HumanTime::from(blame.time).to_string(),
}))
}
Some(Placeholder::Str("author")) => Some(Cow::from(blame.author)),
Some(Placeholder::Str("commit")) => Some(delta::format_raw_line(blame.commit, config)),
None => None,
Expand Down Expand Up @@ -408,6 +411,33 @@ mod tests {
assert_eq!(caps.get(2).unwrap().as_str(), "Kangwook Lee (이강욱)");
}

#[test]
fn test_format_blame_metadata_with_default_timestamp_output_format() {
let format_data = format::FormatStringPlaceholderData {
placeholder: Some(Placeholder::Str("timestamp")),
..Default::default()
};
let blame = make_blame_line_with_time("1996-12-19T16:39:57-08:00");
let config = integration_test_utils::make_config_from_args(&[]);
let regex = Regex::new(r"^\d+ years ago$").unwrap();
let result = format_blame_metadata(&[format_data], &blame, &config);
assert!(regex.is_match(result.trim()));
}

#[test]
fn test_format_blame_metadata_with_custom_timestamp_output_format() {
let format_data = format::FormatStringPlaceholderData {
placeholder: Some(Placeholder::Str("timestamp")),
..Default::default()
};
let blame = make_blame_line_with_time("1996-12-19T16:39:57-08:00");
let config = integration_test_utils::make_config_from_args(&[
"--blame-timestamp-output-format=%Y-%m-%d %H:%M",
]);
let result = format_blame_metadata(&[format_data], &blame, &config);
assert_eq!(result.trim(), "1996-12-19 16:39");
}

#[test]
fn test_color_assignment() {
let mut writer = Cursor::new(vec![0; 512]);
Expand Down Expand Up @@ -497,4 +527,15 @@ mod tests {
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect()
}

fn make_blame_line_with_time(timestamp: &str) -> BlameLine {
let time = chrono::DateTime::parse_from_rfc3339(&timestamp).unwrap();
return BlameLine {
commit: "",
author: "",
time: time,
line_number: 0,
code: "",
};
}
}
1 change: 1 addition & 0 deletions src/options/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ pub fn set_options(
blame_palette,
blame_separator_style,
blame_timestamp_format,
blame_timestamp_output_format,
color_only,
commit_decoration_style,
commit_regex,
Expand Down

0 comments on commit c03600e

Please # to comment.