cargolifter_backend_gitlab/
lib.rs

1mod api;
2mod models;
3
4use async_trait::async_trait;
5use cargolifter_core::models::PublishedVersion;
6use cargolifter_core::Backend;
7
8pub struct Gitlab {
9    cargolifter_token: Option<String>,
10    project_id: usize,
11    host: Option<String>,
12    default_branch: String,
13}
14
15impl Gitlab {
16    pub fn from(config: cargolifter_core::config::GitlabConfig) -> Self {
17        Self {
18            cargolifter_token: config.cargolifter_token,
19            project_id: config.project_id,
20            host: config.host.clone(),
21            default_branch: config
22                .default_branch
23                .unwrap_or_else(|| String::from("main")),
24        }
25    }
26
27    fn host(&self) -> String {
28        let default_host = String::from("https://gitlab.com");
29        self.host.as_ref().unwrap_or(&default_host).into()
30    }
31}
32
33#[async_trait]
34impl Backend for Gitlab {
35    async fn get_file(
36        &self,
37        token: &str,
38        crate_path: &str,
39    ) -> Result<(String, String, String), reqwest::Error> {
40        let host = self.host();
41
42        match api::get_file(
43            &host,
44            token,
45            self.project_id,
46            &crate_path,
47            &self.default_branch,
48        )
49        .await
50        {
51            Ok(response) => Ok((
52                response.content, 
53                response.encoding,
54                response.content_sha256,
55            )),
56            Err(e) => Err(e),
57        }
58    }
59
60    async fn create_file(
61        &self,
62        token: &str,
63        crate_path: &str,
64        branch_name: &str,
65        initial_version: &PublishedVersion,
66    ) -> Result<(), reqwest::Error> {
67        let host = self.host();
68
69        let json = serde_json::to_string(&initial_version).unwrap();
70        let encoded_content = base64::encode(json);
71        let create_request = crate::models::create_file::Request {
72            branch: branch_name.into(),
73            start_branch: Some(self.default_branch.clone()),
74            content: encoded_content,
75            encoding: Some("base64".into()),
76            commit_message: format!("Adding {} {}", initial_version.name, initial_version.vers),
77            ..Default::default()
78        };
79
80        match api::create_file(&host, token, self.project_id, &crate_path, &create_request).await {
81            Ok(_) => Ok(()),
82            Err(e) => Err(e),
83        }
84    }
85
86    async fn update_file(
87        &self,
88        token: &str,
89        crate_path: &str,
90        branch_name: &str,
91        versions: &[PublishedVersion],
92        _current_sha: &str,
93    ) -> Result<(), reqwest::Error> {
94        let host = self.host();
95
96        let new_content = versions
97            .iter()
98            .map(|v| serde_json::to_string(v).unwrap())
99            .collect::<Vec<String>>()
100            .join("\n");
101
102        let update_request = crate::models::update_file::Request {
103            branch: branch_name.into(),
104            start_branch: Some(self.default_branch.clone()),
105            content: base64::encode(new_content),
106            encoding: Some("base64".into()),
107            commit_message: format!("Adding {} {}", versions[0].name, versions[0].vers),
108            ..Default::default()
109        };
110        match api::update_file(&host, token, self.project_id, &crate_path, &update_request).await {
111            Ok(_) => Ok(()),
112            Err(e) => Err(e),
113        }
114    }
115
116    async fn delete_branch(
117        &self,
118        token: &str,
119        branch_name: &str,
120    ) -> Result<(), reqwest::Error>
121    {
122        let host = self.host();
123
124        match api::delete_branch(&host, token, self.project_id, &branch_name.clone()).await {
125            Ok(_) => Ok(()),
126            Err(e) => Err(e),
127        }
128    }
129
130    async fn create_pull_request(
131        &self,
132        token: &str,
133        title: &str,
134        branch_name: &str,
135    ) -> Result<u64, reqwest::Error> {
136        let host = self.host();
137
138        let merge_request = models::create_merge_request::Request {
139            source_branch: branch_name.into(),
140            target_branch: self.default_branch.clone(),
141            title: title.into(),
142            remove_source_branch: Some(false),
143            ..Default::default()
144        };
145        match api::create_merge_request(&host, token, self.project_id, &merge_request).await {
146            Ok(response) => {
147                Ok(response.iid)
148            },
149            Err(e) => Err(e),
150        }
151    }
152
153    async fn merge_pull_request(
154        &self,
155        token: &str,
156        id: u64,
157    ) -> Result<(), reqwest::Error> {
158        let host = self.host();
159
160        let owned_token = token.to_owned();
161        let merge_token = self.cargolifter_token.as_ref().unwrap_or(&owned_token);
162
163        let accept_request = models::accept_merge_request::Request {
164            should_remove_source_branch: Some(false),
165            ..Default::default()
166        };
167
168        match api::accept_merge_request(
169            &host,
170            merge_token,
171            self.project_id,
172            id,
173            &accept_request,
174        )
175        .await
176        {
177            Ok(_) => Ok(()),
178            Err(e) => Err(e),
179        }
180    }
181
182    async fn delete_pull_request(
183        &self,
184        _token: &str,
185        _id: u64,
186    ) -> Result<(), reqwest::Error> {
187        Ok(())
188    }
189}