178 lines
5.1 KiB
Rust
178 lines
5.1 KiB
Rust
use clap::{Parser, Subcommand};
|
|
// use time::OffsetDateTime;
|
|
use forgejo_api::Auth::Token;
|
|
use forgejo_api::Forgejo;
|
|
use forgejo_api::structs::CreateReleaseOption;
|
|
use url::Url;
|
|
use std::io;
|
|
|
|
pub mod config;
|
|
|
|
#[derive(Debug, Parser)]
|
|
#[clap(
|
|
name = "forge-auto",
|
|
version = "1.0",
|
|
about = "Automate routine tasks in Forgejo"
|
|
)]
|
|
struct Cli {
|
|
#[clap(subcommand)]
|
|
command: Commands,
|
|
}
|
|
|
|
#[derive(Debug, Subcommand)]
|
|
enum Commands {
|
|
/// A subcommand with its own subcommands
|
|
#[clap(subcommand)]
|
|
Release(ReleaseSubCommands),
|
|
}
|
|
|
|
#[derive(Debug, Subcommand)]
|
|
enum ReleaseSubCommands {
|
|
/// A sub-subcommand
|
|
New {
|
|
alias: String,
|
|
tag: String,
|
|
#[clap(long, short)]
|
|
target: Option<String>,
|
|
},
|
|
|
|
/// Another sub-subcommand
|
|
List { alias: String },
|
|
}
|
|
|
|
async fn handle_new_release(
|
|
config: &config::Config,
|
|
alias: &str,
|
|
tag: &str,
|
|
target: &Option<String>,
|
|
) -> Result<(), String> {
|
|
println!("Creating new release with alias: {}, tag: {}", alias, tag);
|
|
|
|
let repo = config.repos.get(alias).map_or_else(
|
|
|| Err(format!("No repository found with alias: {}", alias)),
|
|
|repo| {
|
|
println!("Using repository: {} owned by {}", repo.repo, repo.owner);
|
|
// Here you would typically call the Forgejo API to create a new release
|
|
// For example:
|
|
Ok(repo)
|
|
},
|
|
)?;
|
|
|
|
let token = Token(&repo.token);
|
|
let url = Url::parse(&repo.hostname).map_err(|e| {
|
|
eprintln!("Failed to parse URL: {}", e);
|
|
e.to_string()
|
|
})?;
|
|
let forgejo = Forgejo::new(token, url).map_err(|e| {
|
|
eprintln!("Failed to create Forgejo client: {}", e);
|
|
e.to_string()
|
|
})?;
|
|
|
|
if target.is_none() {
|
|
println!("Target not provided for creating a release.");
|
|
println!("Please confirm by typing 'yes' that you want to create automatically with the latest commit.");
|
|
|
|
let mut input = String::new();
|
|
io::stdin()
|
|
.read_line(&mut input)
|
|
.expect("Failed to read line");
|
|
if input.trim().to_lowercase() != "yes" {
|
|
return Err("Release creation cancelled by user.".to_string());
|
|
}
|
|
}
|
|
|
|
let option = CreateReleaseOption {
|
|
tag_name: tag.to_string(),
|
|
name: Some(format!("{}", tag)),
|
|
body: Some(format!("Release {}", tag)),
|
|
hide_archive_links: Some(false),
|
|
target_commitish: target.clone(),
|
|
draft: None,
|
|
prerelease: None,
|
|
};
|
|
|
|
forgejo
|
|
.repo_create_release(&repo.owner, &repo.repo, option)
|
|
.await
|
|
.map_err(|e| {
|
|
eprintln!("Failed to create release: {}", e);
|
|
e.to_string()
|
|
})?;
|
|
Ok(())
|
|
}
|
|
|
|
async fn handle_list_releases(config: &config::Config, alias: &str) -> Result<(), String> {
|
|
println!("Listing releases for all repositories");
|
|
|
|
let repo = config.repos.get(alias).map_or_else(
|
|
|| Err(format!("No repository found with alias: {}", alias)),
|
|
|repo| {
|
|
println!("Using repository: {} owned by {}", repo.repo, repo.owner);
|
|
// Here you would typically call the Forgejo API to create a new release
|
|
// For example:
|
|
Ok(repo)
|
|
},
|
|
)?;
|
|
|
|
let token = Token(&repo.token);
|
|
let url = Url::parse(&repo.hostname).map_err(|e| {
|
|
eprintln!("Failed to parse URL: {}", e);
|
|
e.to_string()
|
|
})?;
|
|
let forgejo = Forgejo::new(token, url).map_err(|e| {
|
|
eprintln!("Failed to create Forgejo client: {}", e);
|
|
e.to_string()
|
|
})?;
|
|
|
|
let query = forgejo_api::structs::RepoListReleasesQuery {
|
|
draft: None,
|
|
page: None,
|
|
q: None,
|
|
pre_release: None,
|
|
limit: Some(100),
|
|
};
|
|
let result_query = forgejo
|
|
.repo_list_releases(&repo.owner, &repo.repo, query)
|
|
.await
|
|
.map_err(|e| {
|
|
eprintln!("Failed to list releases: {}", e);
|
|
e.to_string()
|
|
})?;
|
|
|
|
for release in result_query.1 {
|
|
println!(
|
|
"Release: {}, Tag: {}, Created at: {}",
|
|
release.name.unwrap_or_default(),
|
|
release.tag_name.unwrap_or("N/A".to_string()),
|
|
release.created_at.unwrap()
|
|
);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
let args = Cli::parse();
|
|
|
|
let config = config::load_config("config.ini").expect("Failed to load config");
|
|
|
|
match args.command {
|
|
Commands::Release(subcommand) => {
|
|
match subcommand {
|
|
ReleaseSubCommands::New { alias, tag, target } => {
|
|
handle_new_release(&config, &alias, &tag, &target).await?
|
|
}
|
|
ReleaseSubCommands::List { alias } => {
|
|
handle_list_releases(&config, &alias).await?;
|
|
}
|
|
}
|
|
// Uncomment the following lines if you want to use the dispatch macro
|
|
// dispatch!(subcommand,
|
|
// SubCommands::SubSubCommand { input } => handle_sub_sub_command(&input),
|
|
// SubCommands::AnotherSubSubCommand { output } => handle_another_sub_sub_command(&output),
|
|
// );
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|