genpac 0.1.0

Sandbox for Gentoo ebuild development using bubblewrap
// Copyright (C) 2023 Gokul Das B
// SPDX-License-Identifier: GPL-3.0-or-later
//! CLIf module for snapshot command

use super::ModConfig;
use crate::GlobalsFinal;
use anyhow::Result as AResult;
use clap::{Args, Subcommand};
use std::path::PathBuf;

/// Manage snapshots/chroots
#[derive(Subcommand)]
pub enum SubCmdArgs {
    /// List availabe chroots
    #[command(alias = "ls")]
    List,

    /// Make a new snapshot chroot
    #[command(aliases = ["new", "make", "mk", "create"])]
    Add {
        #[command(flatten)]
        source: Source,
        /// Chroot/snapshot to create
        target: PathBuf,
    },

    /// Delete a snapshot
    #[command(aliases = ["rm", "delete"])]
    Del { target: PathBuf },
}

#[derive(Args)]
#[group(required = true, multiple = false)]
pub struct Source {
    /// Create snapshot chroot from designated template
    #[arg(short, long)]
    template: bool,

    /// Create a blank chroot
    #[arg(short, long)]
    blank: bool,

    /// Create snapshot of specified chroot
    #[arg(short, long)]
    source: Option<PathBuf>,
}

impl SubCmdArgs {
    pub fn handle(&self, globals: GlobalsFinal) -> AResult<()> {
        let snapcfg = ModConfig::new(&globals)?;
        let backend = globals.backend();
        match self {
            Self::List => {
                let chroots = globals.list_chroots()?.join(" ");
                println!("Available chroots: {chroots}");
            }
            Self::Add { source, target } => {
                let mut target = backend.target(target, &globals);

                let source = if source.source.is_some() {
                    Some(source.source.as_ref().unwrap().as_path())
                } else if source.template {
                    Some(snapcfg.template().unwrap())
                } else {
                    None
                };

                if let Some(path) = source {
                    let source = globals.chroot(path).verify(true)?;
                    target.duplicate(source)?;
                } else {
                    target.make_blank()?;
                }
            }
            Self::Del { target } => {
                let mut target = backend.target(target, &globals);
                target.delete()?;
            }
        }
        Ok(())
    }
}