use anyhow::{anyhow, Result}; use reqwest::{header, Client}; use std::path::PathBuf; use structopt::StructOpt; mod changelog; mod cmd; mod gitea; #[derive(StructOpt, Debug)] pub(crate) struct Common { /// The gitea server to connect to #[structopt(short, long, env = "GITEA_SERVER")] server: String, /// The gitea token to authenticate with #[structopt(long, env = "GITEA_TOKEN")] token: String, /// The gitea user to authenticate as #[structopt(short, long, env = "GITEA_AUTH_USER")] auth_user: String, /// The owner of the gitea repo #[structopt(short, long, env = "GITEA_OWNER")] owner: String, /// The gitea repo to operate on #[structopt(short, long, env = "GITEA_REPO")] repo: String, } // Name your user agent after your app? static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); pub(crate) fn client(c: &Common) -> Result { let mut headers = header::HeaderMap::new(); let auth = format!("token {}", &c.token); let auth = auth.as_str(); headers.insert(header::AUTHORIZATION, header::HeaderValue::from_str(auth)?); Ok(Client::builder() .user_agent(APP_USER_AGENT) .default_headers(headers) .build()?) } #[derive(StructOpt, Debug)] pub(crate) struct ReleaseMeta { /// Release name #[structopt(short, long)] name: Option, /// Draft release #[structopt(long)] draft: bool, /// Pre-release (not suitable for production) #[structopt(short, long)] pre_release: bool, } #[derive(StructOpt, Debug)] #[structopt(about = "Gitea release assistant")] pub(crate) enum Cmd { /// Delete a given release from Gitea Delete { #[structopt(flatten)] common: Common, /// The version tag to operate on #[structopt(short, long)] tag: String, }, /// Downloads release artifacts Download { #[structopt(flatten)] common: Common, /// Folder to download release artifacts to #[structopt(short, long)] fname: Option, /// The version tag to operate on #[structopt(short, long)] tag: String, }, /// Edits a release's description, name and other flags Edit { #[structopt(flatten)] common: Common, /// Release description #[structopt(short, long)] description: Option, #[structopt(flatten)] release_meta: ReleaseMeta, /// The version tag to operate on #[structopt(short, long)] tag: String, }, /// Gets release info Info { #[structopt(flatten)] common: Common, #[structopt(long, short)] json: bool, /// The version tag to operate on #[structopt(short, long)] tag: Option, }, /// Create a new tag and release on Gitea Release { #[structopt(flatten)] common: Common, /// Changelog file to read from to create the release description #[structopt(short, long, default_value = "./CHANGELOG.md")] changelog: PathBuf, #[structopt(flatten)] release_meta: ReleaseMeta, }, /// Uploads release artifacts to Gitea Upload { #[structopt(flatten)] common: Common, /// The location of the file on the disk #[structopt(short, long)] fname: PathBuf, /// The version tag to operate on #[structopt(short, long)] tag: String, }, } #[tokio::main] async fn main() -> Result<()> { let _ = kankyo::init(); let cmd = Cmd::from_args(); match cmd { Cmd::Delete { common, tag } => cmd::delete::run(common, tag).await, Cmd::Download { common, fname, tag } => cmd::download::run(common, fname, tag).await, Cmd::Edit { common, description, release_meta, tag, } => cmd::edit::run(common, description, release_meta, tag).await, Cmd::Info { common, json, tag } => cmd::info::run(common, json, tag).await, Cmd::Upload { common, fname, tag } => cmd::upload::run(common, fname, tag).await, _ => Err(anyhow!("not implemented yet")), } }