Skip to content

Commit 995a1ca

Browse files
committed
entry format config is tuneable
1 parent bb0a059 commit 995a1ca

File tree

5 files changed

+64
-39
lines changed

5 files changed

+64
-39
lines changed

bear/src/config.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@
6666
//! directory: canonical
6767
//! file: canonical
6868
//! output: canonical
69+
//! entry:
70+
//! command_as_array: true
71+
//! keep_output_field: true
6972
//! ```
7073
//!
7174
//! ```yaml
@@ -334,6 +337,8 @@ mod types {
334337
pub struct Format {
335338
#[serde(default)]
336339
pub paths: PathFormat,
340+
#[serde(default)]
341+
pub entry: EntryFormat,
337342
}
338343

339344
/// Format configuration of paths in the JSON compilation database.
@@ -358,6 +363,24 @@ mod types {
358363
Relative,
359364
}
360365

366+
/// Configuration for formatting output entries.
367+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
368+
pub struct EntryFormat {
369+
#[serde(default = "default_enabled")]
370+
pub command_field_as_array: bool,
371+
#[serde(default = "default_enabled")]
372+
pub keep_output_field: bool,
373+
}
374+
375+
impl Default for EntryFormat {
376+
fn default() -> Self {
377+
Self {
378+
command_field_as_array: true,
379+
keep_output_field: true,
380+
}
381+
}
382+
}
383+
361384
pub(super) const SUPPORTED_SCHEMA_VERSION: &str = "4.0";
362385
const PRELOAD_LIBRARY_PATH: &str = env!("PRELOAD_LIBRARY_PATH");
363386
const WRAPPER_EXECUTABLE_PATH: &str = env!("WRAPPER_EXECUTABLE_PATH");
@@ -382,14 +405,14 @@ mod types {
382405
}
383406

384407
// Custom deserialization function to validate the schema version
385-
fn validate_schema_version<'de, D>(deserializer: D) -> std::result::Result<String, D::Error>
408+
fn validate_schema_version<'de, D>(deserializer: D) -> Result<String, D::Error>
386409
where
387410
D: serde::Deserializer<'de>,
388411
{
389412
let schema: String = Deserialize::deserialize(deserializer)?;
390413
if schema != SUPPORTED_SCHEMA_VERSION {
391414
use serde::de::Error;
392-
Err(D::Error::custom(format!(
415+
Err(Error::custom(format!(
393416
"Unsupported schema version: {}. Expected: {}",
394417
schema, SUPPORTED_SCHEMA_VERSION
395418
)))
@@ -624,6 +647,10 @@ pub mod loader {
624647
file: PathResolver::Canonical,
625648
output: PathResolver::Canonical,
626649
},
650+
entry: EntryFormat {
651+
command_field_as_array: true,
652+
keep_output_field: true,
653+
},
627654
},
628655
},
629656
schema: String::from("4.0"),
@@ -678,6 +705,10 @@ pub mod loader {
678705
file: PathResolver::Canonical,
679706
output: PathResolver::Canonical,
680707
},
708+
entry: EntryFormat {
709+
command_field_as_array: true,
710+
keep_output_field: true,
711+
},
681712
},
682713
},
683714
schema: String::from("4.0"),
@@ -737,6 +768,9 @@ pub mod loader {
737768
directory: relative
738769
file: relative
739770
output: relative
771+
entry:
772+
command_field_as_array: false
773+
keep_output_field: false
740774
"#;
741775

742776
let result = Loader::from_reader(content).unwrap();
@@ -781,6 +815,10 @@ pub mod loader {
781815
file: PathResolver::Relative,
782816
output: PathResolver::Relative,
783817
},
818+
entry: EntryFormat {
819+
command_field_as_array: false,
820+
keep_output_field: false,
821+
},
784822
},
785823
},
786824
schema: String::from("4.0"),

bear/src/output/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ impl TryFrom<(&args::BuildSemantic, &config::Output)> for OutputWriter {
4848
fn try_from(value: (&args::BuildSemantic, &config::Output)) -> Result<Self, Self::Error> {
4949
let (args, config) = value;
5050
match config {
51-
config::Output::Clang { duplicates, .. } => {
51+
config::Output::Clang {
52+
duplicates, format, ..
53+
} => {
5254
let final_file_name = path::Path::new(&args.file_name);
5355
let temp_file_name = final_file_name.with_extension("tmp");
5456

@@ -58,7 +60,8 @@ impl TryFrom<(&args::BuildSemantic, &config::Output)> for OutputWriter {
5860
AtomicClangOutputWriter::new(unique_writer, &temp_file_name, final_file_name);
5961
let append_writer =
6062
AppendClangOutputWriter::new(atomic_writer, args.append, final_file_name);
61-
let formatted_writer = ConverterClangOutputWriter::new(append_writer);
63+
let formatted_writer =
64+
ConverterClangOutputWriter::new(append_writer, &format.entry);
6265

6366
Ok(Self::Clang(formatted_writer))
6467
}

bear/src/output/writers.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use super::formats::{FileFormat, JsonCompilationDatabase, JsonSemanticDatabase};
44
use crate::semantic::clang::{DuplicateEntryFilter, Entry};
5-
use crate::semantic::{FormatConfig, Formattable};
5+
use crate::semantic::Formattable;
66
use crate::{config, semantic};
77
use anyhow::Context;
88
use std::{fs, io, path};
@@ -49,14 +49,16 @@ impl IteratorWriter<semantic::Command> for SemanticOutputWriter {
4949

5050
/// Formats `semantic::CompilerCall` instances into `Entry` objects.
5151
pub(super) struct ConverterClangOutputWriter<T: IteratorWriter<Entry>> {
52-
format: FormatConfig,
52+
format: config::EntryFormat,
5353
writer: T,
5454
}
5555

5656
impl<T: IteratorWriter<Entry>> ConverterClangOutputWriter<T> {
57-
pub(super) fn new(writer: T) -> Self {
58-
let format = FormatConfig::default();
59-
Self { format, writer }
57+
pub(super) fn new(writer: T, format: &config::EntryFormat) -> Self {
58+
Self {
59+
format: format.clone(),
60+
writer,
61+
}
6062
}
6163
}
6264

bear/src/semantic/command.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! It defines how to classify arguments, group them, and convert them into entries
66
//! for the final compilation database.
77
8-
use crate::semantic::{clang, FormatConfig, Formattable};
8+
use crate::semantic::{clang, EntryFormat, Formattable};
99
use serde::{Deserialize, Serialize};
1010
use std::path::PathBuf;
1111

@@ -92,7 +92,7 @@ impl Formattable for CompilerCommand {
9292
///
9393
/// It processes the command arguments, identifies source files, and constructs
9494
/// entries with the executable, arguments, working directory, and output file if present.
95-
fn to_entries(&self, config: &FormatConfig) -> Vec<clang::Entry> {
95+
fn to_entries(&self, config: &EntryFormat) -> Vec<clang::Entry> {
9696
// Find all source files in the arguments
9797
let source_files: Vec<String> = self
9898
.arguments
@@ -161,7 +161,7 @@ mod test {
161161
],
162162
);
163163

164-
let config = FormatConfig::default();
164+
let config = EntryFormat::default();
165165
let entries = sut.to_entries(&config);
166166

167167
let expected = vec![clang::Entry::from_arguments_str(
@@ -188,7 +188,7 @@ mod test {
188188
],
189189
);
190190

191-
let config = FormatConfig::default();
191+
let config = EntryFormat::default();
192192
let entries = sut.to_entries(&config);
193193

194194
let expected = vec![
@@ -219,7 +219,7 @@ mod test {
219219
)],
220220
);
221221

222-
let config = FormatConfig::default();
222+
let config = EntryFormat::default();
223223
let entries = sut.to_entries(&config);
224224

225225
let expected: Vec<clang::Entry> = vec![];
@@ -240,7 +240,7 @@ mod test {
240240
(ArgumentKind::Output, vec!["-o", "main.o"]),
241241
],
242242
);
243-
let config = FormatConfig {
243+
let config = EntryFormat {
244244
keep_output_field: true,
245245
command_field_as_array: false,
246246
};
@@ -269,7 +269,7 @@ mod test {
269269
(ArgumentKind::Output, vec!["-o", "main.o"]),
270270
],
271271
);
272-
let config = FormatConfig {
272+
let config = EntryFormat {
273273
command_field_as_array: true,
274274
keep_output_field: false,
275275
};

bear/src/semantic/mod.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@
1010
//! - [`Command`]: Enum representing recognized command types.
1111
//! - [`Interpreter`]: Trait for recognizing the semantic meaning of an `Execution`.
1212
//! - [`Formattable`]: Trait for converting recognized commands into output entries.
13-
//! - [`FormatConfig`]: Configuration for formatting output entries.
13+
//! - [`EntryFormat`]: Configuration for formatting output entries.
1414
//!
1515
//! Implementers of [`Interpreter`] analyze an `Execution` and determine if it matches a known command.
1616
//! If recognized, they return a boxed [`Command`] representing the semantic meaning of the execution.
1717
//!
1818
//! The [`Formattable`] trait allows recognized commands to be transformed into output entries (e.g.,
19-
//! for a compilation database), using the provided [`FormatConfig`].
19+
//! for a compilation database), using the provided [`EntryFormat`].
2020
2121
pub mod clang;
2222
pub mod command;
2323
pub mod interpreters;
2424

2525
use super::intercept::Execution;
26+
use crate::config::EntryFormat;
2627
use serde::{Deserialize, Serialize};
2728
use std::fmt::Debug;
2829

@@ -50,33 +51,14 @@ pub trait Interpreter: Send {
5051
fn recognize(&self, execution: &Execution) -> Option<Command>;
5152
}
5253

53-
/// Configuration for formatting output entries.
54-
///
55-
/// This struct can be extended to control how recognized commands are
56-
/// transformed into output entries (e.g., for a compilation database).
57-
#[derive(Debug)]
58-
pub struct FormatConfig {
59-
command_field_as_array: bool,
60-
keep_output_field: bool,
61-
}
62-
63-
impl Default for FormatConfig {
64-
fn default() -> Self {
65-
Self {
66-
command_field_as_array: true,
67-
keep_output_field: true,
68-
}
69-
}
70-
}
71-
7254
/// Trait for types that can be formatted into output entries.
7355
pub trait Formattable {
7456
/// Converts the command into a list of entries, using the provided format configuration.
75-
fn to_entries(&self, config: &FormatConfig) -> Vec<clang::Entry>;
57+
fn to_entries(&self, config: &EntryFormat) -> Vec<clang::Entry>;
7658
}
7759

7860
impl Formattable for Command {
79-
fn to_entries(&self, config: &FormatConfig) -> Vec<clang::Entry> {
61+
fn to_entries(&self, config: &EntryFormat) -> Vec<clang::Entry> {
8062
match self {
8163
Command::Compiler(cmd) => cmd.to_entries(config),
8264
Command::Ignored(_) => vec![],

0 commit comments

Comments
 (0)