Skip to content

Commit

Permalink
feat(json-schema): Add command to output the JSON schema of a Resolve…
Browse files Browse the repository at this point in the history
…dRegistry object.
  • Loading branch information
lquerel committed May 30, 2024
1 parent 1259bed commit 70c45d9
Show file tree
Hide file tree
Showing 15 changed files with 330 additions and 67 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ walkdir.workspace = true
include_dir.workspace = true
thiserror.workspace = true
miette.workspace = true
schemars.workspace = true

rayon = "1.10.0"

Expand Down
5 changes: 5 additions & 0 deletions crates/weaver_common/src/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,9 @@ impl crate::Logger for Logger {
.expect("Failed to lock messages")
.push(LogMessage::Log(message.to_owned()));
}

/// Mute all the messages except for the warnings and errors.
fn mute(&self) {

Check warning on line 156 in crates/weaver_common/src/in_memory.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/in_memory.rs#L156

Added line #L156 was not covered by tests
// We do not mute the logger in this implementation.
}
}
57 changes: 56 additions & 1 deletion crates/weaver_common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ pub trait Logger {

/// Logs a message without icon.
fn log(&self, message: &str);

/// Mute all the messages except for the warnings and errors.
fn mute(&self);
}

/// A generic logger that can be used to log messages to the console.
Expand All @@ -55,6 +58,7 @@ pub trait Logger {
pub struct ConsoleLogger {
logger: Arc<Mutex<paris::Logger<'static>>>,
debug_level: u8,
mute: Arc<Mutex<bool>>,
}

impl ConsoleLogger {
Expand All @@ -64,14 +68,16 @@ impl ConsoleLogger {
ConsoleLogger {
logger: Arc::new(Mutex::new(paris::Logger::new())),
debug_level,
mute: Arc::new(Mutex::new(false)),

Check warning on line 71 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L71

Added line #L71 was not covered by tests
}
}
}

impl Logger for ConsoleLogger {
/// Logs an trace message (only with debug enabled).
fn trace(&self, message: &str) {
if self.debug_level > 0 {
let mute = *self.mute.lock().expect("Failed to lock mute");
if self.debug_level > 0 && !mute {

Check warning on line 80 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L79-L80

Added lines #L79 - L80 were not covered by tests
_ = self
.logger
.lock()
Expand All @@ -82,6 +88,10 @@ impl Logger for ConsoleLogger {

/// Logs an info message.
fn info(&self, message: &str) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 91 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L91

Added line #L91 was not covered by tests
return;
}

_ = self
.logger
.lock()
Expand Down Expand Up @@ -109,6 +119,10 @@ impl Logger for ConsoleLogger {

/// Logs a success message.
fn success(&self, message: &str) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 122 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L122

Added line #L122 was not covered by tests
return;
}

_ = self
.logger
.lock()
Expand All @@ -118,6 +132,10 @@ impl Logger for ConsoleLogger {

/// Logs a newline.
fn newline(&self, count: usize) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 135 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L135

Added line #L135 was not covered by tests
return;
}

_ = self
.logger
.lock()
Expand All @@ -127,6 +145,10 @@ impl Logger for ConsoleLogger {

/// Indents the logger.
fn indent(&self, count: usize) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 148 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L148

Added line #L148 was not covered by tests
return;
}

_ = self
.logger
.lock()
Expand All @@ -136,11 +158,19 @@ impl Logger for ConsoleLogger {

/// Stops a loading message.
fn done(&self) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 161 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L161

Added line #L161 was not covered by tests
return;
}

_ = self.logger.lock().expect("Failed to lock logger").done();
}

/// Adds a style to the logger.
fn add_style(&self, name: &str, styles: Vec<&'static str>) -> &Self {
if *self.mute.lock().expect("Failed to lock mute") {
return self;

Check warning on line 171 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L170-L171

Added lines #L170 - L171 were not covered by tests
}

_ = self
.logger
.lock()
Expand All @@ -151,6 +181,10 @@ impl Logger for ConsoleLogger {

/// Logs a loading message with a spinner.
fn loading(&self, message: &str) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 184 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L184

Added line #L184 was not covered by tests
return;
}

_ = self
.logger
.lock()
Expand All @@ -160,18 +194,31 @@ impl Logger for ConsoleLogger {

/// Forces the logger to not print a newline for the next message.
fn same(&self) -> &Self {
if *self.mute.lock().expect("Failed to lock mute") {
return self;

Check warning on line 198 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L197-L198

Added lines #L197 - L198 were not covered by tests
}

_ = self.logger.lock().expect("Failed to lock logger").same();
self
}

/// Logs a message without icon.
fn log(&self, message: &str) {
if *self.mute.lock().expect("Failed to lock mute") {

Check warning on line 207 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L207

Added line #L207 was not covered by tests
return;
}

_ = self
.logger
.lock()
.expect("Failed to lock logger")
.log(message);
}

/// Mute all the messages except for the warnings and errors.
fn mute(&self) {
*self.mute.lock().expect("Failed to lock mute") = true;

Check warning on line 220 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L219-L220

Added lines #L219 - L220 were not covered by tests
}
}

/// A logger that does not log anything.
Expand Down Expand Up @@ -226,6 +273,9 @@ impl Logger for NullLogger {

/// Logs a message without icon.
fn log(&self, _: &str) {}

/// Mute all the messages except for the warnings and errors.
fn mute(&self) {}

Check warning on line 278 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L278

Added line #L278 was not covered by tests
}

/// A logger that can be used in unit or integration tests.
Expand Down Expand Up @@ -363,4 +413,9 @@ impl Logger for TestLogger {
.expect("Failed to lock logger")
.log(message);
}

/// Mute all the messages except for the warnings and errors.
fn mute(&self) {

Check warning on line 418 in crates/weaver_common/src/lib.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/lib.rs#L418

Added line #L418 was not covered by tests
// We do not need to mute the logger in the tests.
}
}
5 changes: 5 additions & 0 deletions crates/weaver_common/src/quiet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,9 @@ impl Logger for QuietLogger {

/// Logs a message without icon.
fn log(&self, _message: &str) {}

/// Mute all the messages except for the warnings and errors.
fn mute(&self) {

Check warning on line 83 in crates/weaver_common/src/quiet.rs

View check run for this annotation

Codecov / codecov/patch

crates/weaver_common/src/quiet.rs#L83

Added line #L83 was not covered by tests
// Do nothing
}
}
17 changes: 10 additions & 7 deletions src/diagnostic/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Initializes a `diagnostic_templates` directory to define or override diagnostic output formats.

use crate::diagnostic::{Error, DEFAULT_DIAGNOSTIC_TEMPLATES};
use crate::DiagnosticArgs;
use crate::{DiagnosticArgs, ExitDirectives};
use clap::Args;
use include_dir::DirEntry;
use std::fs;
Expand Down Expand Up @@ -32,7 +32,7 @@ pub struct DiagnosticInitArgs {
pub(crate) fn command(
logger: impl Logger + Sync + Clone,
args: &DiagnosticInitArgs,
) -> Result<(), DiagnosticMessages> {
) -> Result<ExitDirectives, DiagnosticMessages> {
extract(args.diagnostic_templates_dir.clone(), &args.target).map_err(|e| {
Error::InitDiagnosticError {
path: args.diagnostic_templates_dir.clone(),
Expand All @@ -44,7 +44,10 @@ pub(crate) fn command(
"Diagnostic templates initialized at {:?}",
args.diagnostic_templates_dir
));
Ok(())
Ok(ExitDirectives {
exit_code: 0,
quiet_mode: false,
})
}

/// Extracts the diagnostic templates to the specified path for the given target.
Expand Down Expand Up @@ -104,9 +107,9 @@ mod tests {
})),
};

let exit_code = run_command(&cli, logger.clone());
let exit_directive = run_command(&cli, logger.clone());
// The command should succeed.
assert_eq!(exit_code, 0);
assert_eq!(exit_directive.exit_code, 0);

// Check the presence of 3 subdirectories in the temp_output directory
let subdirs = fs::read_dir(&temp_output).unwrap().count();
Expand All @@ -128,9 +131,9 @@ mod tests {
})),
};

let exit_code = run_command(&cli, logger.clone());
let exit_directive = run_command(&cli, logger.clone());
// The command should succeed.
assert_eq!(exit_code, 0);
assert_eq!(exit_directive.exit_code, 0);

// Check the presence of 3 subdirectories in the temp_output directory
let subdirs = fs::read_dir(&temp_output).unwrap().count();
Expand Down
66 changes: 45 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,23 @@ impl Default for DiagnosticArgs {
/// Result of a command execution.
#[derive(Debug)]
pub(crate) struct CmdResult {
pub(crate) command_result: Result<(), DiagnosticMessages>,
pub(crate) command_result: Result<ExitDirectives, DiagnosticMessages>,
pub(crate) diagnostic_args: Option<DiagnosticArgs>,
}

/// Exit directives.
#[derive(Debug, Clone)]
pub(crate) struct ExitDirectives {
/// Exit code.
exit_code: i32,
/// Quiet mode.
quiet_mode: bool,
}

impl CmdResult {
/// Create a new command result.
pub(crate) fn new(
command_result: Result<(), DiagnosticMessages>,
command_result: Result<ExitDirectives, DiagnosticMessages>,
diagnostic_args: Option<DiagnosticArgs>,
) -> Self {
Self {
Expand All @@ -71,45 +80,61 @@ fn main() {
let cli = Cli::parse();

let start = std::time::Instant::now();
let exit_code = if cli.quiet {
let exit_directives = if cli.quiet {
let log = QuietLogger::new();
run_command(&cli, log)
} else {
let log = ConsoleLogger::new(cli.debug);
run_command(&cli, log)
};

if !cli.quiet {
if !cli.quiet && !exit_directives.quiet_mode {
let elapsed = start.elapsed();
println!("Total execution time: {:?}s", elapsed.as_secs_f64());
println!("\nTotal execution time: {:?}s", elapsed.as_secs_f64());
}

// Exit the process with the exit code provided by the `run_command` function.
#[allow(clippy::exit)]
std::process::exit(exit_code);
std::process::exit(exit_directives.exit_code);
}

/// Run the command specified by the CLI arguments and return the exit code.
/// Run the command specified by the CLI arguments and return the exit directives.
#[cfg(not(tarpaulin_include))]
fn run_command(cli: &Cli, log: impl Logger + Sync + Clone) -> i32 {
fn run_command(cli: &Cli, log: impl Logger + Sync + Clone) -> ExitDirectives {
let cmd_result = match &cli.command {
Some(Commands::Registry(params)) => semconv_registry(log.clone(), params),
Some(Commands::Schema(params)) => telemetry_schema(log.clone(), params),
Some(Commands::Diagnostic(params)) => diagnostic::diagnostic(log.clone(), params),
None => return 0,
None => {
return ExitDirectives {
exit_code: 0,
quiet_mode: false,
}
}
};

process_diagnostics(cmd_result, log.clone())
}

/// Render the diagnostic messages based on the diagnostic configuration and return the exit code
/// based on the diagnostic messages.
fn process_diagnostics(cmd_result: CmdResult, logger: impl Logger + Sync + Clone) -> i32 {
/// Render the diagnostic messages based on the diagnostic configuration and return the exit
/// directives based on the diagnostic messages and the CmdResult quiet mode.
fn process_diagnostics(
cmd_result: CmdResult,
logger: impl Logger + Sync + Clone,
) -> ExitDirectives {
let diagnostic_args = if let Some(diagnostic_args) = cmd_result.diagnostic_args {
diagnostic_args
} else {
DiagnosticArgs::default() // Default diagnostic arguments;
};
let mut exit_directives = if let Ok(exit_directives) = &cmd_result.command_result {
exit_directives.clone()
} else {
ExitDirectives {
exit_code: 0,
quiet_mode: false,
}
};

if let Err(diagnostic_messages) = cmd_result.command_result {
let loader = EmbeddedFileLoader::try_new(
Expand All @@ -132,22 +157,21 @@ fn process_diagnostics(cmd_result: CmdResult, logger: impl Logger + Sync + Clone
"Failed to render the diagnostic messages. Error: {}",
e
));
return 1;
exit_directives.exit_code = 1;
return exit_directives;
}
}
}
Err(e) => {
logger.error(&format!("Failed to create the template engine to render the diagnostic messages. Error: {}", e));
return 1;
exit_directives.exit_code = 1;
return exit_directives;
}
}
return if diagnostic_messages.has_error() {
1
} else {
0
};
if diagnostic_messages.has_error() {
exit_directives.exit_code = 1;
}
}

// Return 0 if there are no diagnostic messages
0
exit_directives
}
Loading

0 comments on commit 70c45d9

Please sign in to comment.