|
1 | 1 | use std::cell::OnceCell; |
2 | 2 |
|
| 3 | +pub use releasekit::Release as ReleaseInfo; |
3 | 4 | use releasekit::client::UreqClient; |
4 | 5 | use releasekit::platform::{GitHub, GitLab, Gitea}; |
5 | 6 | use releasekit::{Filter, Forge, Release}; |
@@ -56,64 +57,83 @@ impl ForgeUpdateInfo { |
56 | 57 | Ok(self.resolved_url.get().unwrap()) |
57 | 58 | } |
58 | 59 |
|
| 60 | + pub fn list_releases(&self) -> Result<Vec<Release>> { |
| 61 | + let project = format!("{}/{}", self.owner, self.repo); |
| 62 | + self.with_forge(|forge| { |
| 63 | + forge |
| 64 | + .fetch_releases(&project, None) |
| 65 | + .map_err(|e| Error::ForgeApi(e.to_string())) |
| 66 | + }) |
| 67 | + } |
| 68 | + |
59 | 69 | fn resolve_url(&self) -> Result<String> { |
| 70 | + self.with_forge(|forge| self.fetch_with_forge(forge)) |
| 71 | + } |
| 72 | + |
| 73 | + fn with_forge<T>(&self, action: impl Fn(&dyn Forge) -> Result<T>) -> Result<T> { |
60 | 74 | match &self.kind { |
61 | | - ForgeKind::GitHub => self.resolve_with_proxies( |
| 75 | + ForgeKind::GitHub => self.with_forge_proxied( |
62 | 76 | config::get_github_proxies(), |
63 | 77 | |base| { |
64 | 78 | GitHub::new(UreqClient) |
65 | 79 | .with_base_url(base) |
66 | 80 | .with_token_from_env(&["GITHUB_TOKEN", "GH_TOKEN"]) |
67 | 81 | }, |
68 | 82 | || GitHub::new(UreqClient).with_token_from_env(&["GITHUB_TOKEN", "GH_TOKEN"]), |
| 83 | + &action, |
69 | 84 | ), |
70 | | - ForgeKind::GitLab => self.resolve_with_proxies( |
| 85 | + ForgeKind::GitLab => self.with_forge_proxied( |
71 | 86 | config::get_gitlab_proxies(), |
72 | 87 | |base| { |
73 | 88 | GitLab::new(UreqClient) |
74 | 89 | .with_base_url(base) |
75 | 90 | .with_token_from_env(&["GITLAB_TOKEN", "GL_TOKEN"]) |
76 | 91 | }, |
77 | 92 | || GitLab::new(UreqClient).with_token_from_env(&["GITLAB_TOKEN", "GL_TOKEN"]), |
| 93 | + &action, |
78 | 94 | ), |
79 | | - ForgeKind::Codeberg => self.resolve_with_proxies( |
| 95 | + ForgeKind::Codeberg => self.with_forge_proxied( |
80 | 96 | config::get_codeberg_proxies(), |
81 | 97 | |base| Gitea::new(UreqClient, base).with_token_from_env(&["CODEBERG_TOKEN"]), |
82 | 98 | || { |
83 | 99 | Gitea::new(UreqClient, "https://codeberg.org") |
84 | 100 | .with_token_from_env(&["CODEBERG_TOKEN"]) |
85 | 101 | }, |
| 102 | + &action, |
86 | 103 | ), |
87 | 104 | ForgeKind::Gitea { instance } => { |
88 | 105 | let gt = Gitea::new(UreqClient, format!("https://{instance}")) |
89 | 106 | .with_token_from_env(&["GITEA_TOKEN"]); |
90 | | - self.fetch_with_forge(gt) |
| 107 | + action(>) |
91 | 108 | } |
92 | 109 | } |
93 | 110 | } |
94 | 111 |
|
95 | | - fn resolve_with_proxies<F: Forge>( |
| 112 | + fn with_forge_proxied<F: Forge, T>( |
96 | 113 | &self, |
97 | 114 | proxies: Vec<String>, |
98 | 115 | make_proxy: impl Fn(&str) -> F, |
99 | 116 | make_default: impl FnOnce() -> F, |
100 | | - ) -> Result<String> { |
| 117 | + action: &impl Fn(&dyn Forge) -> Result<T>, |
| 118 | + ) -> Result<T> { |
101 | 119 | if proxies.is_empty() { |
102 | | - return self.fetch_with_forge(make_default()); |
| 120 | + let forge = make_default(); |
| 121 | + return action(&forge); |
103 | 122 | } |
104 | 123 |
|
105 | 124 | let mut last_error = None; |
106 | 125 | for proxy in &proxies { |
107 | | - match self.fetch_with_forge(make_proxy(proxy)) { |
108 | | - Ok(url) => return Ok(url), |
| 126 | + let forge = make_proxy(proxy); |
| 127 | + match action(&forge) { |
| 128 | + Ok(v) => return Ok(v), |
109 | 129 | Err(e) => last_error = Some(e), |
110 | 130 | } |
111 | 131 | } |
112 | 132 |
|
113 | 133 | Err(last_error.unwrap_or_else(|| Error::ForgeApi("All proxies failed".into()))) |
114 | 134 | } |
115 | 135 |
|
116 | | - fn fetch_with_forge(&self, forge: impl Forge) -> Result<String> { |
| 136 | + fn fetch_with_forge(&self, forge: &dyn Forge) -> Result<String> { |
117 | 137 | let project = format!("{}/{}", self.owner, self.repo); |
118 | 138 |
|
119 | 139 | let (tag, find_prerelease) = match self.tag.as_str() { |
|
0 commit comments