Skip to content

Commit b73904f

Browse files
committed
Log errors by default
Remove imperative `clap::Error::exit`.
1 parent e816e1b commit b73904f

File tree

3 files changed

+55
-53
lines changed

3 files changed

+55
-53
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ edition = "2021"
1717

1818
[dependencies]
1919
# cli deps
20+
anyhow = "1.0.81"
2021
clap = { version = "4.5.4", features = ["derive"] }
2122
tracing-appender = "0.2"
2223
tracing-subscriber = { version = "0.3", features = ["env-filter", "registry"] }

src/bin/bpf-linker.rs

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@
33
#[cfg(feature = "rust-llvm")]
44
extern crate aya_rustc_llvm_proxy;
55

6-
use std::{env, fs, io, path::PathBuf, str::FromStr};
6+
use std::{
7+
env, fs, io,
8+
path::{Path, PathBuf},
9+
str::FromStr,
10+
};
711

812
use bpf_linker::{Cpu, Linker, LinkerOptions, OptLevel, OutputType};
9-
use clap::Parser;
13+
use clap::{
14+
builder::{PathBufValueParser, TypedValueParser as _},
15+
Parser,
16+
};
1017
use thiserror::Error;
11-
use tracing::{info, Level, Subscriber};
12-
use tracing_appender::non_blocking::WorkerGuard;
18+
use tracing::{info, Level};
1319
use tracing_subscriber::{fmt::MakeWriter, prelude::*, EnvFilter};
1420
use tracing_tree::HierarchicalLayer;
1521

@@ -59,6 +65,20 @@ impl FromStr for CliOutputType {
5965
}
6066
}
6167

68+
fn parent_and_file_name(p: PathBuf) -> anyhow::Result<(PathBuf, PathBuf)> {
69+
let mut comps = p.components();
70+
let file_name = comps
71+
.next_back()
72+
.map(|p| match p {
73+
std::path::Component::Normal(p) => Ok(p),
74+
p => Err(anyhow::anyhow!("unexpected path component {:?}", p)),
75+
})
76+
.transpose()?
77+
.ok_or_else(|| anyhow::anyhow!("unexpected empty path"))?;
78+
let parent = comps.as_path();
79+
Ok((parent.to_path_buf(), Path::new(file_name).to_path_buf()))
80+
}
81+
6282
#[derive(Debug, Parser)]
6383
struct CommandLine {
6484
/// LLVM target triple. When not provided, the target is inferred from the inputs
@@ -100,8 +120,12 @@ struct CommandLine {
100120
export_symbols: Option<PathBuf>,
101121

102122
/// Output logs to the given `path`
103-
#[clap(long, value_name = "path")]
104-
log_file: Option<PathBuf>,
123+
#[clap(
124+
long,
125+
value_name = "path",
126+
value_parser = PathBufValueParser::new().try_map(parent_and_file_name),
127+
)]
128+
log_file: Option<(PathBuf, PathBuf)>,
105129

106130
/// Set the log level. If not specified, no logging is used. Can be one of
107131
/// `error`, `warn`, `info`, `debug`, `trace`.
@@ -135,6 +159,7 @@ struct CommandLine {
135159
disable_memory_builtins: bool,
136160

137161
/// Input files. Can be object files or static libraries
162+
#[clap(required = true)]
138163
inputs: Vec<PathBuf>,
139164

140165
/// Comma separated list of symbols to export. See also `--export-symbols`
@@ -161,8 +186,7 @@ where
161186
.with_indent_lines(true)
162187
.with_writer(writer)
163188
}
164-
165-
fn main() {
189+
fn main() -> anyhow::Result<()> {
166190
let args = env::args().map(|arg| {
167191
if arg == "-flavor" {
168192
"--flavor".to_string()
@@ -192,57 +216,38 @@ fn main() {
192216
export,
193217
fatal_errors,
194218
_debug,
195-
} = Parser::parse_from(args);
196-
197-
if inputs.is_empty() {
198-
error("no input files", clap::error::ErrorKind::TooFewValues);
199-
}
219+
} = Parser::try_parse_from(args)?;
200220

201221
// Configure tracing.
202-
if let Some(log_level) = log_level {
203-
let subscriber_registry = tracing_subscriber::registry()
204-
.with(EnvFilter::from_default_env().add_directive(log_level.into()));
205-
let (subscriber, _guard): (
206-
Box<dyn Subscriber + Send + Sync + 'static>,
207-
Option<WorkerGuard>,
208-
) = match log_file {
209-
Some(log_file) => {
210-
let file_appender = tracing_appender::rolling::never(
211-
log_file.parent().unwrap_or_else(|| {
212-
error("invalid log_file", clap::error::ErrorKind::InvalidValue)
213-
}),
214-
log_file.file_name().unwrap_or_else(|| {
215-
error("invalid log_file", clap::error::ErrorKind::InvalidValue)
216-
}),
217-
);
218-
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
222+
let _guard = {
223+
let filter = EnvFilter::from_default_env();
224+
let filter = match log_level {
225+
None => filter,
226+
Some(log_level) => filter.add_directive(log_level.into()),
227+
};
228+
let subscriber_registry = tracing_subscriber::registry().with(filter);
229+
match log_file {
230+
Some((parent, file_name)) => {
231+
let file_appender = tracing_appender::rolling::never(parent, file_name);
232+
let (non_blocking, guard) = tracing_appender::non_blocking(file_appender);
219233
let subscriber = subscriber_registry
220234
.with(tracing_layer(io::stdout))
221235
.with(tracing_layer(non_blocking));
222-
223-
(Box::new(subscriber), Some(_guard))
236+
tracing::subscriber::set_global_default(subscriber).map(|()| Some(guard))
224237
}
225238
None => {
226239
let subscriber = subscriber_registry.with(tracing_layer(io::stderr));
227-
(Box::new(subscriber), None)
240+
tracing::subscriber::set_global_default(subscriber).map(|()| None)
228241
}
229-
};
230-
if let Err(e) = tracing::subscriber::set_global_default(subscriber) {
231-
error(&e.to_string(), clap::error::ErrorKind::Format);
232242
}
233-
}
243+
}?;
234244

235245
info!(
236246
"command line: {:?}",
237247
env::args().collect::<Vec<_>>().join(" ")
238248
);
239249

240-
let export_symbols = export_symbols
241-
.map(fs::read_to_string)
242-
.transpose()
243-
.unwrap_or_else(|e| {
244-
error(&e.to_string(), clap::error::ErrorKind::Io);
245-
});
250+
let export_symbols = export_symbols.map(fs::read_to_string).transpose()?;
246251

247252
// TODO: the data is owned by this call frame; we could make this zero-alloc.
248253
let export_symbols = export_symbols
@@ -282,20 +287,15 @@ fn main() {
282287
btf,
283288
});
284289

285-
if let Err(e) = linker.link() {
286-
error(&e.to_string(), clap::error::ErrorKind::Io);
287-
}
290+
linker.link()?;
288291

289292
if fatal_errors && linker.has_errors() {
290-
error(
291-
"LLVM issued diagnostic with error severity",
292-
clap::error::ErrorKind::Io,
293-
);
293+
return Err(anyhow::anyhow!(
294+
"LLVM issued diagnostic with error severity"
295+
));
294296
}
295-
}
296297

297-
fn error(desc: &str, kind: clap::error::ErrorKind) -> ! {
298-
clap::Error::raw(kind, desc.to_string()).exit();
298+
Ok(())
299299
}
300300

301301
#[cfg(test)]

0 commit comments

Comments
 (0)