1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use git_next_config::RemoteUrl;
use tracing::info;

use crate as git;

#[tracing::instrument(skip_all)]
pub fn validate_default_remotes(
    open_repository: &dyn git::repository::OpenRepositoryLike,
    repo_details: &git::RepoDetails,
) -> Result<()> {
    let push_remote = open_repository
        .find_default_remote(git::repository::Direction::Push)
        .ok_or_else(|| Error::NoDefaultPushRemote)?;
    let fetch_remote = open_repository
        .find_default_remote(git::repository::Direction::Fetch)
        .ok_or_else(|| Error::NoDefaultFetchRemote)?;
    let Some(remote_url) = repo_details.remote_url() else {
        return Err(git::validation::remotes::Error::UnableToOpenRepo(
            "Unable to build forge url".to_string(),
        ));
    };
    info!(config = %remote_url, push = %push_remote, fetch = %fetch_remote, "Check remotes match");
    if remote_url != push_remote {
        return Err(Error::MismatchDefaultPushRemote {
            found: push_remote,
            expected: remote_url,
        });
    }
    if remote_url != fetch_remote {
        return Err(Error::MismatchDefaultFetchRemote {
            found: fetch_remote,
            expected: remote_url,
        });
    }
    Ok(())
}

type Result<T> = core::result::Result<T, Error>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("no default push remote")]
    NoDefaultPushRemote,

    #[error("no default fetch remote")]
    NoDefaultFetchRemote,

    #[error("no url for default push remote")]
    NoUrlForDefaultPushRemote,

    #[error("no hostname for default push remote")]
    NoHostnameForDefaultPushRemote,

    #[error("unable to open repo: {0}")]
    UnableToOpenRepo(String),

    #[error("io")]
    Io(#[from] std::io::Error),

    #[error("MismatchDefaultPushRemote(found: {found}, expected: {expected})")]
    MismatchDefaultPushRemote {
        found: RemoteUrl,
        expected: RemoteUrl,
    },

    #[error("MismatchDefaultFetchRemote(found: {found}, expected: {expected})")]
    MismatchDefaultFetchRemote {
        found: RemoteUrl,
        expected: RemoteUrl,
    },

    #[error("Unable to open repo")]
    GixOpen(#[from] gix::open::Error),
}