use std::io::Write;
use clap::Parser;
use tectonic::{
config::PersistentConfig,
ctry,
docmodel::{DocumentExt, DocumentSetupOptions},
driver::PassSetting,
errors::Result,
tt_error,
};
use tectonic_bridge_core::{SecuritySettings, SecurityStance};
use tectonic_docmodel::workspace::Workspace;
use tectonic_status_base::StatusBackend;
use crate::v2cli::{CommandCustomizations, TectonicCommand};
#[derive(Debug, Eq, PartialEq, Parser)]
pub struct DumpCommand {
#[arg(long)]
untrusted: bool,
#[arg(short = 'C', long)]
only_cached: bool,
#[arg(short = 'p', long)]
profile: Option<String>,
#[arg(long = "suffix", short)]
suffix_mode: bool,
#[arg()]
filename: String,
}
impl TectonicCommand for DumpCommand {
fn customize(&self, cc: &mut CommandCustomizations) {
cc.always_stderr = true;
cc.minimal_chatter = true;
}
fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
let ws = Workspace::open_from_environment()?;
let doc = ws.first_document();
let stance = if self.untrusted {
SecurityStance::DisableInsecures
} else {
SecurityStance::MaybeAllowInsecures
};
let mut setup_options =
DocumentSetupOptions::new_with_security(SecuritySettings::new(stance));
setup_options.only_cached(self.only_cached);
let output_name = self
.profile
.as_ref()
.unwrap_or_else(|| doc.outputs.keys().next().unwrap());
let mut builder = doc.setup_session(output_name, &setup_options, status)?;
builder
.format_cache_path(config.format_cache_path()?)
.pass(PassSetting::Tex);
let sess = crate::compile::run_and_report(builder, status)?;
let files = sess.into_file_data();
if self.suffix_mode {
let mut found_any = false;
for (key, info) in &files {
if key.ends_with(&self.filename) {
found_any = true;
ctry!(
std::io::stdout().write_all(&info.data[..]);
"error dumping intermediate file `{}`", key
);
}
}
if !found_any {
tt_error!(
status,
"found no intermediate files with names ending in `{}`",
self.filename
);
return Ok(1);
}
} else {
let info = files
.get(&self.filename)
.ok_or_else(|| format!("no such intermediate file `{}`", self.filename))?;
ctry!(
std::io::stdout().write_all(&info.data[..]);
"error dumping intermediate file `{}`", self.filename
);
}
Ok(0)
}
}