guartcl 0.6.0-alpha1

Enhanced Jim Tcl.
Documentation
use std::path::PathBuf;

use clap::{ArgAction::Count, Parser};
use guartcl::{compile::ScriptCompiler, guardian_interp};
use jimtcl::{JimError, JimResult, tcl_error};
use log::*;

/// Compile a Tcl script into a self-contained executable.
#[derive(Parser)]
#[command(version, name = "guarsh")]
struct GuardianShell {
    /// Enable verbose logging.
    #[arg(short = 'v', long = "verbose", action=Count)]
    verbose: u8,
    /// Parse command-line arguments with Usage.
    // #[arg(short = 'U', long = "usage")]
    // usage: bool,

    /// Specify a working directory instead of the default temp dir.
    #[arg(short = 'W', long = "work-dir")]
    work_dir: Option<PathBuf>,

    /// Specify alternate path to the Guardian Tcl source.
    #[arg(long = "guardian-src")]
    source_dir: Option<PathBuf>,

    /// Specify output file.
    #[arg(short = 'o', long = "output")]
    output: Option<PathBuf>,

    /// Script to compile.
    #[arg()]
    script: PathBuf,
}

fn main() -> JimResult<()> {
    let args = GuardianShell::parse();
    let dft = if args.verbose >= 2 {
        LevelFilter::Trace
    } else if args.verbose == 1 {
        LevelFilter::Debug
    } else {
        LevelFilter::Info
    };
    env_logger::builder()
        .filter_level(dft)
        .parse_default_env()
        .try_init()
        .map_err(|_| tcl_error!("cannot initialize logging"))?;

    info!("compiling {}", args.script.display());
    let out = if let Some(path) = args.output {
        path
    } else {
        args.script.with_extension("")
    };
    let interp = guardian_interp()?;
    let mut comp = ScriptCompiler::new(&interp);
    if let Some(dir) = &args.work_dir {
        comp.working_dir(dir);
    };
    if let Some(dir) = &args.source_dir {
        comp.guardian_source_dir(dir);
    }
    comp.compile(&args.script, &out).map_err(JimError::wrap)?;
    info!("compiled to {}", out.display());

    Ok(())
}