lean_ctx/core/providers/
config.rs1use std::env;
2
3#[derive(Debug, Clone)]
4pub struct GitLabConfig {
5 pub host: String,
6 pub token: String,
7 pub project_path: Option<String>,
8}
9
10impl GitLabConfig {
11 pub fn from_env() -> Result<Self, String> {
12 let token = env::var("LEAN_CTX_GITLAB_TOKEN")
13 .or_else(|_| env::var("GITLAB_TOKEN"))
14 .or_else(|_| env::var("CI_JOB_TOKEN"))
15 .map_err(|_| {
16 "No GitLab token found. Set GITLAB_TOKEN or LEAN_CTX_GITLAB_TOKEN.".to_string()
17 })?;
18
19 let host = env::var("GITLAB_HOST")
20 .or_else(|_| env::var("CI_SERVER_HOST"))
21 .unwrap_or_else(|_| "gitlab.com".to_string());
22
23 let project_path = env::var("CI_PROJECT_PATH")
24 .ok()
25 .or_else(|| detect_project_from_git_remote(&host));
26
27 Ok(Self {
28 host,
29 token,
30 project_path,
31 })
32 }
33
34 pub fn api_url(&self, endpoint: &str) -> String {
35 format!("https://{}/api/v4{}", self.host, endpoint)
36 }
37}
38
39fn detect_project_from_git_remote(host: &str) -> Option<String> {
40 let output = std::process::Command::new("git")
41 .args(["remote", "get-url", "origin"])
42 .output()
43 .ok()?;
44 if !output.status.success() {
45 return None;
46 }
47 let url = String::from_utf8_lossy(&output.stdout).trim().to_string();
48
49 if let Some(rest) = url.strip_prefix(&format!("git@{host}:")) {
51 return Some(rest.trim_end_matches(".git").to_string());
52 }
53 if let Some(rest) = url.strip_prefix(&format!("https://{host}/")) {
55 return Some(rest.trim_end_matches(".git").to_string());
56 }
57 None
58}