use crate::header::{CommandDataV1, CommandTypeV1, FSMetaV1, ENV_PREFIX};
use crate::jobfile;
use crate::seqfile;
use anyhow;
use clap::Args;
use std::ffi::OsString;
use std::os::unix::ffi::OsStrExt;
#[derive(Debug, Args)]
pub struct SFOpts {
#[arg(short, long, value_name = "FILE")]
pub seqfile: OsString,
}
#[derive(Debug, Args)]
pub struct SFSetOpts {
#[clap(flatten)]
sfopts: SFOpts,
#[arg(value_name = "ID")]
pub nextid: u64,
}
#[derive(Debug, Args)]
pub struct PrepareOpts {
#[clap(flatten)]
pub sfopts: SFOpts,
#[arg(short, long, value_name = "INPUT")]
pub input: Option<OsString>,
#[arg(last = true)]
pub params: Vec<OsString>,
}
pub fn cmd_preparegetnext(opts: &SFOpts) -> Result<(), anyhow::Error> {
let mut lock = seqfile::prepare_seqfile_lock(&opts.seqfile, true)?;
let seqf = seqfile::SeqFile::open(&opts.seqfile, &mut lock)?;
println!("{}", seqf.get_next());
Ok(())
}
pub fn cmd_preparesetnext(opts: &SFSetOpts) -> Result<(), anyhow::Error> {
let mut lock = seqfile::prepare_seqfile_lock(&opts.sfopts.seqfile, true)?;
let mut seqf = seqfile::SeqFile::open(&opts.sfopts.seqfile, &mut lock)?;
seqf.set(opts.nextid)?;
Ok(())
}
pub fn cmd_preparenop(opts: &SFOpts) -> Result<(), anyhow::Error> {
let mut lock = None;
let mut sf = None;
if opts.seqfile != "-" {
lock = Some(seqfile::prepare_seqfile_lock(&opts.seqfile, true)?);
sf = Some(seqfile::SeqFile::open(
&opts.seqfile,
lock.as_mut().unwrap(),
)?);
};
let meta = FSMetaV1 {
seq: match sf {
None => 1,
Some(ref mut x) => x.increment()?,
},
cmd_type: CommandTypeV1::NOP,
..FSMetaV1::default()
};
std::mem::drop(sf);
std::mem::drop(lock);
let mut fd_stdout = std::io::stdout();
jobfile::write_jobfile_header(meta, &mut fd_stdout)
}
pub fn cmd_preparefail(opts: &SFOpts) -> Result<(), anyhow::Error> {
let mut lock = None;
let mut sf = None;
if opts.seqfile != "-" {
lock = Some(seqfile::prepare_seqfile_lock(&opts.seqfile, true)?);
sf = Some(seqfile::SeqFile::open(
&opts.seqfile,
lock.as_mut().unwrap(),
)?);
};
let meta = FSMetaV1 {
seq: match sf {
None => 1,
Some(ref mut x) => x.increment()?,
},
cmd_type: CommandTypeV1::Fail,
..FSMetaV1::default()
};
std::mem::drop(sf);
std::mem::drop(lock);
let mut fd_stdout = std::io::stdout();
jobfile::write_jobfile_header(meta, &mut fd_stdout)
}
pub fn cmd_prepare(opts: &PrepareOpts) -> Result<(), anyhow::Error> {
let mut lock = None;
let mut sf = None;
if opts.sfopts.seqfile != "-" {
lock = Some(seqfile::prepare_seqfile_lock(&opts.sfopts.seqfile, true)?);
sf = Some(seqfile::SeqFile::open(
&opts.sfopts.seqfile,
lock.as_mut().unwrap(),
)?);
};
let u8params: Vec<Vec<u8>> = opts
.params
.iter()
.map(|x| Vec::from(x.as_bytes()))
.collect();
let mut envtosend: Vec<(Vec<u8>, Vec<u8>)> = vec![];
for (key, val) in std::env::vars_os() {
if key.as_bytes().starts_with(ENV_PREFIX) {
envtosend.push((
Vec::from(&key.as_bytes()[ENV_PREFIX.len()..]),
Vec::from(val.as_bytes()),
));
}
}
let meta = FSMetaV1 {
seq: match sf {
None => 1,
Some(ref mut x) => x.increment()?,
},
cmd_type: CommandTypeV1::Command(CommandDataV1 {
params: u8params,
env: envtosend,
}),
..FSMetaV1::default()
};
std::mem::drop(sf);
std::mem::drop(lock);
let mut fd_stdout = std::io::stdout();
if let Some(inpath) = &opts.input {
if inpath == "-" {
let mut fd_stdin = std::io::stdin();
jobfile::write_jobfile_header_payload(meta, &mut fd_stdin, &mut fd_stdout)?;
} else {
let mut fd_input = std::fs::File::open(inpath)?;
jobfile::write_jobfile_header_payload(meta, &mut fd_input, &mut fd_stdout)?;
}
} else {
jobfile::write_jobfile_header(meta, &mut fd_stdout)?;
}
Ok(())
}