git_next_core/git/validation/
remotes.rs1use crate::{
3 git::{self, repository::open::OpenRepositoryLike},
4 s, RemoteUrl,
5};
6
7#[tracing::instrument(skip_all)]
8pub fn validate_default_remotes(
9 open_repository: &dyn OpenRepositoryLike,
10 repo_details: &git::RepoDetails,
11) -> Result<()> {
12 let push_remote = open_repository
13 .find_default_remote(git::repository::Direction::Push)
14 .ok_or(Error::NoDefaultPushRemote)?;
15 let fetch_remote = open_repository
16 .find_default_remote(git::repository::Direction::Fetch)
17 .ok_or(Error::NoDefaultFetchRemote)?;
18 let Some(remote_url) = repo_details.remote_url() else {
19 return Err(git::validation::remotes::Error::UnableToOpenRepo(s!(
20 "Unable to build forge url"
21 )));
22 };
23 if !remote_url.matches(&push_remote) {
24 return Err(Error::MismatchDefaultPushRemote {
25 found: push_remote,
26 expected: remote_url,
27 });
28 }
29 if !remote_url.matches(&fetch_remote) {
30 return Err(Error::MismatchDefaultFetchRemote {
31 found: fetch_remote,
32 expected: remote_url,
33 });
34 }
35 Ok(())
36}
37
38type Result<T> = core::result::Result<T, Error>;
39#[derive(Debug, thiserror::Error)]
40pub enum Error {
41 #[error("no default push remote")]
42 NoDefaultPushRemote,
43
44 #[error("no default fetch remote")]
45 NoDefaultFetchRemote,
46
47 #[error("no url for default push remote")]
48 NoUrlForDefaultPushRemote,
49
50 #[error("no hostname for default push remote")]
51 NoHostnameForDefaultPushRemote,
52
53 #[error("unable to open repo: {0}")]
54 UnableToOpenRepo(String),
55
56 #[error("io")]
57 Io(#[from] std::io::Error),
58
59 #[error("MismatchDefaultPushRemote(found: {found}, expected: {expected})")]
60 MismatchDefaultPushRemote {
61 found: RemoteUrl,
62 expected: RemoteUrl,
63 },
64
65 #[error("MismatchDefaultFetchRemote(found: {found}, expected: {expected})")]
66 MismatchDefaultFetchRemote {
67 found: RemoteUrl,
68 expected: RemoteUrl,
69 },
70
71 #[error("Unable to open repo")]
72 GixOpen(#[from] gix::open::Error),
73}