Skip to content

Commit f36e92f

Browse files
fix: Support checking out months and years ago (#7)
1 parent 2f777c3 commit f36e92f

1 file changed

Lines changed: 45 additions & 20 deletions

File tree

src/main.rs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,34 @@ fn normalize_ago(input: &str) -> String {
3838
return input.to_string();
3939
}
4040

41-
let (number, unit) = input.split_at(
42-
input
43-
.find(|c: char| !c.is_ascii_digit())
44-
.unwrap_or(input.len()),
45-
);
41+
// Split into numeric prefix and the rest
42+
let split_idx = input
43+
.find(|c: char| !c.is_ascii_digit())
44+
.unwrap_or(input.len());
4645

47-
if number.is_empty() || unit.is_empty() {
46+
let (number, rest) = input.split_at(split_idx);
47+
48+
if number.is_empty() || rest.trim().is_empty() {
4849
return input.to_string();
4950
}
5051

51-
let expanded_unit = match unit {
52-
"s" => "seconds",
53-
"m" => "minutes",
54-
"h" => "hours",
55-
"d" => "days",
56-
"w" => "weeks",
52+
// Normalize unit: remove whitespace, lowercase
53+
let unit = rest.trim().to_ascii_lowercase();
54+
55+
let expanded = match unit.as_str() {
56+
"s" | "sec" | "second" | "seconds" => "second",
57+
"m" | "min" | "minute" | "minutes" => "minute",
58+
"h" | "hr" | "hour" | "hours" => "hour",
59+
"d" | "day" | "days" => "day",
60+
"w" | "week" | "weeks" => "week",
61+
"mo" | "month" | "months" => "month",
62+
"y" | "year" | "years" => "year",
5763
_ => return input.to_string(),
5864
};
5965

60-
format!("{number} {expanded_unit}")
66+
let optional_plural = if number == "1" { "" } else { "s" };
67+
68+
format!("{number} {expanded}{optional_plural}")
6169
}
6270

6371
/// Build the `git rev-list` command arguments for a given "ago" string.
@@ -96,9 +104,15 @@ fn run(ago: &str, print_only: bool) -> Result<(), Box<dyn Error>> {
96104
}
97105

98106
{
99-
println!("Current HEAD: {original_head}");
100-
println!("Target commit: {target}");
107+
let ago_normalized = normalize_ago(ago);
108+
println!("Current HEAD: {original_head}");
109+
println!("Target commit: {target} ({ago_normalized})");
110+
if original_head == target {
111+
println!("[WARNING] Already at the target commit. Nothing to do.");
112+
return Ok(());
113+
}
101114
println!("To return: git checkout {original_head}");
115+
println!("-----------------------------------------------------");
102116
}
103117

104118
if !print_only {
@@ -126,8 +140,24 @@ fn main() {
126140
mod tests {
127141
use super::*;
128142

143+
#[test]
144+
fn test_normalize_shorthand_months() {
145+
assert_eq!(normalize_ago("1mo"), "1 month");
146+
assert_eq!(normalize_ago("2mo"), "2 months");
147+
assert_eq!(normalize_ago("3mo"), "3 months");
148+
assert_eq!(normalize_ago("4 months"), "4 months"); // Passthrough.
149+
assert_eq!(normalize_ago("4months"), "4 months");
150+
}
151+
152+
#[test]
153+
fn test_normalize_shorthand_weeks() {
154+
assert_eq!(normalize_ago("1w"), "1 week");
155+
assert_eq!(normalize_ago("2w"), "2 weeks");
156+
}
157+
129158
#[test]
130159
fn test_normalize_shorthand_days() {
160+
assert_eq!(normalize_ago("1d"), "1 day");
131161
assert_eq!(normalize_ago("2d"), "2 days");
132162
}
133163

@@ -136,11 +166,6 @@ mod tests {
136166
assert_eq!(normalize_ago("3h"), "3 hours");
137167
}
138168

139-
#[test]
140-
fn test_normalize_shorthand_weeks() {
141-
assert_eq!(normalize_ago("1w"), "1 weeks");
142-
}
143-
144169
#[test]
145170
fn test_normalize_shorthand_minutes() {
146171
assert_eq!(normalize_ago("15m"), "15 minutes");

0 commit comments

Comments
 (0)