use std::{
ffi::OsString,
fs::{self, File},
path::PathBuf,
};
use anyhow::{Context as _, Result};
use clap::Parser as ClapParser;
use patsh::{patch, Context};
use tree_sitter::Parser;
#[derive(ClapParser)]
#[command(version, verbatim_doc_comment)]
struct Opts {
input: PathBuf,
output: Option<PathBuf>,
#[arg(short, long, default_value = "bash", value_name = "COMMAND")]
bash: OsString,
#[arg(short, long)]
force: bool,
#[arg(short, long)]
path: Option<OsString>,
#[arg(short, long, default_value = "/nix/store", value_name = "PATH")]
store_dir: PathBuf,
}
fn main() -> Result<()> {
let opts = Opts::parse();
let mut parser = Parser::new();
parser.set_language(tree_sitter_bash::language())?;
let src = fs::read(&opts.input)?;
let tree = parser
.parse(&src, None)
.with_context(|| format!("failed to parse {}", opts.input.display()))?;
let mut ctx = Context::load(opts.bash, opts.path, src, opts.store_dir)?;
patch(
&mut ctx,
tree,
&mut File::options()
.write(true)
.create(true)
.create_new(!opts.force)
.open(opts.output.unwrap_or(opts.input))?,
)?;
Ok(())
}