summaryrefslogtreecommitdiff
path: root/cli/src
diff options
context:
space:
mode:
Diffstat (limited to 'cli/src')
-rw-r--r--cli/src/args.rs6
-rw-r--r--cli/src/main.rs111
-rw-r--r--cli/src/trace.rs7
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,
}
}