settings.rs

 1use std::sync::Arc;
 2
 3use anyhow::Result;
 4use git::GitHostingProviderRegistry;
 5use gpui::App;
 6use schemars::JsonSchema;
 7use serde::{Deserialize, Serialize};
 8use settings::{Settings, SettingsKey, SettingsStore, SettingsUi};
 9use url::Url;
10use util::ResultExt as _;
11
12use crate::{Bitbucket, Github, Gitlab};
13
14pub(crate) fn init(cx: &mut App) {
15    GitHostingProviderSettings::register(cx);
16
17    init_git_hosting_provider_settings(cx);
18}
19
20fn init_git_hosting_provider_settings(cx: &mut App) {
21    update_git_hosting_providers_from_settings(cx);
22
23    cx.observe_global::<SettingsStore>(update_git_hosting_providers_from_settings)
24        .detach();
25}
26
27fn update_git_hosting_providers_from_settings(cx: &mut App) {
28    let settings_store = cx.global::<SettingsStore>();
29    let settings = GitHostingProviderSettings::get_global(cx);
30    let provider_registry = GitHostingProviderRegistry::global(cx);
31
32    let local_values: Vec<GitHostingProviderConfig> = settings_store
33        .get_all_locals::<GitHostingProviderSettings>()
34        .into_iter()
35        .flat_map(|(_, _, providers)| providers.git_hosting_providers.clone())
36        .collect();
37
38    let iter = settings
39        .git_hosting_providers
40        .clone()
41        .into_iter()
42        .chain(local_values)
43        .filter_map(|provider| {
44            let url = Url::parse(&provider.base_url).log_err()?;
45
46            Some(match provider.provider {
47                GitHostingProviderKind::Bitbucket => {
48                    Arc::new(Bitbucket::new(&provider.name, url)) as _
49                }
50                GitHostingProviderKind::Github => Arc::new(Github::new(&provider.name, url)) as _,
51                GitHostingProviderKind::Gitlab => Arc::new(Gitlab::new(&provider.name, url)) as _,
52            })
53        });
54
55    provider_registry.set_setting_providers(iter);
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
59#[serde(rename_all = "snake_case")]
60pub enum GitHostingProviderKind {
61    Github,
62    Gitlab,
63    Bitbucket,
64}
65
66/// A custom Git hosting provider.
67#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
68pub struct GitHostingProviderConfig {
69    /// The type of the provider.
70    ///
71    /// Must be one of `github`, `gitlab`, or `bitbucket`.
72    pub provider: GitHostingProviderKind,
73
74    /// The base URL for the provider (e.g., "https://code.corp.big.com").
75    pub base_url: String,
76
77    /// The display name for the provider (e.g., "BigCorp GitHub").
78    pub name: String,
79}
80
81#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, SettingsUi, SettingsKey)]
82#[settings_key(None)]
83pub struct GitHostingProviderSettings {
84    /// The list of custom Git hosting providers.
85    #[serde(default)]
86    pub git_hosting_providers: Vec<GitHostingProviderConfig>,
87}
88
89impl Settings for GitHostingProviderSettings {
90    type FileContent = Self;
91
92    fn load(sources: settings::SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
93        sources.json_merge()
94    }
95
96    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
97}