Part of #11043. Codeberg is a public instance of Forgejo, as confirmed by the API documentation at https://codeberg.org/api/swagger. Therefore, I renamed the related component from codeberg to forgejo and added codeberg.org as a public instance. Furthermore, to optimize request speed for the commit API, I set `stat=false&verification=false&files=false`. <img width="1650" height="1268" alt="CleanShot 2025-11-03 at 19 57 06@2x" src="https://github.com/user-attachments/assets/c1b4129e-f324-41c2-86dc-5e4f7403c046" /> <br/> <br/> Regarding Gitea Support: Forgejo is a fork of Gitea, and their APIs are currently identical (e.g., for getting avatars). However, to future-proof against potential API divergence, I decided to treat them as separate entities. The current gitea implementation is essentially a copy of the forgejo file with the relevant type names and the public instance URL updated. Release Notes: - Added Support for Forgejo and Gitea avatars in git blame
98 lines
3.4 KiB
Rust
98 lines
3.4 KiB
Rust
mod providers;
|
|
mod settings;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use anyhow::Context as _;
|
|
use anyhow::Result;
|
|
use git::GitHostingProviderRegistry;
|
|
use git::repository::GitRepository;
|
|
use gpui::App;
|
|
use url::Url;
|
|
use util::maybe;
|
|
|
|
pub use crate::providers::*;
|
|
pub use crate::settings::*;
|
|
|
|
/// Initializes the Git hosting providers.
|
|
pub fn init(cx: &mut App) {
|
|
crate::settings::init(cx);
|
|
|
|
let provider_registry = GitHostingProviderRegistry::global(cx);
|
|
provider_registry.register_hosting_provider(Arc::new(Bitbucket::public_instance()));
|
|
provider_registry.register_hosting_provider(Arc::new(Chromium));
|
|
provider_registry.register_hosting_provider(Arc::new(Forgejo::public_instance()));
|
|
provider_registry.register_hosting_provider(Arc::new(Gitea::public_instance()));
|
|
provider_registry.register_hosting_provider(Arc::new(Gitee));
|
|
provider_registry.register_hosting_provider(Arc::new(Github::public_instance()));
|
|
provider_registry.register_hosting_provider(Arc::new(Gitlab::public_instance()));
|
|
provider_registry.register_hosting_provider(Arc::new(Sourcehut));
|
|
}
|
|
|
|
/// Registers additional Git hosting providers.
|
|
///
|
|
/// These require information from the Git repository to construct, so their
|
|
/// registration is deferred until we have a Git repository initialized.
|
|
pub fn register_additional_providers(
|
|
provider_registry: Arc<GitHostingProviderRegistry>,
|
|
repository: Arc<dyn GitRepository>,
|
|
) {
|
|
let Some(origin_url) = repository.remote_url("origin") else {
|
|
return;
|
|
};
|
|
|
|
if let Ok(gitlab_self_hosted) = Gitlab::from_remote_url(&origin_url) {
|
|
provider_registry.register_hosting_provider(Arc::new(gitlab_self_hosted));
|
|
} else if let Ok(github_self_hosted) = Github::from_remote_url(&origin_url) {
|
|
provider_registry.register_hosting_provider(Arc::new(github_self_hosted));
|
|
} else if let Ok(forgejo_self_hosted) = Forgejo::from_remote_url(&origin_url) {
|
|
provider_registry.register_hosting_provider(Arc::new(forgejo_self_hosted));
|
|
} else if let Ok(gitea_self_hosted) = Gitea::from_remote_url(&origin_url) {
|
|
provider_registry.register_hosting_provider(Arc::new(gitea_self_hosted));
|
|
}
|
|
}
|
|
|
|
pub fn get_host_from_git_remote_url(remote_url: &str) -> Result<String> {
|
|
maybe!({
|
|
if let Some(remote_url) = remote_url.strip_prefix("git@")
|
|
&& let Some((host, _)) = remote_url.trim_start_matches("git@").split_once(':')
|
|
{
|
|
return Some(host.to_string());
|
|
}
|
|
|
|
Url::parse(remote_url)
|
|
.ok()
|
|
.and_then(|remote_url| remote_url.host_str().map(|host| host.to_string()))
|
|
})
|
|
.context("URL has no host")
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::get_host_from_git_remote_url;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn test_get_host_from_git_remote_url() {
|
|
let tests = [
|
|
(
|
|
"https://jlannister@github.com/some-org/some-repo.git",
|
|
Some("github.com".to_string()),
|
|
),
|
|
(
|
|
"git@github.com:zed-industries/zed.git",
|
|
Some("github.com".to_string()),
|
|
),
|
|
(
|
|
"git@my.super.long.subdomain.com:zed-industries/zed.git",
|
|
Some("my.super.long.subdomain.com".to_string()),
|
|
),
|
|
];
|
|
|
|
for (remote_url, expected_host) in tests {
|
|
let host = get_host_from_git_remote_url(remote_url).ok();
|
|
assert_eq!(host, expected_host);
|
|
}
|
|
}
|
|
}
|