git-cloak 0.0.1

The Invisible Layer for Your Repositories - Manage private, untracked files across Git clones.
mod git_utils;
mod ops;
mod pid;
mod store;

use clap::{Parser, Subcommand};
use std::path::PathBuf;
use std::process;

#[derive(Parser)]
#[command(name = "git-cloak")]
#[command(bin_name = "git-cloak")]
#[command(about = "The Invisible Layer for Your Repositories", long_about = None)]
#[command(version)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Track a file for management
    Track {
        /// The file to track
        file: PathBuf,

        /// Optional target path relative to project root
        target_path: Option<PathBuf>,
    },
    /// Untrack a file from the project
    Untrack {
        /// The file in the project to untrack
        file_in_project: PathBuf,
    },
    /// Move a tracked file to a new location
    Move {
        /// Old target path
        old_target: PathBuf,
        /// New target path
        new_target: PathBuf,
    },
    /// Inject context into the current workspace
    Inject,
    /// Eject context from the current workspace
    Eject,
    /// Show status of tracked files in the current project
    Status,
    /// List all managed projects
    Projects,
    /// Relink misplaced projects (Interactive)
    Relink,
    /// Clean up stale project records
    Clean,
    /// Run a command with context injected, then eject
    Run {
        /// The command to run
        #[arg(last = true)]
        command: Vec<String>,
    },
    /// Install Git hooks for automatic injection
    InstallHooks,
}

fn run(cmd: &Commands) -> Result<(), ops::CloakError> {
    match cmd {
        Commands::Track { file, target_path } => {
            ops::track(file, target_path.as_deref())
        }
        Commands::Untrack { file_in_project } => ops::untrack(file_in_project),
        Commands::Inject => ops::inject(),
        Commands::Eject => ops::eject(),
        Commands::Status => ops::status(),
        Commands::Projects => ops::projects(),
        _ => {
            todo!("Command not yet implemented.");
        }
    }
}

fn main() {
    let cli = Cli::parse();

    if let Err(e) = run(&cli.command) {
        eprintln!("error: {e}");
        process::exit(1);
    }
}