-
Notifications
You must be signed in to change notification settings - Fork 289
Added File Churn Metric #1071
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Added File Churn Metric #1071
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
5019e81
add churn metric
o2sh 205dd36
add diff_count
o2sh 6dadbf8
revert
o2sh 5f941dd
rename
o2sh 667ca9a
add churn cli flags
o2sh 6850da5
fix integration test
o2sh 3d58e26
add unit tests
o2sh d4a5339
Merge branch 'main' into feat/churn
o2sh 6ffd49c
try fix codeowners
o2sh 5f91e6e
fix codeowners
o2sh 2f7a2b4
Merge branch 'main' into feat/churn
o2sh 5b85a3f
Merge branch 'main' into feat/churn
o2sh afa5788
Optimize diff implementation
Byron 0339581
Don't fail on missing parent as we want to work in shallow repos, too
Byron c36fe41
Increase performance by decoding the commit only once
Byron fee2db3
track changes on executable files
o2sh ce54746
remove for_each method
o2sh f9e0777
use horizontal ellipsis
o2sh 27246fe
review
o2sh 7cae61b
use MAIN_SEPERATOR when building path
o2sh 195fe73
revert
o2sh 627b9f2
run expensive diffs in parallel and abort them once we run out of time.
Byron 1433c17
Always calculate at least one diff for 'churn'
Byron 27af8a5
improved readability + churn_pool_size CLI flag
o2sh cc6b3ef
fix test
o2sh ddeaea3
halt if the churn pool size is bigger than the total number of commits
o2sh 2876860
improve readability
o2sh 0b0abae
add unit test
o2sh 16d2274
refactor
Byron c8a8cb7
update to latest `gix` version
Byron b767374
Avoid exhaustive memory consumption by sending the commit-id instead …
Byron File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
use super::utils::{git::CommitMetrics, info_field::InfoField}; | ||
use crate::{cli::NumberSeparator, info::format_number}; | ||
use owo_colors::{DynColors, OwoColorize}; | ||
use serde::Serialize; | ||
use std::fmt::Write; | ||
|
||
#[derive(Serialize, Clone)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct FileChurn { | ||
pub file_path: String, | ||
pub nbr_of_commits: usize, | ||
#[serde(skip_serializing)] | ||
number_separator: NumberSeparator, | ||
} | ||
|
||
impl FileChurn { | ||
pub fn new( | ||
file_path: String, | ||
nbr_of_commits: usize, | ||
number_separator: NumberSeparator, | ||
) -> Self { | ||
Self { | ||
file_path, | ||
nbr_of_commits, | ||
number_separator, | ||
} | ||
} | ||
} | ||
|
||
impl std::fmt::Display for FileChurn { | ||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
write!( | ||
f, | ||
"{} {}", | ||
shorten_file_path(&self.file_path, 2), | ||
format_number(&self.nbr_of_commits, self.number_separator) | ||
) | ||
} | ||
} | ||
|
||
#[derive(Serialize)] | ||
pub struct ChurnInfo { | ||
pub file_churns: Vec<FileChurn>, | ||
pub churn_pool_size: usize, | ||
#[serde(skip_serializing)] | ||
pub info_color: DynColors, | ||
} | ||
impl ChurnInfo { | ||
pub fn new(info_color: DynColors, commit_metrics: &CommitMetrics) -> Self { | ||
let file_churns = commit_metrics.file_churns_to_display.clone(); | ||
Self { | ||
file_churns, | ||
churn_pool_size: commit_metrics.churn_pool_size, | ||
info_color, | ||
} | ||
} | ||
} | ||
impl std::fmt::Display for ChurnInfo { | ||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
let mut churn_info = String::new(); | ||
|
||
let pad = self.title().len() + 2; | ||
|
||
for (i, churn) in self.file_churns.iter().enumerate() { | ||
let churn_str = churn.color(self.info_color); | ||
|
||
if i == 0 { | ||
write!(churn_info, "{churn_str}")?; | ||
} else { | ||
write!(churn_info, "\n{:<width$}{}", "", churn_str, width = pad)?; | ||
} | ||
} | ||
|
||
write!(f, "{churn_info}") | ||
} | ||
} | ||
|
||
#[typetag::serialize] | ||
impl InfoField for ChurnInfo { | ||
fn value(&self) -> String { | ||
self.to_string() | ||
} | ||
|
||
fn title(&self) -> String { | ||
format!("Churn ({})", self.churn_pool_size) | ||
} | ||
|
||
fn should_color(&self) -> bool { | ||
false | ||
} | ||
} | ||
|
||
fn shorten_file_path(file_path: &str, depth: usize) -> String { | ||
let components: Vec<&str> = file_path.split('/').collect(); | ||
|
||
if depth == 0 || components.len() <= depth { | ||
return file_path.to_string(); | ||
} | ||
|
||
let truncated_components: Vec<&str> = components | ||
.iter() | ||
.skip(components.len() - depth) | ||
.copied() | ||
.collect(); | ||
|
||
format!("\u{2026}/{}", truncated_components.join("/")) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_display_file_churn() { | ||
let file_churn = FileChurn::new("path/to/file.txt".into(), 50, NumberSeparator::Plain); | ||
|
||
assert_eq!(file_churn.to_string(), "\u{2026}/to/file.txt 50"); | ||
} | ||
|
||
#[test] | ||
fn test_churn_info_value_with_two_file_churns() { | ||
let file_churn_1 = FileChurn::new("path/to/file.txt".into(), 50, NumberSeparator::Plain); | ||
let file_churn_2 = FileChurn::new("file_2.txt".into(), 30, NumberSeparator::Plain); | ||
|
||
let churn_info = ChurnInfo { | ||
file_churns: vec![file_churn_1, file_churn_2], | ||
churn_pool_size: 5, | ||
info_color: DynColors::Rgb(255, 0, 0), | ||
}; | ||
|
||
assert!(churn_info.value().contains( | ||
&"\u{2026}/to/file.txt 50" | ||
.color(DynColors::Rgb(255, 0, 0)) | ||
.to_string() | ||
)); | ||
|
||
assert!(churn_info | ||
.value() | ||
.contains(&"file_2.txt 30".color(DynColors::Rgb(255, 0, 0)).to_string())); | ||
} | ||
|
||
#[test] | ||
fn test_truncate_file_path() { | ||
assert_eq!(shorten_file_path("path/to/file.txt", 3), "path/to/file.txt"); | ||
assert_eq!(shorten_file_path("another/file.txt", 2), "another/file.txt"); | ||
assert_eq!(shorten_file_path("file.txt", 1), "file.txt"); | ||
assert_eq!( | ||
shorten_file_path("path/to/file.txt", 2), | ||
"\u{2026}/to/file.txt" | ||
); | ||
assert_eq!( | ||
shorten_file_path("another/file.txt", 1), | ||
"\u{2026}/file.txt" | ||
); | ||
assert_eq!(shorten_file_path("file.txt", 0), "file.txt"); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.