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, SettingsStore};
 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 = GitHostingProviderSettings::get_global(cx);
29    let provider_registry = GitHostingProviderRegistry::global(cx);
30
31    for provider in settings.git_hosting_providers.iter() {
32        let Some(url) = Url::parse(&provider.base_url).log_err() else {
33            continue;
34        };
35
36        let provider = match provider.provider {
37            GitHostingProviderKind::Bitbucket => Arc::new(Bitbucket::new(&provider.name, url)) as _,
38            GitHostingProviderKind::Github => Arc::new(Github::new(&provider.name, url)) as _,
39            GitHostingProviderKind::Gitlab => Arc::new(Gitlab::new(&provider.name, url)) as _,
40        };
41
42        provider_registry.register_hosting_provider(provider);
43    }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
47#[serde(rename_all = "snake_case")]
48pub enum GitHostingProviderKind {
49    Github,
50    Gitlab,
51    Bitbucket,
52}
53
54/// A custom Git hosting provider.
55#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
56pub struct GitHostingProviderConfig {
57    /// The type of the provider.
58    ///
59    /// Must be one of `github`, `gitlab`, or `bitbucket`.
60    pub provider: GitHostingProviderKind,
61
62    /// The base URL for the provider (e.g., "https://code.corp.big.com").
63    pub base_url: String,
64
65    /// The display name for the provider (e.g., "BigCorp GitHub").
66    pub name: String,
67}
68
69#[derive(Default, Clone, Serialize, Deserialize, JsonSchema)]
70pub struct GitHostingProviderSettings {
71    /// The list of custom Git hosting providers.
72    #[serde(default)]
73    pub git_hosting_providers: Vec<GitHostingProviderConfig>,
74}
75
76impl Settings for GitHostingProviderSettings {
77    const KEY: Option<&'static str> = None;
78
79    type FileContent = Self;
80
81    fn load(sources: settings::SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
82        sources.json_merge()
83    }
84
85    fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
86}