1use std::sync::Arc;
2
3use git::GitHostingProviderRegistry;
4use gpui::App;
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7use settings::{
8 GitHostingProviderConfig, GitHostingProviderKind, Settings, SettingsKey, SettingsStore,
9 SettingsUi,
10};
11use url::Url;
12use util::ResultExt as _;
13
14use crate::{Bitbucket, Github, Gitlab};
15
16pub(crate) fn init(cx: &mut App) {
17 GitHostingProviderSettings::register(cx);
18
19 init_git_hosting_provider_settings(cx);
20}
21
22fn init_git_hosting_provider_settings(cx: &mut App) {
23 update_git_hosting_providers_from_settings(cx);
24
25 cx.observe_global::<SettingsStore>(update_git_hosting_providers_from_settings)
26 .detach();
27}
28
29fn update_git_hosting_providers_from_settings(cx: &mut App) {
30 let settings_store = cx.global::<SettingsStore>();
31 let settings = GitHostingProviderSettings::get_global(cx);
32 let provider_registry = GitHostingProviderRegistry::global(cx);
33
34 let local_values: Vec<GitHostingProviderConfig> = settings_store
35 .get_all_locals::<GitHostingProviderSettings>()
36 .into_iter()
37 .flat_map(|(_, _, providers)| providers.git_hosting_providers.clone())
38 .collect();
39
40 let iter = settings
41 .git_hosting_providers
42 .clone()
43 .into_iter()
44 .chain(local_values)
45 .filter_map(|provider| {
46 let url = Url::parse(&provider.base_url).log_err()?;
47
48 Some(match provider.provider {
49 GitHostingProviderKind::Bitbucket => {
50 Arc::new(Bitbucket::new(&provider.name, url)) as _
51 }
52 GitHostingProviderKind::Github => Arc::new(Github::new(&provider.name, url)) as _,
53 GitHostingProviderKind::Gitlab => Arc::new(Gitlab::new(&provider.name, url)) as _,
54 })
55 });
56
57 provider_registry.set_setting_providers(iter);
58}
59
60#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, SettingsUi, SettingsKey)]
61#[settings_key(None)]
62pub struct GitHostingProviderSettings {
63 /// The list of custom Git hosting providers.
64 #[serde(default)]
65 pub git_hosting_providers: Vec<GitHostingProviderConfig>,
66}
67
68impl Settings for GitHostingProviderSettings {
69 fn from_default(content: &settings::SettingsContent, _cx: &mut App) -> Option<Self> {
70 Some(Self {
71 git_hosting_providers: content.git_hosting_providers.clone()?,
72 })
73 }
74
75 fn refine(&mut self, content: &settings::SettingsContent, _: &mut App) {
76 if let Some(more) = &content.git_hosting_providers {
77 self.git_hosting_providers.extend_from_slice(&more.clone());
78 }
79 }
80
81 fn import_from_vscode(_: &settings::VsCodeSettings, _: &mut settings::SettingsContent) {}
82}