Skip to content

Commit e713084

Browse files
OJarrisonndavidbtadokoro
authored andcommitted
feat: check if the dependencies are present before running patch-hub
Check if the depedencies are present, log any issues and if hard dependencies are not present do not run the app. [Maintainer edits] - Squash test commit aggainst commit that introduces the unit (this) - Change var name `ok` in `binary_exists` to `can_run_app` Signed-off-by: OJarrisonn <[email protected]> Reviewed-by: David Tadokoro <[email protected]> Signed-off-by: David Tadokoro <[email protected]>
1 parent 25cd55b commit e713084

File tree

5 files changed

+97
-1
lines changed

5 files changed

+97
-1
lines changed

Cargo.lock

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ thiserror = "1.0.37"
1919
clap = { version = "4.5.13", features = ["derive"] }
2020
chrono = "0.4.38"
2121
ansi-to-tui = "6.0.0"
22+
which = "6.0.3"
2223

2324
# The profile that 'cargo dist' will build with
2425
[profile.dist]

src/app.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use color_eyre::eyre::bail;
33
use config::Config;
44
use logging::Logger;
55
use patch_hub::{lore_api_client::BlockingLoreAPIClient, lore_session, patch::Patch};
6+
use patch_renderer::PatchRenderer;
67
use screens::{
78
bookmarked::BookmarkedPatchsetsState,
89
details_actions::{PatchsetAction, PatchsetDetailsAndActionsState},
@@ -13,6 +14,8 @@ use screens::{
1314
};
1415
use std::collections::HashMap;
1516

17+
use crate::utils;
18+
1619
mod config;
1720
pub mod logging;
1821
pub mod patch_renderer;
@@ -250,4 +253,46 @@ impl App {
250253
pub fn set_current_screen(&mut self, new_current_screen: CurrentScreen) {
251254
self.current_screen = new_current_screen;
252255
}
256+
257+
/// Check if the external dependencies are installed
258+
///
259+
/// If soft dependencies are missing, the application can still run and
260+
/// their absence will only be logged
261+
pub fn check_external_deps(&self) -> bool {
262+
let mut app_can_run = true;
263+
264+
if !utils::binary_exists("b4") {
265+
Logger::error("b4 is not installed, patchsets cannot be downloaded");
266+
app_can_run = false;
267+
}
268+
269+
if !utils::binary_exists("git") {
270+
Logger::warn("git is not installed, send-email won't work");
271+
}
272+
273+
match self.config.patch_renderer() {
274+
PatchRenderer::Bat => {
275+
if !utils::binary_exists("bat") {
276+
Logger::warn("bat is not installed, patch rendering will fallback to default");
277+
}
278+
}
279+
PatchRenderer::Delta => {
280+
if !utils::binary_exists("delta") {
281+
Logger::warn(
282+
"delta is not installed, patch rendering will fallback to default",
283+
);
284+
}
285+
}
286+
PatchRenderer::DiffSoFancy => {
287+
if !utils::binary_exists("diff-so-fancy") {
288+
Logger::warn(
289+
"diff-so-fancy is not installed, patch rendering will fallback to default",
290+
);
291+
}
292+
}
293+
_ => {}
294+
}
295+
296+
app_can_run
297+
}
253298
}

src/handler.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ use std::{
1010
};
1111

1212
use crate::{
13-
app::{screens::CurrentScreen, App},
13+
app::{logging::Logger, screens::CurrentScreen, App},
1414
loading_screen,
1515
ui::draw_ui,
1616
};
1717

1818
use bookmarked::handle_bookmarked_patchsets;
19+
use color_eyre::eyre::bail;
1920
use details_actions::handle_patchset_details;
2021
use edit_config::handle_edit_config;
2122
use latest::handle_latest_patchsets;
@@ -101,6 +102,11 @@ pub fn run_app<B>(mut terminal: Terminal<B>, mut app: App) -> color_eyre::Result
101102
where
102103
B: Backend + Send + 'static,
103104
{
105+
if !app.check_external_deps() {
106+
Logger::error("patch-hub cannot be executed because some dependencies are missing");
107+
bail!("patch-hub cannot be executed because some dependencies are missing, check logs for more information");
108+
}
109+
104110
loop {
105111
terminal.draw(|f| draw_ui(f, &app))?;
106112

src/utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ pub fn teardown_user_io<B: Backend>(terminal: &mut Terminal<B>) -> color_eyre::R
7171
Ok(())
7272
}
7373

74+
#[inline]
75+
/// Simply calls `which` to check if a binary exists
76+
pub fn binary_exists(binary: &str) -> bool {
77+
which::which(binary).is_ok()
78+
}
79+
7480
#[macro_export]
7581
/// Macro that encapsulates a piece of code that takes long to run and displays a loading screen while it runs.
7682
///
@@ -111,3 +117,13 @@ macro_rules! loading_screen {
111117
}
112118
};
113119
}
120+
121+
mod tests {
122+
#[test]
123+
fn test_binary_exists() {
124+
// cargo should always exist since we are running the tests with `cargo test`
125+
assert!(super::binary_exists("cargo"));
126+
// there is no way this binary exists
127+
assert!(!super::binary_exists("there_is_no_way_this_binary_exists"));
128+
}
129+
}

0 commit comments

Comments
 (0)