[+] Forgejo (#3)

* [+] Forgejo, tangled

* [-] Tangled
This commit is contained in:
2026-05-07 00:45:01 -04:00
committed by GitHub
parent 39ba96051c
commit 7b65d919d6
5 changed files with 93 additions and 8 deletions
+31 -4
View File
@@ -369,7 +369,7 @@ fn matching_sites<'a>(config: &'a Config, target: &ProfileTarget) -> Vec<&'a Sit
}
fn prompt_provider_styled(theme: &ColorfulTheme, base_url: &str) -> Result<ProviderKind> {
let options = ["GitHub", "GitLab", "Gitea"];
let options = ["GitHub", "GitLab", "Gitea", "Forgejo"];
let index = Select::with_theme(theme)
.with_prompt(format!("Provider for {base_url}"))
.items(options)
@@ -378,7 +378,8 @@ fn prompt_provider_styled(theme: &ColorfulTheme, base_url: &str) -> Result<Provi
Ok(match index {
0 => ProviderKind::Github,
1 => ProviderKind::Gitlab,
_ => ProviderKind::Gitea,
2 => ProviderKind::Gitea,
_ => ProviderKind::Forgejo,
})
}
@@ -477,6 +478,11 @@ fn pat_instruction_lines(provider: &ProviderKind, base_url: &str) -> Vec<String>
format!("Open: {url}"),
"Generate a new token, allow repository access, then paste it here.".to_string(),
],
ProviderKind::Forgejo => vec![
"Create a personal access token with repository permissions.".to_string(),
format!("Open: {url}"),
"Generate a new token, allow repository access, then paste it here.".to_string(),
],
}
}
@@ -686,7 +692,11 @@ where
"github" => return Ok(ProviderKind::Github),
"gitlab" => return Ok(ProviderKind::Gitlab),
"gitea" => return Ok(ProviderKind::Gitea),
_ => writeln!(writer, "Provider must be github, gitlab, or gitea.")?,
"forgejo" => return Ok(ProviderKind::Forgejo),
_ => writeln!(
writer,
"Provider must be github, gitlab, gitea, or forgejo."
)?,
}
}
}
@@ -842,6 +852,8 @@ fn known_provider_from_host(host: &str) -> Option<ProviderKind> {
Some(ProviderKind::Github)
} else if host == "gitlab.com" || host.ends_with(".gitlab.com") || host.contains("gitlab") {
Some(ProviderKind::Gitlab)
} else if host == "codeberg.org" || host.contains("forgejo") {
Some(ProviderKind::Forgejo)
} else if host.contains("gitea") {
Some(ProviderKind::Gitea)
} else {
@@ -855,6 +867,14 @@ fn detect_provider_from_instance(base_url: &str) -> Option<ProviderKind> {
.build()
.ok()?;
let base = trim_url_end(base_url);
if client
.get(format!("{base}/api/forgejo/v1/version"))
.send()
.ok()
.is_some_and(|response| response.status().is_success())
{
return Some(ProviderKind::Forgejo);
}
if client
.get(format!("{base}/api/v1/version"))
.send()
@@ -937,7 +957,7 @@ fn detect_namespace_kind_public(
.is_some_and(|items| !items.is_empty())
.then_some(NamespaceKind::User)
}
ProviderKind::Gitea => {
ProviderKind::Gitea | ProviderKind::Forgejo => {
if client
.get(format!("{api_base}/orgs/{namespace}"))
.send()
@@ -1003,6 +1023,7 @@ fn default_base_url(provider: &ProviderKind) -> &'static str {
ProviderKind::Github => "https://github.com",
ProviderKind::Gitlab => "https://gitlab.com",
ProviderKind::Gitea => "https://gitea.example.com",
ProviderKind::Forgejo => "https://forgejo.example.com",
}
}
@@ -1065,6 +1086,7 @@ fn provider_slug(provider: &ProviderKind) -> &'static str {
ProviderKind::Github => "github",
ProviderKind::Gitlab => "gitlab",
ProviderKind::Gitea => "gitea",
ProviderKind::Forgejo => "forgejo",
}
}
@@ -1078,6 +1100,7 @@ fn token_creation_url(provider: &ProviderKind, base_url: &str) -> String {
format!("{base}/-/user_settings/personal_access_tokens?name=git-sync&scopes=api")
}
ProviderKind::Gitea => format!("{base}/user/settings/applications"),
ProviderKind::Forgejo => format!("{base}/user/settings/applications"),
}
}
@@ -1449,5 +1472,9 @@ mod tests {
token_creation_url(&ProviderKind::Gitea, "gitea.example.test"),
"https://gitea.example.test/user/settings/applications"
);
assert_eq!(
token_creation_url(&ProviderKind::Forgejo, "forgejo.example.test"),
"https://forgejo.example.test/user/settings/applications"
);
}
}