Skip to main content

heddle_core/fsck/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2//! Repository integrity checks.
3
4mod bridge;
5mod objects;
6mod refs;
7mod repair;
8mod state;
9#[cfg(test)]
10mod tests;
11
12use ::objects::{HeddleError, error::Result};
13use serde::Serialize;
14
15use crate::ExecutionContext;
16
17#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
18pub struct FsckOptions {
19    pub full: bool,
20    pub thorough: bool,
21    pub repair: bool,
22    pub bridge: bool,
23}
24
25#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
26pub struct FsckReport {
27    pub valid: bool,
28    pub errors: Vec<FsckError>,
29    pub warnings: Vec<String>,
30    pub objects_checked: usize,
31    pub bridge_checked: bool,
32}
33
34#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
35pub struct FsckError {
36    pub kind: String,
37    pub message: String,
38    pub object: Option<String>,
39}
40
41fn make_error(kind: &str, message: &str, object: Option<String>) -> FsckError {
42    FsckError {
43        kind: kind.to_string(),
44        message: message.to_string(),
45        object,
46    }
47}
48
49pub fn fsck(ctx: &ExecutionContext, opts: FsckOptions) -> Result<FsckReport> {
50    let repo = ctx.require_repo()?;
51
52    let mut errors: Vec<FsckError> = Vec::new();
53    let mut warnings: Vec<String> = Vec::new();
54    let mut objects_checked: usize = 0;
55
56    state::check_states(repo, &mut errors, &mut objects_checked, opts.thorough)?;
57
58    if opts.full {
59        objects::check_trees(repo, &mut errors, &mut warnings, &mut objects_checked)?;
60        objects::check_blobs(repo, &mut errors, &mut warnings, &mut objects_checked)?;
61    }
62
63    refs::check_refs(repo, &mut errors, &mut warnings)?;
64    refs::check_merge_state(repo, &mut warnings)?;
65    if opts.bridge {
66        bridge::check_bridge(repo, &mut errors, &mut warnings, &mut objects_checked)?;
67    }
68
69    let valid = errors.is_empty();
70
71    if opts.repair && !valid {
72        repair::repair_issues(repo, &errors)?;
73    }
74
75    Ok(FsckReport {
76        valid,
77        errors,
78        warnings,
79        objects_checked,
80        bridge_checked: opts.bridge,
81    })
82}
83
84fn invalid_fsck_config(message: impl Into<String>) -> HeddleError {
85    HeddleError::Config(message.into())
86}