Skip to content

Commit 122d48a

Browse files
committed
rust: configuration for path formatting
1 parent 48dee7f commit 122d48a

File tree

6 files changed

+96
-282
lines changed

6 files changed

+96
-282
lines changed

rust/bear/src/config.rs

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@
6666
//! - file
6767
//! - directory
6868
//! format:
69-
//! command_as_array: true
70-
//! drop_output_field: false
71-
//! paths_as: canonical
69+
//! paths:
70+
//! resolver: original
71+
//! relative: false
7272
//! ```
7373
//!
7474
//! ```yaml
@@ -104,6 +104,16 @@ pub struct Main {
104104
pub output: Output,
105105
}
106106

107+
impl Default for Main {
108+
fn default() -> Self {
109+
Main {
110+
schema: String::from(SUPPORTED_SCHEMA_VERSION),
111+
intercept: Intercept::default(),
112+
output: Output::default(),
113+
}
114+
}
115+
}
116+
107117
impl Main {
108118
/// Loads the configuration from the specified file or the default locations.
109119
///
@@ -184,16 +194,6 @@ impl Main {
184194
}
185195
}
186196

187-
impl Default for Main {
188-
fn default() -> Self {
189-
Main {
190-
schema: String::from(SUPPORTED_SCHEMA_VERSION),
191-
intercept: Intercept::default(),
192-
output: Output::default(),
193-
}
194-
}
195-
}
196-
197197
/// Intercept configuration is either a wrapper or a preload mode.
198198
///
199199
/// In wrapper mode, the compiler is wrapped with a script that intercepts the compiler calls.
@@ -413,52 +413,45 @@ pub enum OutputFields {
413413
}
414414

415415
/// Format configuration of the JSON compilation database.
416-
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
416+
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
417417
pub struct Format {
418-
#[serde(default = "default_enabled")]
419-
pub command_as_array: bool,
420-
#[serde(default = "default_disabled")]
421-
pub drop_output_field: bool,
422-
#[serde(default)]
423-
pub paths_as: PathFormat,
418+
pub paths: PathFormat,
424419
}
425420

426-
impl Default for Format {
427-
fn default() -> Self {
428-
Format {
429-
command_as_array: true,
430-
drop_output_field: false,
431-
paths_as: PathFormat::default(),
432-
}
433-
}
421+
/// Format configuration of paths in the JSON compilation database.
422+
#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
423+
pub struct PathFormat {
424+
#[serde(default)]
425+
pub resolver: PathResolver,
426+
#[serde(default = "default_disabled")]
427+
pub relative: bool,
434428
}
435429

436-
/// Path format configuration describes how the paths should be formatted.
430+
/// Path resolver configuration.
437431
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
438-
pub enum PathFormat {
432+
pub enum PathResolver {
433+
/// The original path is the path as it is passed to the compiler.
439434
#[serde(rename = "original", alias = "is")]
440435
Original,
436+
/// The absolute path from the original path. Symlinks are not resolved.
441437
#[serde(rename = "absolute")]
442438
Absolute,
439+
/// The canonical path is the absolute path with the symlinks resolved.
443440
#[serde(rename = "canonical")]
444441
Canonical,
445442
}
446443

447444
/// The default path format is the original path.
448-
impl Default for PathFormat {
445+
impl Default for PathResolver {
449446
fn default() -> Self {
450-
PathFormat::Original
447+
PathResolver::Original
451448
}
452449
}
453450

454451
fn default_disabled() -> bool {
455452
false
456453
}
457454

458-
fn default_enabled() -> bool {
459-
true
460-
}
461-
462455
/// The default directory where the wrapper executables will be stored.
463456
fn default_wrapper_directory() -> PathBuf {
464457
std::env::temp_dir()
@@ -544,9 +537,9 @@ mod test {
544537
- file
545538
- directory
546539
format:
547-
command_as_array: true
548-
drop_output_field: false
549-
paths_as: canonical
540+
paths:
541+
resolver: canonical
542+
relative: false
550543
"#;
551544

552545
let result = Main::from_reader(content).unwrap();
@@ -617,9 +610,10 @@ mod test {
617610
by_fields: vec![OutputFields::File, OutputFields::Directory],
618611
},
619612
format: Format {
620-
command_as_array: true,
621-
drop_output_field: false,
622-
paths_as: PathFormat::Canonical,
613+
paths: PathFormat {
614+
resolver: PathResolver::Canonical,
615+
relative: false,
616+
},
623617
},
624618
},
625619
schema: String::from("4.0"),
@@ -646,8 +640,6 @@ mod test {
646640
by_fields:
647641
- file
648642
- directory
649-
format:
650-
command_as_array: true
651643
"#;
652644

653645
let result = Main::from_reader(content).unwrap();
@@ -668,9 +660,10 @@ mod test {
668660
by_fields: vec![OutputFields::File, OutputFields::Directory],
669661
},
670662
format: Format {
671-
command_as_array: true,
672-
drop_output_field: false,
673-
paths_as: PathFormat::Original,
663+
paths: PathFormat {
664+
resolver: PathResolver::Original,
665+
relative: false,
666+
},
674667
},
675668
},
676669
schema: String::from("4.0"),
@@ -726,9 +719,9 @@ mod test {
726719
by_fields:
727720
- file
728721
format:
729-
command_as_array: true
730-
drop_output_field: true
731-
use_absolute_path: false
722+
paths:
723+
resolver: canonical
724+
relative: true
732725
"#;
733726

734727
let result = Main::from_reader(content).unwrap();
@@ -768,9 +761,10 @@ mod test {
768761
by_fields: vec![OutputFields::File],
769762
},
770763
format: Format {
771-
command_as_array: true,
772-
drop_output_field: true,
773-
paths_as: PathFormat::Original,
764+
paths: PathFormat {
765+
resolver: PathResolver::Canonical,
766+
relative: true,
767+
},
774768
},
775769
},
776770
schema: String::from("4.0"),

rust/bear/src/modes/semantic.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,16 @@ impl OutputWriterImpl {
8181
// TODO: This method should fail early if the output file is not writable.
8282
match config {
8383
config::Output::Clang {
84-
format,
8584
sources,
8685
duplicates,
8786
..
8887
} => {
8988
let result = ClangOutputWriter {
9089
output: PathBuf::from(&args.file_name),
9190
append: args.append,
91+
formatter: output::formatter::EntryFormatter::new(),
9292
source_filter: sources.clone(),
9393
duplicate_filter: duplicates.clone(),
94-
command_as_array: format.command_as_array,
95-
formatter: From::from(format),
9694
};
9795
Ok(OutputWriterImpl::Clang(result))
9896
}
@@ -133,19 +131,15 @@ impl OutputWriter for SemanticOutputWriter {
133131
pub(crate) struct ClangOutputWriter {
134132
output: PathBuf,
135133
append: bool,
134+
formatter: output::formatter::EntryFormatter,
136135
source_filter: config::SourceFilter,
137136
duplicate_filter: config::DuplicateFilter,
138-
command_as_array: bool,
139-
formatter: output::formatter::EntryFormatter,
140137
}
141138

142139
impl OutputWriter for ClangOutputWriter {
143140
/// Implements the main logic of the output writer.
144-
fn run(
145-
&self,
146-
compiler_calls: impl Iterator<Item = semantic::CompilerCall>,
147-
) -> anyhow::Result<()> {
148-
let entries = compiler_calls.flat_map(|compiler_call| self.formatter.apply(compiler_call));
141+
fn run(&self, semantics: impl Iterator<Item = semantic::CompilerCall>) -> anyhow::Result<()> {
142+
let entries = semantics.flat_map(|semantic| self.formatter.apply(semantic));
149143
if self.append && self.output.exists() {
150144
let entries_from_db = Self::read_from_compilation_db(self.output.as_path())?;
151145
let final_entries = entries.chain(entries_from_db);
@@ -200,7 +194,7 @@ impl ClangOutputWriter {
200194
.map(BufWriter::new)
201195
.with_context(|| format!("Failed to create file: {:?}", file_name.as_path()))?;
202196
// Write the entries to the file.
203-
output::clang::write(self.command_as_array, file, entries)
197+
output::clang::write(file, entries)
204198
.with_context(|| format!("Failed to write entries: {:?}", file_name.as_path()))?;
205199
// Return the temporary file name.
206200
Ok(file_name)

rust/bear/src/output/clang/mod.rs

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use serde_json::Error;
1818
mod iterator;
1919
mod tests;
2020
mod type_de;
21-
mod type_ser;
2221

2322
/// Represents an entry of the compilation database.
2423
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
@@ -46,46 +45,16 @@ pub fn read(reader: impl std::io::Read) -> impl Iterator<Item = Result<Entry, Er
4645
iterator::iter_json_array(reader)
4746
}
4847

49-
/// The entries are written in the format specified by the configuration.
50-
pub fn write(
51-
command_as_array: bool,
52-
writer: impl std::io::Write,
53-
entries: impl Iterator<Item = Entry>,
54-
) -> Result<(), Error> {
55-
let method = if command_as_array {
56-
write_with_arguments
57-
} else {
58-
write_with_command
59-
};
60-
method(writer, entries)
61-
}
62-
6348
/// Serialize entries from an iterator into a JSON array.
6449
///
6550
/// It uses the `arguments` field of the `Entry` struct to serialize the array of strings.
66-
pub(super) fn write_with_arguments(
67-
writer: impl std::io::Write,
68-
entries: impl Iterator<Item = Entry>,
69-
) -> Result<(), Error> {
70-
let mut ser = serde_json::Serializer::pretty(writer);
71-
let mut seq = ser.serialize_seq(None)?;
72-
for entry in entries {
73-
seq.serialize_element(&entry)?;
74-
}
75-
seq.end()
76-
}
77-
78-
/// Serialize entries from an iterator into a JSON array.
79-
///
80-
/// It uses the `arguments` field of the `Entry` struct to serialize the array of strings.
81-
pub(super) fn write_with_command(
51+
pub fn write(
8252
writer: impl std::io::Write,
8353
entries: impl Iterator<Item = Entry>,
8454
) -> Result<(), Error> {
8555
let mut ser = serde_json::Serializer::pretty(writer);
8656
let mut seq = ser.serialize_seq(None)?;
8757
for entry in entries {
88-
let entry = type_ser::EntryWithCommand::from(entry);
8958
seq.serialize_element(&entry)?;
9059
}
9160
seq.end()

rust/bear/src/output/clang/tests.rs

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ mod success {
165165

166166
// Create fake "file"
167167
let mut buffer = Cursor::new(Vec::new());
168-
let result = write_with_arguments(&mut buffer, input.into_iter());
168+
let result = write(&mut buffer, input.into_iter());
169169
assert!(result.is_ok());
170170

171171
// Use the fake "file" as input
@@ -176,24 +176,6 @@ mod success {
176176

177177
Ok(())
178178
}
179-
180-
#[test]
181-
fn save_with_string_command_syntax() -> Result<(), Error> {
182-
let input = expected_values();
183-
184-
// Create fake "file"
185-
let mut buffer = Cursor::new(Vec::new());
186-
let result = write_with_command(&mut buffer, input.into_iter());
187-
assert!(result.is_ok());
188-
189-
// Use the fake "file" as input
190-
buffer.seek(SeekFrom::Start(0)).unwrap();
191-
let content: serde_json::Value = serde_json::from_reader(&mut buffer)?;
192-
193-
assert_eq!(expected_with_string_syntax(), content);
194-
195-
Ok(())
196-
}
197179
}
198180

199181
mod quoted {
@@ -276,37 +258,29 @@ mod success {
276258
}
277259

278260
#[test]
279-
fn save_with_array_command_syntax() -> Result<(), Error> {
280-
let input = expected_values();
281-
282-
// Create fake "file"
283-
let mut buffer = Cursor::new(Vec::new());
284-
let result = write_with_arguments(&mut buffer, input.into_iter());
285-
assert!(result.is_ok());
286-
287-
// Use the fake "file" as input
288-
buffer.seek(SeekFrom::Start(0)).unwrap();
289-
let content: Value = serde_json::from_reader(&mut buffer)?;
261+
fn load_content_with_string_command_syntax() {
262+
let content = expected_with_string_syntax().to_string();
290263

291-
assert_eq!(expected_with_array_syntax(), content);
264+
let result = read(content.as_bytes());
265+
let entries: Vec<Entry> = result.map(|e| e.unwrap()).collect();
292266

293-
Ok(())
267+
assert_eq!(expected_values(), entries);
294268
}
295269

296270
#[test]
297-
fn save_with_string_command_syntax() -> Result<(), Error> {
271+
fn save_with_array_command_syntax() -> Result<(), Error> {
298272
let input = expected_values();
299273

300274
// Create fake "file"
301275
let mut buffer = Cursor::new(Vec::new());
302-
let result = write_with_command(&mut buffer, input.into_iter());
276+
let result = write(&mut buffer, input.into_iter());
303277
assert!(result.is_ok());
304278

305279
// Use the fake "file" as input
306280
buffer.seek(SeekFrom::Start(0)).unwrap();
307281
let content: Value = serde_json::from_reader(&mut buffer)?;
308282

309-
assert_eq!(expected_with_string_syntax(), content);
283+
assert_eq!(expected_with_array_syntax(), content);
310284

311285
Ok(())
312286
}

0 commit comments

Comments
 (0)