codeberg-cli 0.5.5

CLI Tool for codeberg similar to gh and glab
Documentation
pub mod api;
pub mod auth;
pub mod config;
pub mod issue;
pub mod keys;
pub mod label;
pub mod milestone;
pub mod notification;
pub mod pull_request;
pub mod release;
pub mod repo;
pub mod user;

// utils for DRYing text functionalities
mod text_manipulation;

use clap::builder::Styles;
use clap::builder::styling::{AnsiColor, Effects};
use clap::{CommandFactory, Parser};
use clap_complete::Shell;

use crate::types::{git::OwnerRepo, output::OutputMode};

const STYLES: Styles = Styles::styled()
    .header(AnsiColor::Yellow.on_default().effects(Effects::BOLD))
    .usage(AnsiColor::Green.on_default().effects(Effects::BOLD))
    .literal(AnsiColor::Green.on_default().effects(Effects::BOLD))
    .placeholder(AnsiColor::Green.on_default());

#[derive(Debug, clap::Parser)]
#[command(version, styles = STYLES)]
pub struct BergCommand {
    #[command(subcommand)]
    pub sub: BergActions,

    /// How to display the responses of the forgejo instance if there are any
    #[arg(value_enum, long, default_value_t = OutputMode::Pretty, global = true,)]
    pub output_mode: OutputMode,

    /// Whether or not to disable all interactive features.
    /// In this case arguments have to be provided in the console!
    ///
    /// Still WIP
    #[arg(long, global = true)]
    pub non_interactive: bool,

    /// Maximum with of the stdout output,
    ///
    /// - negative numbers indicate using 'infinite' width per line
    ///
    /// - zero indicates using the terminals width
    ///
    /// - positive numbers are interpreted as max width. You may specify
    ///   widths that can lead to weird linebreaks. This is a feature for tools
    ///   which process stdout output line by line. You may also just negative
    ///   widths in this case. We discourage use of widths <= 25
    ///
    /// Falls back to `max_width` value in config or defaults to 80 otherwise.
    #[arg(long, short = 'w', global = true)]
    pub max_width: Option<i32>,

    /// The OWNER/REPO tuple if you want to target a repository other than the one in $PWD
    #[arg(long, global = true, value_name = "OWNER/REPO")]
    pub owner_repo: Option<OwnerRepo>,
}

#[derive(Debug, Clone)]
pub struct GlobalArgs {
    pub non_interactive: bool,
    pub max_width: Option<i32>,
    pub output_mode: OutputMode,
    pub owner_repo: Option<OwnerRepo>,
}

impl BergCommand {
    pub fn generate_completion(shell: Shell) -> miette::Result<()> {
        clap_complete::generate(
            shell,
            &mut BergCommand::command(),
            "berg",
            &mut std::io::stdout(),
        );
        Ok(())
    }

    pub async fn run(self) -> miette::Result<()> {
        let global_args = GlobalArgs {
            non_interactive: self.non_interactive,
            max_width: self.max_width,
            output_mode: self.output_mode,
            owner_repo: self.owner_repo,
        };
        match self.sub {
            BergActions::API(args) => args.run(global_args).await,
            BergActions::Auth(args) => args.run(global_args).await,
            BergActions::Config(args) => args.run(global_args).await,
            BergActions::User(args) => args.run(global_args).await,
            BergActions::Issue(args) => args.run(global_args).await,
            BergActions::Pull(args) => args.run(global_args).await,
            BergActions::Label(args) => args.run(global_args).await,
            BergActions::Release(args) => args.run(global_args).await,
            BergActions::Repo(args) => args.run(global_args).await,
            BergActions::Milestone(args) => args.run(global_args).await,
            BergActions::Notification(args) => args.run(global_args).await,
            BergActions::Keys(args) => args.run(global_args).await,
            BergActions::Completion { shell } => Self::generate_completion(shell),
        }
    }
}

/// Codeberg/Forgejo CLI app
#[derive(Parser, Debug)]
pub enum BergActions {
    #[command(subcommand)]
    API(api::ApiArgs),

    #[command(subcommand)]
    Auth(auth::AuthArgs),

    #[command(subcommand)]
    Config(config::ConfigArgs),

    #[command(subcommand)]
    User(user::UserArgs),

    #[command(subcommand)]
    Issue(issue::IssueArgs),

    #[command(subcommand)]
    Pull(pull_request::PullRequestArgs),

    #[command(subcommand)]
    Label(label::LabelArgs),

    #[command(subcommand)]
    Release(release::ReleaseArgs),

    #[command(subcommand)]
    Repo(repo::RepoArgs),

    #[command(subcommand)]
    Milestone(milestone::MilestoneArgs),

    #[command(subcommand)]
    Notification(notification::NotificationArgs),

    #[command(subcommand)]
    Keys(keys::KeysArgs),

    /// Print completion script
    Completion {
        /// Shell to generate completion for
        shell: Shell,
    },
}