pare-down-functionality #7
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "gitea"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Christine Dodrill <me@christine.website>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
thiserror = "1"
|
||||||
|
reqwest = { version = "0.10", features = ["json"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
|
@ -0,0 +1,241 @@
|
||||||
|
use reqwest::header;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::result::Result as StdResult;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("error from reqwest: {0:#?}")]
|
||||||
|
Reqwest(#[from] reqwest::Error),
|
||||||
|
|
||||||
|
#[error("bad API token: {0:#?}")]
|
||||||
|
BadAPIToken(#[from] reqwest::header::InvalidHeaderValue),
|
||||||
|
|
||||||
|
#[error("error parsing/serializing json: {0:#?}")]
|
||||||
|
Json(#[from] serde_json::Error),
|
||||||
|
|
||||||
|
#[error("tag not found: {0}")]
|
||||||
|
TagNotFound(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Result<T> = StdResult<T, Error>;
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Author {
|
||||||
|
pub id: i64,
|
||||||
|
pub login: String,
|
||||||
|
pub full_name: String,
|
||||||
|
pub email: String,
|
||||||
|
pub avatar_url: String,
|
||||||
|
pub language: String,
|
||||||
|
pub is_admin: bool,
|
||||||
|
pub last_login: String,
|
||||||
|
pub created: String,
|
||||||
|
pub username: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Release {
|
||||||
|
pub id: i64,
|
||||||
|
pub tag_name: String,
|
||||||
|
pub target_commitish: String,
|
||||||
|
pub name: String,
|
||||||
|
pub body: String,
|
||||||
|
pub url: String,
|
||||||
|
pub tarball_url: String,
|
||||||
|
pub zipball_url: String,
|
||||||
|
pub draft: bool,
|
||||||
|
pub prerelease: bool,
|
||||||
|
pub created_at: String,
|
||||||
|
pub published_at: String,
|
||||||
|
pub author: Author,
|
||||||
|
pub assets: Vec<Attachment>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct CreateRelease {
|
||||||
|
pub body: String,
|
||||||
|
pub draft: bool,
|
||||||
|
pub name: String,
|
||||||
|
pub prerelease: bool,
|
||||||
|
pub tag_name: String,
|
||||||
|
pub target_commitish: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Attachment {
|
||||||
|
pub id: i64,
|
||||||
|
pub name: String,
|
||||||
|
pub size: i64,
|
||||||
|
pub download_count: i64,
|
||||||
|
pub created_at: String,
|
||||||
|
pub uuid: String,
|
||||||
|
pub browser_download_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Repo {
|
||||||
|
pub allow_merge_commits: bool,
|
||||||
|
pub allow_rebase: bool,
|
||||||
|
pub allow_rebase_explicit: bool,
|
||||||
|
pub allow_squash_merge: bool,
|
||||||
|
pub archived: bool,
|
||||||
|
pub avatar_url: String,
|
||||||
|
pub clone_url: String,
|
||||||
|
pub created_at: String,
|
||||||
|
pub default_branch: String,
|
||||||
|
pub description: String,
|
||||||
|
pub empty: bool,
|
||||||
|
pub fork: bool,
|
||||||
|
pub forks_count: i64,
|
||||||
|
pub full_name: String,
|
||||||
|
pub has_issues: bool,
|
||||||
|
pub has_pull_requests: bool,
|
||||||
|
pub has_wiki: bool,
|
||||||
|
pub html_url: String,
|
||||||
|
pub id: i64,
|
||||||
|
pub ignore_whitespace_conflicts: bool,
|
||||||
|
pub mirror: bool,
|
||||||
|
pub name: String,
|
||||||
|
pub open_issues_count: i64,
|
||||||
|
pub open_pr_counter: i64,
|
||||||
|
pub original_url: String,
|
||||||
|
pub owner: User,
|
||||||
|
pub permissions: Permissions,
|
||||||
|
pub private: bool,
|
||||||
|
pub release_counter: i64,
|
||||||
|
pub size: i64,
|
||||||
|
pub ssh_url: String,
|
||||||
|
pub stars_count: i64,
|
||||||
|
pub template: bool,
|
||||||
|
pub updated_at: String,
|
||||||
|
pub watchers_count: i64,
|
||||||
|
pub website: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct User {
|
||||||
|
pub avatar_url: String,
|
||||||
|
pub created: String,
|
||||||
|
pub email: String,
|
||||||
|
pub full_name: String,
|
||||||
|
pub id: i64,
|
||||||
|
pub is_admin: bool,
|
||||||
|
pub language: String,
|
||||||
|
pub last_login: String,
|
||||||
|
pub login: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Permissions {
|
||||||
|
pub admin: bool,
|
||||||
|
pub pull: bool,
|
||||||
|
pub push: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Version {
|
||||||
|
pub version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
cli: reqwest::Client,
|
||||||
|
base_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub fn new(base_url: String, token: String, user_agent: String) -> Result<Self> {
|
||||||
|
let mut headers = header::HeaderMap::new();
|
||||||
|
let auth = format!("token {}", token);
|
||||||
|
let auth = auth.as_str();
|
||||||
|
headers.insert(header::AUTHORIZATION, header::HeaderValue::from_str(auth)?);
|
||||||
|
let cli = reqwest::Client::builder()
|
||||||
|
.user_agent(user_agent)
|
||||||
|
.default_headers(headers)
|
||||||
|
.build()?;
|
||||||
|
Ok(Self {
|
||||||
|
cli: cli,
|
||||||
|
base_url: base_url,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn version(&self) -> Result<Version> {
|
||||||
|
Ok(self
|
||||||
|
.cli
|
||||||
|
.get(&format!("{}/api/v1/version", self.base_url))
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json()
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_release_by_tag(
|
||||||
|
&self,
|
||||||
|
owner: String,
|
||||||
|
repo: String,
|
||||||
|
tag: String,
|
||||||
|
) -> Result<Release> {
|
||||||
|
let releases: Vec<Release> = self.get_releases(owner, repo).await?;
|
||||||
|
let mut release: Option<Release> = None;
|
||||||
|
|
||||||
|
for rls in releases {
|
||||||
|
if *tag == rls.tag_name {
|
||||||
|
release = Some(rls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match release {
|
||||||
|
None => Err(Error::TagNotFound(tag)),
|
||||||
|
Some(release) => Ok(release),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_repo(&self, owner: String, repo: String) -> Result<Repo> {
|
||||||
|
Ok(self
|
||||||
|
.cli
|
||||||
|
.get(&format!(
|
||||||
|
"{}/api/v1/repos/{}/{}",
|
||||||
|
self.base_url, owner, repo
|
||||||
|
))
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json()
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_releases(&self, owner: String, repo: String) -> Result<Vec<Release>> {
|
||||||
|
Ok(self
|
||||||
|
.cli
|
||||||
|
.get(&format!(
|
||||||
|
"{}/api/v1/repos/{}/{}/releases",
|
||||||
|
self.base_url, owner, repo
|
||||||
|
))
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json()
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_release(
|
||||||
|
&self,
|
||||||
|
owner: String,
|
||||||
|
repo: String,
|
||||||
|
cr: CreateRelease,
|
||||||
|
) -> Result<Release> {
|
||||||
|
Ok(self
|
||||||
|
.cli
|
||||||
|
.post(&format!(
|
||||||
|
"{}/api/v1/repos/{}/{}/releases",
|
||||||
|
self.base_url, owner, repo
|
||||||
|
))
|
||||||
|
.json(&cr)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json()
|
||||||
|
.await?)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
use crate::{gitea::*, *};
|
|
||||||
use anyhow::{anyhow, Result};
|
|
||||||
|
|
||||||
pub(crate) async fn run(common: Common, tag: String) -> Result<()> {
|
|
||||||
let cli = client(&common)?;
|
|
||||||
let release =
|
|
||||||
get_release_by_tag(&cli, &common.server, &common.owner, &common.repo, &tag).await?;
|
|
||||||
|
|
||||||
let resp = cli
|
|
||||||
.delete(
|
|
||||||
format!(
|
|
||||||
"{}/api/v1/repos/{}/{}/releases/{}",
|
|
||||||
&common.server, &common.owner, &common.repo, release.id
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
)
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if resp.status() != http::StatusCode::from_u16(204)? {
|
|
||||||
Err(anyhow!("wanted 204, got {}", resp.status()))
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
use crate::{gitea::*, *};
|
|
||||||
use anyhow::{anyhow, Result};
|
|
||||||
use cli_table::{Cell, Row, Table};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
pub(crate) async fn run(common: Common, fname: Option<PathBuf>, tag: String) -> Result<()> {
|
|
||||||
let cli = client(&common)?;
|
|
||||||
let release =
|
|
||||||
get_release_by_tag(&cli, &common.server, &common.owner, &common.repo, &tag).await?;
|
|
||||||
let attachments = get_attachments_for_release(
|
|
||||||
&cli,
|
|
||||||
&common.server,
|
|
||||||
&common.owner,
|
|
||||||
&common.repo,
|
|
||||||
&release.id,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
match fname {
|
|
||||||
None => {
|
|
||||||
let mut rows: Vec<Row> = vec![Row::new(vec![
|
|
||||||
Cell::new(&"name", Default::default()),
|
|
||||||
Cell::new(&"size", Default::default()),
|
|
||||||
Cell::new(&"url", Default::default()),
|
|
||||||
])];
|
|
||||||
for attachment in attachments {
|
|
||||||
rows.push(attachment.row())
|
|
||||||
}
|
|
||||||
|
|
||||||
let table = Table::new(rows, Default::default())?;
|
|
||||||
table.print_stdout()?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(fname) => {
|
|
||||||
let mut url: Option<String> = None;
|
|
||||||
let fname = fname.into_os_string().into_string().unwrap();
|
|
||||||
|
|
||||||
for attachment in attachments {
|
|
||||||
if &fname == &attachment.name {
|
|
||||||
url = Some(attachment.browser_download_url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if url.is_none() {
|
|
||||||
return Err(anyhow!("no attachment named {}", fname));
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = &cli.get(url.unwrap().as_str()).send().await?.bytes().await?;
|
|
||||||
let mut fout = File::create(&fname)?;
|
|
||||||
|
|
||||||
fout.write(data)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
use crate::{gitea::*, *};
|
|
||||||
use anyhow::{anyhow, Result};
|
|
||||||
|
|
||||||
pub(crate) async fn run(
|
|
||||||
common: Common,
|
|
||||||
description: Option<String>,
|
|
||||||
rm: ReleaseMeta,
|
|
||||||
tag: String,
|
|
||||||
) -> Result<()> {
|
|
||||||
let cli = client(&common)?;
|
|
||||||
let release =
|
|
||||||
get_release_by_tag(&cli, &common.server, &common.owner, &common.repo, &tag).await?;
|
|
||||||
|
|
||||||
let mut cr = CreateRelease {
|
|
||||||
body: release.body,
|
|
||||||
draft: release.draft,
|
|
||||||
name: release.name,
|
|
||||||
prerelease: release.prerelease,
|
|
||||||
tag_name: release.tag_name,
|
|
||||||
target_commitish: release.target_commitish,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(description) = description {
|
|
||||||
cr.body = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(name) = rm.name {
|
|
||||||
cr.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
cr.draft = rm.draft;
|
|
||||||
cr.prerelease = rm.pre_release;
|
|
||||||
|
|
||||||
let resp = cli
|
|
||||||
.post(&format!(
|
|
||||||
"{}/api/v1/repos/{}/{}/releases/{}",
|
|
||||||
common.server, common.owner, common.repo, release.id
|
|
||||||
))
|
|
||||||
.json(&cr)
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !resp.status().is_success() {
|
|
||||||
return Err(anyhow!("{:?}", resp.status()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
use crate::{gitea::*, *};
|
|
||||||
use anyhow::{anyhow, Result};
|
|
||||||
use cli_table::{Cell, Row, Table};
|
|
||||||
|
|
||||||
pub(crate) async fn run(common: Common, json: bool, tag: Option<String>) -> Result<()> {
|
|
||||||
let cli = client(&common)?;
|
|
||||||
|
|
||||||
let releases: Vec<Release> = cli
|
|
||||||
.get(
|
|
||||||
format!(
|
|
||||||
"{}/api/v1/repos/{}/{}/releases",
|
|
||||||
&common.server, &common.owner, &common.repo
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
)
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.json()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
match tag {
|
|
||||||
Some(tag) => {
|
|
||||||
let mut release: Option<Release> = None;
|
|
||||||
|
|
||||||
for rls in releases {
|
|
||||||
if tag == rls.tag_name {
|
|
||||||
release = Some(rls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if release.is_none() {
|
|
||||||
return Err(anyhow!("tag {} not found", tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
if json {
|
|
||||||
println!("{}", serde_json::to_string_pretty(&release)?);
|
|
||||||
} else {
|
|
||||||
let rls = release.unwrap();
|
|
||||||
let table = Table::new(
|
|
||||||
vec![
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&"id", Default::default()),
|
|
||||||
Cell::new(&rls.id, Default::default()),
|
|
||||||
]),
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&"author", Default::default()),
|
|
||||||
Cell::new(
|
|
||||||
&format!("{} - {}", rls.author.full_name, rls.author.username),
|
|
||||||
Default::default(),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&"tag", Default::default()),
|
|
||||||
Cell::new(&rls.tag_name, Default::default()),
|
|
||||||
]),
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&"created at", Default::default()),
|
|
||||||
Cell::new(&rls.created_at, Default::default()),
|
|
||||||
]),
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&"name", Default::default()),
|
|
||||||
Cell::new(&rls.name, Default::default()),
|
|
||||||
]),
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&"body", Default::default()),
|
|
||||||
Cell::new(&rls.body, Default::default()),
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
Default::default(),
|
|
||||||
)?;
|
|
||||||
table.print_stdout()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
if json {
|
|
||||||
println!("{}", serde_json::to_string_pretty(&releases)?);
|
|
||||||
} else {
|
|
||||||
let mut rows: Vec<Row> = vec![Row::new(vec![
|
|
||||||
Cell::new(&"id", Default::default()),
|
|
||||||
Cell::new(&"tag", Default::default()),
|
|
||||||
Cell::new(&"created at", Default::default()),
|
|
||||||
Cell::new(&"commit", Default::default()),
|
|
||||||
Cell::new(&"author", Default::default()),
|
|
||||||
Cell::new(&"name", Default::default()),
|
|
||||||
])];
|
|
||||||
for release in releases {
|
|
||||||
rows.push(release.row())
|
|
||||||
}
|
|
||||||
|
|
||||||
let table = Table::new(rows, Default::default())?;
|
|
||||||
table.print_stdout()?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
use crate::{gitea::*, *};
|
|
||||||
use anyhow::Result;
|
|
||||||
use reqwest::multipart;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
pub(crate) async fn run(common: Common, fname: PathBuf, tag: String) -> Result<()> {
|
|
||||||
let cli = client(&common)?;
|
|
||||||
let bytes = {
|
|
||||||
let mut fin = File::open(&fname)?;
|
|
||||||
let mut buffer = Vec::new();
|
|
||||||
fin.read_to_end(&mut buffer)?;
|
|
||||||
buffer
|
|
||||||
};
|
|
||||||
let form = multipart::Form::new().part("attachment", multipart::Part::bytes(bytes));
|
|
||||||
let release =
|
|
||||||
get_release_by_tag(&cli, &common.server, &common.owner, &common.repo, &tag).await?;
|
|
||||||
|
|
||||||
cli.post(
|
|
||||||
format!(
|
|
||||||
"{}/api/v1/repos/{}/{}/releases/{}",
|
|
||||||
&common.server, &common.owner, &common.repo, release.id,
|
|
||||||
)
|
|
||||||
.as_str(),
|
|
||||||
)
|
|
||||||
.query(&[("name", fname)])
|
|
||||||
.multipart(form)
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
212
src/gitea.rs
212
src/gitea.rs
|
@ -1,212 +0,0 @@
|
||||||
use anyhow::{anyhow, Result};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Author {
|
|
||||||
pub id: i64,
|
|
||||||
pub login: String,
|
|
||||||
pub full_name: String,
|
|
||||||
pub email: String,
|
|
||||||
pub avatar_url: String,
|
|
||||||
pub language: String,
|
|
||||||
pub is_admin: bool,
|
|
||||||
pub last_login: String,
|
|
||||||
pub created: String,
|
|
||||||
pub username: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Release {
|
|
||||||
pub id: i64,
|
|
||||||
pub tag_name: String,
|
|
||||||
pub target_commitish: String,
|
|
||||||
pub name: String,
|
|
||||||
pub body: String,
|
|
||||||
pub url: String,
|
|
||||||
pub tarball_url: String,
|
|
||||||
pub zipball_url: String,
|
|
||||||
pub draft: bool,
|
|
||||||
pub prerelease: bool,
|
|
||||||
pub created_at: String,
|
|
||||||
pub published_at: String,
|
|
||||||
pub author: Author,
|
|
||||||
pub assets: Vec<Attachment>,
|
|
||||||
}
|
|
||||||
|
|
||||||
use cli_table::{Cell, Row};
|
|
||||||
impl Release {
|
|
||||||
pub fn row(&self) -> Row {
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&format!("{}", self.id), Default::default()),
|
|
||||||
Cell::new(&self.tag_name, Default::default()),
|
|
||||||
Cell::new(&self.created_at, Default::default()),
|
|
||||||
Cell::new(&self.target_commitish, Default::default()),
|
|
||||||
Cell::new(&self.author.username, Default::default()),
|
|
||||||
Cell::new(&self.name, Default::default()),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct CreateRelease {
|
|
||||||
pub body: String,
|
|
||||||
pub draft: bool,
|
|
||||||
pub name: String,
|
|
||||||
pub prerelease: bool,
|
|
||||||
pub tag_name: String,
|
|
||||||
pub target_commitish: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn get_release_by_tag(
|
|
||||||
cli: &reqwest::Client,
|
|
||||||
server: &String,
|
|
||||||
owner: &String,
|
|
||||||
repo: &String,
|
|
||||||
tag: &String,
|
|
||||||
) -> Result<Release> {
|
|
||||||
let releases: Vec<Release> = cli
|
|
||||||
.get(&format!(
|
|
||||||
"{}/api/v1/repos/{}/{}/releases",
|
|
||||||
server, owner, repo
|
|
||||||
))
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.json()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let mut release: Option<Release> = None;
|
|
||||||
|
|
||||||
for rls in releases {
|
|
||||||
if *tag == rls.tag_name {
|
|
||||||
release = Some(rls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if release.is_none() {
|
|
||||||
return Err(anyhow!("tag {} not found", tag));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(release.unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Attachment {
|
|
||||||
pub id: i64,
|
|
||||||
pub name: String,
|
|
||||||
pub size: i64,
|
|
||||||
pub download_count: i64,
|
|
||||||
pub created_at: String,
|
|
||||||
pub uuid: String,
|
|
||||||
pub browser_download_url: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Attachment {
|
|
||||||
pub fn row(&self) -> Row {
|
|
||||||
let size = {
|
|
||||||
let bytes = byte_unit::Byte::from_bytes(self.size as u128);
|
|
||||||
let unit = bytes.get_appropriate_unit(false);
|
|
||||||
unit.to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
Row::new(vec![
|
|
||||||
Cell::new(&self.name, Default::default()),
|
|
||||||
Cell::new(&size, Default::default()),
|
|
||||||
Cell::new(&self.browser_download_url, Default::default()),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Repo {
|
|
||||||
pub allow_merge_commits: bool,
|
|
||||||
pub allow_rebase: bool,
|
|
||||||
pub allow_rebase_explicit: bool,
|
|
||||||
pub allow_squash_merge: bool,
|
|
||||||
pub archived: bool,
|
|
||||||
pub avatar_url: String,
|
|
||||||
pub clone_url: String,
|
|
||||||
pub created_at: String,
|
|
||||||
pub default_branch: String,
|
|
||||||
pub description: String,
|
|
||||||
pub empty: bool,
|
|
||||||
pub fork: bool,
|
|
||||||
pub forks_count: i64,
|
|
||||||
pub full_name: String,
|
|
||||||
pub has_issues: bool,
|
|
||||||
pub has_pull_requests: bool,
|
|
||||||
pub has_wiki: bool,
|
|
||||||
pub html_url: String,
|
|
||||||
pub id: i64,
|
|
||||||
pub ignore_whitespace_conflicts: bool,
|
|
||||||
pub mirror: bool,
|
|
||||||
pub name: String,
|
|
||||||
pub open_issues_count: i64,
|
|
||||||
pub open_pr_counter: i64,
|
|
||||||
pub original_url: String,
|
|
||||||
pub owner: Owner,
|
|
||||||
pub permissions: Permissions,
|
|
||||||
pub private: bool,
|
|
||||||
pub release_counter: i64,
|
|
||||||
pub size: i64,
|
|
||||||
pub ssh_url: String,
|
|
||||||
pub stars_count: i64,
|
|
||||||
pub template: bool,
|
|
||||||
pub updated_at: String,
|
|
||||||
pub watchers_count: i64,
|
|
||||||
pub website: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn get_repo(
|
|
||||||
cli: &reqwest::Client,
|
|
||||||
server: &String,
|
|
||||||
owner: &String,
|
|
||||||
repo: &String,
|
|
||||||
) -> Result<Repo> {
|
|
||||||
Ok(cli
|
|
||||||
.get(&format!("{}/api/v1/repos/{}/{}", server, owner, repo))
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.error_for_status()?
|
|
||||||
.json()
|
|
||||||
.await?)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Owner {
|
|
||||||
pub avatar_url: String,
|
|
||||||
pub created: String,
|
|
||||||
pub email: String,
|
|
||||||
pub full_name: String,
|
|
||||||
pub id: i64,
|
|
||||||
pub is_admin: bool,
|
|
||||||
pub language: String,
|
|
||||||
pub last_login: String,
|
|
||||||
pub login: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct Permissions {
|
|
||||||
pub admin: bool,
|
|
||||||
pub pull: bool,
|
|
||||||
pub push: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn get_attachments_for_release(
|
|
||||||
cli: &reqwest::Client,
|
|
||||||
server: &String,
|
|
||||||
owner: &String,
|
|
||||||
repo: &String,
|
|
||||||
id: &i64,
|
|
||||||
) -> Result<Vec<Attachment>> {
|
|
||||||
let attachments: Vec<Attachment> = cli
|
|
||||||
.get(&format!(
|
|
||||||
"{}/api/v1/repos/{}/{}/releases/{}/assets",
|
|
||||||
server, owner, repo, id
|
|
||||||
))
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.json()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(attachments)
|
|
||||||
}
|
|
Loading…
Reference in New Issue