cargolifter_backend_gitlab/
lib.rs1mod 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}