diff options
Diffstat (limited to 'cli/src')
| -rw-r--r-- | cli/src/args.rs | 6 | ||||
| -rw-r--r-- | cli/src/main.rs | 111 | ||||
| -rw-r--r-- | cli/src/trace.rs | 7 |
3 files changed, 65 insertions, 59 deletions
diff --git a/cli/src/args.rs b/cli/src/args.rs index 699dbb97..7eb4f4e2 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -18,7 +18,8 @@ pub struct CliArguments { #[command(subcommand)] pub command: Command, - /// Sets the level of verbosity: 0 = none, 1 = warning & error, 2 = info, 3 = debug, 4 = trace + /// Sets the level of logging verbosity: + /// -v = warning & error, -vv = info, -vvv = debug, -vvvv = trace #[clap(short, long, action = ArgAction::Count)] pub verbosity: u8, } @@ -68,8 +69,7 @@ pub struct CompileCommand { #[arg(long = "open")] pub open: Option<Option<String>>, - /// Produces a flamegraph of the compilation process and saves it to the - /// given file or to `flamegraph.svg` in the current working directory. + /// Produces a flamegraph of the compilation process #[arg(long = "flamegraph", value_name = "OUTPUT_SVG")] pub flamegraph: Option<Option<PathBuf>>, } diff --git a/cli/src/main.rs b/cli/src/main.rs index 4e9bd43e..eb11cfc6 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -7,7 +7,6 @@ use std::fs::{self, File}; use std::hash::Hash; use std::io::{self, Write}; use std::path::{Path, PathBuf}; -use std::process; use atty::Stream; use clap::Parser; @@ -30,12 +29,47 @@ use typst::World; use walkdir::WalkDir; use crate::args::{CliArguments, Command, CompileCommand}; -use crate::trace::init_tracing; type CodespanResult<T> = Result<T, CodespanError>; type CodespanError = codespan_reporting::files::Error; -pub fn typst_version() -> &'static str { +/// Entry point. +fn main() { + let arguments = CliArguments::parse(); + let _guard = match crate::trace::init_tracing(&arguments) { + Ok(guard) => guard, + Err(err) => { + eprintln!("failed to initialize tracing {}", err); + None + } + }; + + let res = match &arguments.command { + Command::Compile(_) | Command::Watch(_) => { + compile(CompileSettings::with_arguments(arguments)) + } + Command::Fonts(_) => fonts(FontsSettings::with_arguments(arguments)), + }; + + if let Err(msg) = res { + print_error(&msg).expect("failed to print error"); + } +} + +/// Print an application-level error (independent from a source file). +fn print_error(msg: &str) -> io::Result<()> { + let mut w = StandardStream::stderr(ColorChoice::Auto); + let styles = term::Styles::default(); + + w.set_color(&styles.header_error)?; + write!(w, "error")?; + + w.reset()?; + writeln!(w, ": {msg}.") +} + +/// Used by `args.rs`. +fn typst_version() -> &'static str { env!("TYPST_VERSION") } @@ -62,7 +96,7 @@ struct CompileSettings { impl CompileSettings { /// Create a new compile settings from the field values. - pub fn new( + fn new( input: PathBuf, output: Option<PathBuf>, watch: bool, @@ -81,7 +115,7 @@ impl CompileSettings { /// /// # Panics /// Panics if the command is not a compile or watch command. - pub fn with_arguments(args: CliArguments) -> Self { + fn with_arguments(args: CliArguments) -> Self { let watch = matches!(args.command, Command::Watch(_)); let CompileCommand { input, output, open, .. } = match args.command { Command::Compile(command) => command, @@ -102,7 +136,7 @@ struct FontsSettings { impl FontsSettings { /// Create font settings from the field values. - pub fn new(font_paths: Vec<PathBuf>, variants: bool) -> Self { + fn new(font_paths: Vec<PathBuf>, variants: bool) -> Self { Self { font_paths, variants } } @@ -110,7 +144,7 @@ impl FontsSettings { /// /// # Panics /// Panics if the command is not a fonts command. - pub fn with_arguments(args: CliArguments) -> Self { + fn with_arguments(args: CliArguments) -> Self { match args.command { Command::Fonts(command) => Self::new(args.font_paths, command.variants), _ => unreachable!(), @@ -118,41 +152,6 @@ impl FontsSettings { } } -/// Entry point. -fn main() { - let arguments = CliArguments::parse(); - let _guard = match init_tracing(&arguments) { - Ok(guard) => guard, - Err(err) => { - eprintln!("failed to initialize tracing, reason: {}", err); - return; - } - }; - - let res = match &arguments.command { - Command::Compile(_) | Command::Watch(_) => { - compile(CompileSettings::with_arguments(arguments)) - } - Command::Fonts(_) => fonts(FontsSettings::with_arguments(arguments)), - }; - - if let Err(msg) = res { - print_error(&msg).expect("failed to print error"); - } -} - -/// Print an application-level error (independent from a source file). -fn print_error(msg: &str) -> io::Result<()> { - let mut w = StandardStream::stderr(ColorChoice::Auto); - let styles = term::Styles::default(); - - w.set_color(&styles.header_error)?; - write!(w, "error")?; - - w.reset()?; - writeln!(w, ": {msg}.") -} - /// Execute a compilation command. fn compile(mut command: CompileSettings) -> StrResult<()> { let root = if let Some(root) = &command.root { @@ -173,10 +172,11 @@ fn compile(mut command: CompileSettings) -> StrResult<()> { let mut world = SystemWorld::new(root, &command.font_paths); // Perform initial compilation. - let failed = compile_once(&mut world, &command)?; + let ok = compile_once(&mut world, &command)?; - // open the file if requested, this must be done on the first **successful** compilation - if !failed { + // Open the file if requested, this must be done on the first **successful** + // compilation. + if ok { if let Some(open) = command.open.take() { open_file(open.as_deref(), &command.output)?; } @@ -184,8 +184,8 @@ fn compile(mut command: CompileSettings) -> StrResult<()> { if !command.watch { // Return with non-zero exit code in case of error. - if failed { - process::exit(1); + if !ok { + std::process::exit(1); } return Ok(()); @@ -223,18 +223,23 @@ fn compile(mut command: CompileSettings) -> StrResult<()> { } if recompile { - compile_once(&mut world, &command)?; + let ok = compile_once(&mut world, &command)?; comemo::evict(30); - // open the file if requested, this must be done on the first **successful** compilation - if let Some(open) = command.open.take() { - open_file(open.as_deref(), &command.output)?; + // Ipen the file if requested, this must be done on the first + // **successful** compilation + if ok { + if let Some(open) = command.open.take() { + open_file(open.as_deref(), &command.output)?; + } } } } } /// Compile a single time. +/// +/// Returns whether it compiled without errors. #[tracing::instrument(skip_all)] fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult<bool> { tracing::info!("Starting compilation"); @@ -252,7 +257,7 @@ fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult status(command, Status::Success).unwrap(); tracing::info!("Compilation succeeded"); - Ok(false) + Ok(true) } // Print diagnostics. @@ -262,7 +267,7 @@ fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult .map_err(|_| "failed to print diagnostics")?; tracing::info!("Compilation failed"); - Ok(true) + Ok(false) } } } diff --git a/cli/src/trace.rs b/cli/src/trace.rs index 0b37c5fc..06b5668e 100644 --- a/cli/src/trace.rs +++ b/cli/src/trace.rs @@ -127,9 +127,10 @@ pub fn init_tracing(args: &CliArguments) -> Result<Option<TracingGuard>, Error> /// Returns the log level filter for the given verbosity level. fn level_filter(args: &CliArguments) -> LevelFilter { match args.verbosity { - 0 => LevelFilter::WARN, - 1 => LevelFilter::INFO, - 2 => LevelFilter::DEBUG, + 0 => LevelFilter::OFF, + 1 => LevelFilter::WARN, + 2 => LevelFilter::INFO, + 3 => LevelFilter::DEBUG, _ => LevelFilter::TRACE, } } |
