use clap::Args;
use tectonic::{
config::is_config_test_mode_activated,
config::PersistentConfig,
docmodel::{DocumentExt, DocumentSetupOptions},
errors::Result,
tt_error, tt_note,
};
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, Args, Clone)]
pub struct BuildCommand {
#[arg(long)]
untrusted: bool,
#[arg(short = 'C', long)]
only_cached: bool,
#[arg(short, long)]
keep_intermediates: bool,
#[arg(long)]
keep_logs: bool,
#[arg(long = "print", short)]
print_stdout: bool,
#[arg(long)]
open: bool,
#[arg(long, help = "Specify the target of the build.")]
target: Option<String>,
#[arg(long, short)]
bundle: Option<String>,
}
impl TectonicCommand for BuildCommand {
fn customize(&self, _cc: &mut CommandCustomizations) {}
fn execute(self, config: PersistentConfig, status: &mut dyn StatusBackend) -> Result<i32> {
if let Some(url) = &self.bundle {
tt_note!(status, "--bundle {} ignored", url);
tt_note!(status, "using workspace bundle configuration");
}
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);
for output_name in doc.output_names() {
if let Some(out) = self.target.as_ref() {
if out != output_name {
continue;
}
}
let mut builder = doc.setup_session(output_name, &setup_options, status)?;
builder
.format_cache_path(config.format_cache_path()?)
.keep_intermediates(self.keep_intermediates)
.keep_logs(self.keep_logs)
.print_stdout(self.print_stdout);
crate::compile::run_and_report(builder, status)?;
if self.open {
let out_file = doc.output_main_file(output_name);
if is_config_test_mode_activated() {
tt_note!(status, "not opening `{}` -- test mode", out_file.display());
} else {
tt_note!(status, "opening `{}`", out_file.display());
if let Err(e) = open::that(&out_file) {
tt_error!(
status,
"failed to open `{}` with system handler",
out_file.display();
e.into()
)
}
}
}
}
Ok(0)
}
}