gitee_cli_rs/api/
releases.rs1use super::client::Client;
2use crate::error::Result;
3use crate::models::{Release, ReleaseAsset};
4use crate::repo::Repo;
5
6pub struct Releases<'a> {
7 client: &'a Client,
8 repo: &'a Repo,
9}
10
11
12pub struct EditRelease<'a> {
13 pub name: Option<&'a str>,
14 pub notes: Option<&'a str>,
15 pub prerelease: Option<bool>,
16}
17
18pub struct CreateRelease<'a> {
19 pub tag: &'a str,
20 pub name: Option<&'a str>,
21 pub notes: Option<&'a str>,
22 pub target: Option<&'a str>,
23 pub prerelease: bool,
24}
25
26impl Releases<'_> {
27 pub(crate) fn new<'a>(client: &'a Client, repo: &'a Repo) -> Releases<'a> {
28 Releases { client, repo }
29 }
30
31 pub fn list(&self, limit: usize) -> Result<Vec<Release>> {
32 let o = self.repo.owner.as_str();
33 let r = self.repo.name.as_str();
34 let path = format!("/repos/{o}/{r}/releases");
35 self.client.get_paged(&path, &[], limit)
36 }
37
38 pub fn get_by_tag(&self, tag: &str) -> Result<Release> {
41 let o = self.repo.owner.as_str();
42 let r = self.repo.name.as_str();
43 let rel: Option<Release> = self
44 .client
45 .get(&format!("/repos/{o}/{r}/releases/tags/{tag}"), &[])?;
46 rel.ok_or_else(|| {
47 crate::error::GiteeError::NotFound(format!("release {tag}"))
48 })
49 }
50
51 pub fn create(&self, req: &CreateRelease<'_>) -> Result<Release> {
55 let o = self.repo.owner.as_str();
56 let r = self.repo.name.as_str();
57 let display_name = req.name.unwrap_or(req.tag);
58 let mut f: Vec<(&str, String)> = vec![
59 ("tag_name", req.tag.to_string()),
60 ("name", display_name.to_string()),
61 ("body", req.notes.unwrap_or(display_name).to_string()),
62 ];
63 if let Some(t) = req.target {
64 f.push(("target_commitish", t.to_string()));
65 }
66 f.push(("prerelease", Client::bool_str(req.prerelease).to_string()));
67 let form = Client::str_refs(&f);
68 self.client.post(&format!("/repos/{o}/{r}/releases"), &form)
69 }
70
71
72 pub fn edit(&self, tag: &str, req: &EditRelease<'_>) -> Result<Release> {
77 let current = self.get_by_tag(tag)?;
78 let o = self.repo.owner.as_str();
79 let r = self.repo.name.as_str();
80 let display_name = req
81 .name
82 .or(current.name.as_deref())
83 .unwrap_or(tag);
84 let body = req
85 .notes
86 .or(current.body.as_deref())
87 .unwrap_or(display_name);
88 let mut f: Vec<(&str, String)> = vec![
89 ("tag_name", tag.to_string()),
90 ("name", display_name.to_string()),
91 ("body", body.to_string()),
92 ];
93 if req.prerelease == Some(true) {
94 f.push(("prerelease", "true".to_string()));
95 }
96 let form = Client::str_refs(&f);
97 self.client
98 .patch(&format!("/repos/{o}/{r}/releases/{}", current.id), &form)
99 }
100
101 pub fn delete(&self, tag: &str) -> Result<()> {
102 let release = self.get_by_tag(tag)?;
103 let o = self.repo.owner.as_str();
104 let r = self.repo.name.as_str();
105 self.client
106 .delete_ok(&format!("/repos/{o}/{r}/releases/{}", release.id))
107 }
108
109 pub fn upload(&self, tag: &str, file_path: &str) -> Result<ReleaseAsset> {
114 let o = self.repo.owner.as_str();
115 let r = self.repo.name.as_str();
116 let release = self.get_by_tag(tag)?;
117 let id = release.id;
118 self.client.post_multipart(
119 &format!("/repos/{o}/{r}/releases/{id}/attach_files"),
120 file_path,
121 )
122 }
123}