Files
gt-tool/src/main.rs

177 lines
5.3 KiB
Rust

use gt_tools::structs::release::CreateReleaseOption;
use gt_tools::{structs::release::Release, cli::Args};
use reqwest::multipart::Part;
use std::collections::HashMap;
use std::{
env,
fs
};
use clap::Parser;
use reqwest::{header, Error};
use reqwest::header::{ACCEPT, USER_AGENT};
const API_RELEASE_FRONT: &'static str = "/api/v1/repos/";
const API_RELEASE_BACK: &'static str = "/releases";
#[tokio::main]
async fn main() -> Result<(), gt_tools::Error> {
let args = Args::parse();
let token = std::env::var("RELEASE_KEY_GITEA")
.map_err(|_| gt_tools::Error::MissingAuthToken )?;
let mut headers = reqwest::header::HeaderMap::new();
headers.append(ACCEPT, header::HeaderValue::from_static("application/json"));
headers.append("Authorization", token.parse().unwrap());
let client = reqwest::Client::builder()
.user_agent("gt-tools-test-agent")
.default_headers(headers)
.build()?;
match args.command {
gt_tools::cli::Commands::ListReleases => {
let releases = gt_tools::api::release::list_releases(
&client,
&args.gitea_url,
&args.repo
).await?;
for release in releases {
println!("{:?}", release);
}
}
gt_tools::cli::Commands::CreateRelease {
name,
body,
draft,
prerelease,
tag_name,
target_commitish,
} => {
let submission = CreateReleaseOption {
body,
draft,
name,
prerelease,
tag_name,
target_commitish,
};
do_create_release(&client, &args.gitea_url, &args.repo, submission)
.await
.map_err(reqwest_to_gttool)?;
}
gt_tools::cli::Commands::UploadRelease {
tag_name,
create,
files
} => {
println!("Uploading files to a release!");
println!("Release Tag: {tag_name}");
println!("Creating?: {create}");
println!("Files...");
for file in &files {
println!("--- {file}");
}
// TODO: Pre-create the release, if it doesn't exist.
// TODO: Find an existing release and use it's ID, if it does
do_upload_release(
&client,
&args.gitea_url,
&args.repo,
52usize,
files
).await.map_err(reqwest_to_gttool)?;
}
}
Ok(())
}
fn reqwest_to_gttool(err: reqwest::Error) -> gt_tools::Error {
gt_tools::Error::WrappedReqwestErr(err)
}
#[must_use]
async fn do_create_release(
client: &reqwest::Client,
gitea_url: &str,
repo: &str,
submission: CreateReleaseOption,
) -> Result<(), Error> {
let token = env::var("RELEASE_KEY_GITEA").expect(
"You must set the RELEASE_KEY_GITEA environment variable so the Gitea API can be used.",
);
let request_url = format!(
"{gitea_url}{front}{repo}{back}",
front = API_RELEASE_FRONT,
back = API_RELEASE_BACK
);
let response = client
.post(request_url)
.header(USER_AGENT, "gt-tools-test-agent")
.header(ACCEPT, "application/json")
.header("Authorization", format!("token {}", token))
.json(&submission)
.send()
.await?;
println!("HTTP Response: {}", response.status());
let result: gt_tools::CreateResult = response.json().await?;
println!("{:?}", result);
Ok(())
}
async fn do_upload_release(
client: &reqwest::Client,
gitea_url: &str,
repo: &str,
release_id: usize,
files: Vec<String>,
) -> Result<(), Error> {
let token = env::var("RELEASE_KEY_GITEA").expect(
"You must set the RELEASE_KEY_GITEA environment variable so the Gitea API can be used.",
);
let request_url = format!(
"{gitea_url}{front}{repo}{back}/{id}/assets",
front = API_RELEASE_FRONT,
back = API_RELEASE_BACK,
id = release_id
);
// Setup a "partial request". I'll need to loop over the files, so I'll
// clone this a bunch of times for each one
let partial_request = client
.post(request_url)
.header(USER_AGENT, "gt-tools-test-agent")
.header(ACCEPT, "application/json")
.header("Authorization", format!("token {}", token));
// Ensure all files exists before starting the uploads
for file in &files {
assert!(fs::exists(file)
.expect(&format!("Can't check existence of {file}"))
);
}
for file in files {
if let Some(request) = partial_request.try_clone() {
println!("Uploading file {}", &file);
let data = reqwest::multipart::Part::stream(fs::read(&file).unwrap())
.file_name("attachment")
.mime_str("text/plain")?;
let form= reqwest::multipart::Form::new()
.part("attachment", data);
let request = request
.multipart(form)
.query(&[("name", file.split("/").last())])
.send()
.await?;
} else {
panic!("Failed to clone the RequestBuilder during file upload loop.");
}
}
Ok(())
}