Skip to content

Commit f5f0e7f

Browse files
committed
fix warnings
1 parent 7fa96f2 commit f5f0e7f

File tree

4 files changed

+119
-95
lines changed

4 files changed

+119
-95
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,4 @@ pedantic = { level = "warn", priority = -1 }
3333
nursery = { level = "warn", priority = -1 }
3434
# cargo = { level = "warn", priority = -1 }
3535

36-
missing_docs_in_private_items = "warn"
3736
unwrap_used = "warn"

src/config.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
use std::path::PathBuf;
44

55
use clap::{Parser, ValueEnum};
6+
use gix::bstr::ByteSlice;
67
use label_logger::warn;
78

89
/// Check for unsaved or uncommitted changes on your machine
10+
#[expect(clippy::struct_excessive_bools)]
911
#[derive(Parser)]
1012
#[clap(name = "git-leave", about, version, author, long_about = None)]
1113
pub struct Args {
@@ -31,8 +33,8 @@ pub struct Args {
3133

3234
// Singular is used because of repetition on the CLI
3335
// e.g. `--check dirty --check ahead-branches`
34-
#[clap(long)]
3536
/// Override checks to run on found repositories
37+
#[clap(long)]
3638
pub check: Vec<Check>,
3739
}
3840

@@ -91,11 +93,10 @@ impl Config {
9193
self.default_folder = Some(default_folder.to_string().into());
9294
}
9395

94-
if let Some(checks) = config.string(CONFIG_KEY_CHECKS) {
96+
if let Some(checks) = config.strings(CONFIG_KEY_CHECKS) {
9597
let checks = checks
96-
.to_string()
97-
.split_ascii_whitespace()
98-
.map(|check| Check::from_str(check, false))
98+
.into_iter()
99+
.map(|check| Check::from_str(&check.to_str_lossy(), false))
99100
.collect::<Result<Vec<_>, _>>();
100101

101102
match checks {

src/diagnostic.rs

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,117 @@
11
//! Wrappers around git2 crate to simplify some specific git operations
22
3-
use eyre::{Context, bail};
4-
use gix::{Repository, features::progress, remote::Direction, status::UntrackedFiles};
3+
use std::path::{Path, PathBuf};
4+
5+
use eyre::{Context, ContextCompat, bail};
6+
use gix::{
7+
Repository, ThreadSafeRepository, features::progress, remote::Direction, status::UntrackedFiles,
8+
};
9+
use indicatif::ProgressBar;
10+
use label_logger::{OutputLabel, console::style, error, info, label_theme, log};
11+
use pariter::IteratorExt;
512

613
use crate::config::{Check, Config};
714

15+
pub fn print_diagnostics(
16+
repos: Vec<PathBuf>,
17+
config: Config,
18+
search_directory: &Path,
19+
) -> eyre::Result<()> {
20+
let len = repos
21+
.len()
22+
.try_into()
23+
.wrap_err("could not fit repos in a usize")?;
24+
let diag_bar = ProgressBar::new(len).with_style(label_theme(OutputLabel::Info("Checking")));
25+
let diag_bar_parallel = diag_bar.clone();
26+
27+
let diagnostics = repos
28+
.into_iter()
29+
.parallel_map(move |path| {
30+
diag_bar_parallel.inc(1);
31+
32+
let Ok(repo) = ThreadSafeRepository::open(path) else {
33+
error!("could not open repository");
34+
return None;
35+
};
36+
37+
let Ok(diag) = Diagnostic::analyze(&repo.to_thread_local(), &config) else {
38+
error!("could not open diagnostic");
39+
return None;
40+
};
41+
42+
if !diag.useful() {
43+
return None;
44+
}
45+
46+
Some((repo, diag))
47+
})
48+
.flatten()
49+
.collect::<Vec<_>>();
50+
51+
diag_bar.finish_and_clear();
52+
53+
for (repo, diag) in diagnostics {
54+
let path = repo
55+
.path()
56+
.parent()
57+
.expect("repository .git folder always has a parent");
58+
59+
let project_name = path
60+
.file_name()
61+
.wrap_err("could not get project name")?
62+
.to_string_lossy();
63+
let directory = path
64+
.parent()
65+
.wrap_err("could not get project directory")?
66+
.to_string_lossy();
67+
// Make path relative to root search directory
68+
let directory = directory.replacen(search_directory.to_string_lossy().as_ref(), ".", 1);
69+
70+
let path = format!(
71+
"{}{}{}",
72+
style(directory).dim(),
73+
style(std::path::MAIN_SEPARATOR).dim(),
74+
project_name,
75+
);
76+
77+
let dirty_info = if diag.is_dirty {
78+
style(" is dirty").yellow()
79+
} else {
80+
style("")
81+
};
82+
83+
info!(label: "Repo", "{path}{dirty_info}");
84+
85+
let ahead_branches = diag
86+
.ahead_branches
87+
.iter()
88+
.map(|name| style(name).yellow().to_string())
89+
.collect::<Vec<_>>();
90+
if !ahead_branches.is_empty() {
91+
log!(
92+
label: OutputLabel::Custom(style("└")),
93+
"has ahead branches: {}",
94+
ahead_branches.join(", ")
95+
);
96+
}
97+
98+
let branches_no_upstream = diag
99+
.no_upstream_branches
100+
.iter()
101+
.map(|name| style(name).yellow().to_string())
102+
.collect::<Vec<_>>();
103+
if !branches_no_upstream.is_empty() {
104+
log!(
105+
label: OutputLabel::Custom(style("└")),
106+
"has branches with no upstream: {}",
107+
branches_no_upstream.join(", ")
108+
);
109+
}
110+
}
111+
112+
Ok(())
113+
}
114+
8115
/// A repository diagnostic
9116
pub struct Diagnostic {
10117
/// Does the repository contains changes staged or not

src/main.rs

Lines changed: 4 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@ use std::{borrow::Cow, process, time::Instant};
77

88
use clap::Parser;
99
use eyre::Context;
10-
use gix::ThreadSafeRepository;
11-
use indicatif::ProgressBar;
12-
use label_logger::{OutputLabel, console::style, error, info, label_theme, log, success};
13-
use pariter::IteratorExt;
10+
use label_logger::{error, success};
1411

1512
use crate::{
1613
config::{Args, Config},
1714
crawl::crawl_repositories,
18-
diagnostic::Diagnostic,
15+
diagnostic::print_diagnostics,
1916
};
2017

2118
mod config;
@@ -51,6 +48,7 @@ fn main() -> eyre::Result<()> {
5148

5249
// Find git repositories in the specified directory
5350
let mut repos = crawl_repositories(&search_directory, &args);
51+
5452
repos.sort();
5553

5654
// Exit if no git repositories were found
@@ -67,88 +65,7 @@ fn main() -> eyre::Result<()> {
6765
begin_search_time.elapsed().as_secs()
6866
);
6967

70-
let diag_bar = ProgressBar::new(repos.len().try_into().unwrap())
71-
.with_style(label_theme(OutputLabel::Info("Checking")));
72-
let diag_bar_parallel = diag_bar.clone();
73-
74-
let diagnostics = repos
75-
.into_iter()
76-
.parallel_map(move |path| {
77-
diag_bar_parallel.inc(1);
78-
79-
let Ok(repo) = ThreadSafeRepository::open(path) else {
80-
error!("could not open repository");
81-
return None;
82-
};
83-
84-
let Ok(diag) = Diagnostic::analyze(&repo.to_thread_local(), &config) else {
85-
error!("could not open diagnostic");
86-
return None;
87-
};
88-
89-
if !diag.useful() {
90-
return None;
91-
}
92-
93-
Some((repo, diag))
94-
})
95-
.flatten()
96-
.collect::<Vec<_>>();
97-
98-
diag_bar.finish_and_clear();
99-
100-
for (repo, diag) in diagnostics {
101-
let path = repo
102-
.path()
103-
.parent()
104-
.expect("repository .git folder always has a parent");
105-
106-
let project_name = path.file_name().unwrap().to_string_lossy();
107-
let directory = path.parent().unwrap().to_string_lossy();
108-
// Make path relative to root search directory
109-
let directory = directory.replacen(search_directory.to_string_lossy().as_ref(), ".", 1);
110-
111-
let path = format!(
112-
"{}{}{}",
113-
style(directory).dim(),
114-
style(std::path::MAIN_SEPARATOR).dim(),
115-
project_name,
116-
);
117-
118-
let dirty_info = if diag.is_dirty {
119-
style(" is dirty").yellow()
120-
} else {
121-
style("")
122-
};
123-
124-
info!(label: "Repo", "{path}{dirty_info}");
125-
126-
let ahead_branches = diag
127-
.ahead_branches
128-
.iter()
129-
.map(|name| style(name).yellow().to_string())
130-
.collect::<Vec<_>>();
131-
if !ahead_branches.is_empty() {
132-
log!(
133-
label: OutputLabel::Custom(style("└")),
134-
"has ahead branches: {}",
135-
ahead_branches.join(", ")
136-
);
137-
}
138-
139-
let branches_no_upstream = diag
140-
.no_upstream_branches
141-
.iter()
142-
.map(|name| style(name).yellow().to_string())
143-
.collect::<Vec<_>>();
144-
if !branches_no_upstream.is_empty() {
145-
log!(
146-
label: OutputLabel::Custom(style("└")),
147-
"has branches with no upstream: {}",
148-
branches_no_upstream.join(", ")
149-
);
150-
}
151-
}
68+
print_diagnostics(repos, config, &search_directory)?;
15269

15370
Ok(())
15471
}

0 commit comments

Comments
 (0)