mirror of
https://github.com/typst/typst
synced 2025-05-17 02:25:27 +08:00
CLI option for emitting diagnostics in a unix-style short format (#1176)
This commit is contained in:
parent
5400570efa
commit
2cbeeae5da
@ -1,11 +1,16 @@
|
|||||||
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use clap::{ArgAction, Parser, Subcommand};
|
use clap::{ArgAction, Parser, Subcommand, ValueEnum};
|
||||||
|
|
||||||
/// typst creates PDF files from .typ files
|
/// typst creates PDF files from .typ files
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
#[clap(name = "typst", version = crate::typst_version(), author)]
|
#[clap(name = "typst", version = crate::typst_version(), author)]
|
||||||
pub struct CliArguments {
|
pub struct CliArguments {
|
||||||
|
/// The typst command to run
|
||||||
|
#[command(subcommand)]
|
||||||
|
pub command: Command,
|
||||||
|
|
||||||
/// Add additional directories to search for fonts
|
/// Add additional directories to search for fonts
|
||||||
#[clap(long = "font-path", env = "TYPST_FONT_PATHS", value_name = "DIR", action = ArgAction::Append)]
|
#[clap(long = "font-path", env = "TYPST_FONT_PATHS", value_name = "DIR", action = ArgAction::Append)]
|
||||||
pub font_paths: Vec<PathBuf>,
|
pub font_paths: Vec<PathBuf>,
|
||||||
@ -14,16 +19,28 @@ pub struct CliArguments {
|
|||||||
#[clap(long = "root", env = "TYPST_ROOT", value_name = "DIR")]
|
#[clap(long = "root", env = "TYPST_ROOT", value_name = "DIR")]
|
||||||
pub root: Option<PathBuf>,
|
pub root: Option<PathBuf>,
|
||||||
|
|
||||||
/// The typst command to run
|
|
||||||
#[command(subcommand)]
|
|
||||||
pub command: Command,
|
|
||||||
|
|
||||||
/// Sets the level of logging verbosity:
|
/// Sets the level of logging verbosity:
|
||||||
/// -v = warning & error, -vv = info, -vvv = debug, -vvvv = trace
|
/// -v = warning & error, -vv = info, -vvv = debug, -vvvv = trace
|
||||||
#[clap(short, long, action = ArgAction::Count)]
|
#[clap(short, long, action = ArgAction::Count)]
|
||||||
pub verbosity: u8,
|
pub verbosity: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Which format to use for diagnostics.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, ValueEnum)]
|
||||||
|
pub enum DiagnosticFormat {
|
||||||
|
Human,
|
||||||
|
Short,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for DiagnosticFormat {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
self.to_possible_value()
|
||||||
|
.expect("no values are skipped")
|
||||||
|
.get_name()
|
||||||
|
.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// What to do.
|
/// What to do.
|
||||||
#[derive(Debug, Clone, Subcommand)]
|
#[derive(Debug, Clone, Subcommand)]
|
||||||
#[command()]
|
#[command()]
|
||||||
@ -69,13 +86,21 @@ pub struct CompileCommand {
|
|||||||
#[arg(long = "open")]
|
#[arg(long = "open")]
|
||||||
pub open: Option<Option<String>>,
|
pub open: Option<Option<String>>,
|
||||||
|
|
||||||
/// Produces a flamegraph of the compilation process
|
|
||||||
#[arg(long = "flamegraph", value_name = "OUTPUT_SVG")]
|
|
||||||
pub flamegraph: Option<Option<PathBuf>>,
|
|
||||||
|
|
||||||
/// The PPI to use if exported as PNG
|
/// The PPI to use if exported as PNG
|
||||||
#[arg(long = "ppi")]
|
#[arg(long = "ppi")]
|
||||||
pub ppi: Option<f32>,
|
pub ppi: Option<f32>,
|
||||||
|
|
||||||
|
/// In which format to emit diagnostics
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
default_value_t = DiagnosticFormat::Human,
|
||||||
|
value_parser = clap::value_parser!(DiagnosticFormat)
|
||||||
|
)]
|
||||||
|
pub diagnostic_format: DiagnosticFormat,
|
||||||
|
|
||||||
|
/// Produces a flamegraph of the compilation process
|
||||||
|
#[arg(long = "flamegraph", value_name = "OUTPUT_SVG")]
|
||||||
|
pub flamegraph: Option<Option<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List all discovered fonts in system and custom font paths
|
/// List all discovered fonts in system and custom font paths
|
||||||
|
@ -34,7 +34,7 @@ use typst::util::{Buffer, PathExt};
|
|||||||
use typst::World;
|
use typst::World;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::args::{CliArguments, Command, CompileCommand};
|
use crate::args::{CliArguments, Command, CompileCommand, DiagnosticFormat};
|
||||||
|
|
||||||
type CodespanResult<T> = Result<T, CodespanError>;
|
type CodespanResult<T> = Result<T, CodespanError>;
|
||||||
type CodespanError = codespan_reporting::files::Error;
|
type CodespanError = codespan_reporting::files::Error;
|
||||||
@ -111,12 +111,16 @@ struct CompileSettings {
|
|||||||
/// The open command to use.
|
/// The open command to use.
|
||||||
open: Option<Option<String>>,
|
open: Option<Option<String>>,
|
||||||
|
|
||||||
/// The ppi to use for png export
|
/// The PPI to use for PNG export.
|
||||||
ppi: Option<f32>,
|
ppi: Option<f32>,
|
||||||
|
|
||||||
|
/// In which format to emit diagnostics
|
||||||
|
diagnostic_format: DiagnosticFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompileSettings {
|
impl CompileSettings {
|
||||||
/// Create a new compile settings from the field values.
|
/// Create a new compile settings from the field values.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn new(
|
fn new(
|
||||||
input: PathBuf,
|
input: PathBuf,
|
||||||
output: Option<PathBuf>,
|
output: Option<PathBuf>,
|
||||||
@ -125,12 +129,22 @@ impl CompileSettings {
|
|||||||
font_paths: Vec<PathBuf>,
|
font_paths: Vec<PathBuf>,
|
||||||
open: Option<Option<String>>,
|
open: Option<Option<String>>,
|
||||||
ppi: Option<f32>,
|
ppi: Option<f32>,
|
||||||
|
diagnostic_format: DiagnosticFormat,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let output = match output {
|
let output = match output {
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
None => input.with_extension("pdf"),
|
None => input.with_extension("pdf"),
|
||||||
};
|
};
|
||||||
Self { input, output, watch, root, font_paths, open, ppi }
|
Self {
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
watch,
|
||||||
|
root,
|
||||||
|
font_paths,
|
||||||
|
open,
|
||||||
|
diagnostic_format,
|
||||||
|
ppi,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new compile settings from the CLI arguments and a compile command.
|
/// Create a new compile settings from the CLI arguments and a compile command.
|
||||||
@ -139,12 +153,23 @@ impl CompileSettings {
|
|||||||
/// Panics if the command is not a compile or watch command.
|
/// Panics if the command is not a compile or watch command.
|
||||||
fn with_arguments(args: CliArguments) -> Self {
|
fn with_arguments(args: CliArguments) -> Self {
|
||||||
let watch = matches!(args.command, Command::Watch(_));
|
let watch = matches!(args.command, Command::Watch(_));
|
||||||
let CompileCommand { input, output, open, ppi, .. } = match args.command {
|
let CompileCommand { input, output, open, ppi, diagnostic_format, .. } =
|
||||||
Command::Compile(command) => command,
|
match args.command {
|
||||||
Command::Watch(command) => command,
|
Command::Compile(command) => command,
|
||||||
_ => unreachable!(),
|
Command::Watch(command) => command,
|
||||||
};
|
_ => unreachable!(),
|
||||||
Self::new(input, output, watch, args.root, args.font_paths, open, ppi)
|
};
|
||||||
|
|
||||||
|
Self::new(
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
watch,
|
||||||
|
args.root,
|
||||||
|
args.font_paths,
|
||||||
|
open,
|
||||||
|
ppi,
|
||||||
|
diagnostic_format,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +304,7 @@ fn compile_once(world: &mut SystemWorld, command: &CompileSettings) -> StrResult
|
|||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
set_failed();
|
set_failed();
|
||||||
status(command, Status::Error).unwrap();
|
status(command, Status::Error).unwrap();
|
||||||
print_diagnostics(world, *errors)
|
print_diagnostics(world, *errors, command.diagnostic_format)
|
||||||
.map_err(|_| "failed to print diagnostics")?;
|
.map_err(|_| "failed to print diagnostics")?;
|
||||||
tracing::info!("Compilation failed");
|
tracing::info!("Compilation failed");
|
||||||
Ok(false)
|
Ok(false)
|
||||||
@ -400,9 +425,17 @@ impl Status {
|
|||||||
fn print_diagnostics(
|
fn print_diagnostics(
|
||||||
world: &SystemWorld,
|
world: &SystemWorld,
|
||||||
errors: Vec<SourceError>,
|
errors: Vec<SourceError>,
|
||||||
|
diagnostic_format: DiagnosticFormat,
|
||||||
) -> Result<(), codespan_reporting::files::Error> {
|
) -> Result<(), codespan_reporting::files::Error> {
|
||||||
let mut w = StandardStream::stderr(ColorChoice::Auto);
|
let mut w = match diagnostic_format {
|
||||||
let config = term::Config { tab_width: 2, ..Default::default() };
|
DiagnosticFormat::Human => color_stream(),
|
||||||
|
DiagnosticFormat::Short => StandardStream::stderr(ColorChoice::Never),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut config = term::Config { tab_width: 2, ..Default::default() };
|
||||||
|
if diagnostic_format == DiagnosticFormat::Short {
|
||||||
|
config.display_style = term::DisplayStyle::Short;
|
||||||
|
}
|
||||||
|
|
||||||
for error in errors {
|
for error in errors {
|
||||||
// The main diagnostic.
|
// The main diagnostic.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user