codeberg-cli 0.5.5

CLI Tool for codeberg similar to gh and glab
Documentation
use crate::actions::GlobalArgs;
use crate::types::context::BergContext;

use clap::Parser;
use forgejo_api::structs::CreateGPGKeyOption;
use miette::{Context, IntoDiagnostic};

/// Upload a new gpg public key, attaching it to your profile
#[derive(Parser, Debug)]
pub struct AddGpgArgs {
    /// The path to an ascii armored gpg key
    gpg_key_path: std::path::PathBuf,
}

impl AddGpgArgs {
    pub async fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
        let _ = global_args;
        let ctx = BergContext::new(self, global_args).await?;

        let armored_public_key =
            std::fs::read_to_string(ctx.args.gpg_key_path.as_path()).map_err(|e| {
                miette::miette!(
                    help = format!(
                        "Check access permissions for the file '{path}'",
                        path = ctx.args.gpg_key_path.display()
                    ),
                    "{e}"
                )
                .context("Reading the GPG public key from file failed!")
            })?;

        if !armored_public_key.contains("PUBLIC KEY") {
            miette::bail!(
                help = "Did you pass the private key on accident? If you think this is `berg`s fault, please open an issue!",
                "It seems that the file you specified didn't contain a public key!"
            );
        }

        let form = CreateGPGKeyOption {
            armored_public_key,
            armored_signature: None,
        };

        ctx.client
            .user_current_post_gpg_key(form)
            .await
            .into_diagnostic()
            .context("Uploading GPG public key failed!")?;

        println!("Successfully added GPG key to your user profile!");

        Ok(())
    }
}