11// SPDX-License-Identifier: GPL-3.0-or-later
22
33use super :: super :: semantic;
4- use crate :: ipc:: { Envelope , Execution } ;
54use crate :: modes:: Mode ;
5+ use crate :: output:: event:: read;
66use crate :: output:: { OutputWriter , OutputWriterImpl } ;
77use crate :: semantic:: transformation:: Transformation ;
88use crate :: semantic:: Transform ;
99use crate :: { args, config} ;
1010use anyhow:: Context ;
11- use serde_json:: de:: IoRead ;
12- use serde_json:: { Error , StreamDeserializer } ;
13- use std:: convert:: TryFrom ;
14- use std:: fs:: OpenOptions ;
11+ use std:: fs:: { File , OpenOptions } ;
1512use std:: io:: BufReader ;
16- use std:: path:: PathBuf ;
1713use std:: process:: ExitCode ;
1814
1915/// The semantic mode we are deduct the semantic meaning of the
2016/// executed commands from the build process.
2117pub struct Semantic {
22- event_source : EventFileReader ,
18+ event_source : BufReader < File > ,
2319 interpreter : Box < dyn semantic:: Interpreter > ,
2420 semantic_transform : Transformation ,
2521 output_writer : OutputWriterImpl ,
@@ -32,7 +28,7 @@ impl Semantic {
3228 output : args:: BuildSemantic ,
3329 config : config:: Main ,
3430 ) -> anyhow:: Result < Self > {
35- let event_source = EventFileReader :: try_from ( input) ?;
31+ let event_source = Self :: open ( input. file_name . as_str ( ) ) ?;
3632 let interpreter = Self :: interpreter ( & config) ?;
3733 let semantic_transform = Transformation :: from ( & config. output ) ;
3834 let output_writer = OutputWriterImpl :: create ( & output, & config. output ) ?;
@@ -45,6 +41,16 @@ impl Semantic {
4541 } )
4642 }
4743
44+ /// Open the event file for reading.
45+ fn open ( file_name : & str ) -> anyhow:: Result < BufReader < File > > {
46+ let file = OpenOptions :: new ( )
47+ . read ( true )
48+ . open ( file_name)
49+ . map ( BufReader :: new)
50+ . with_context ( || format ! ( "Failed to open file: {:?}" , file_name) ) ?;
51+ Ok ( file)
52+ }
53+
4854 /// Creates an interpreter to recognize the compiler calls.
4955 ///
5056 /// Using the configuration we can define which compilers to include and exclude.
@@ -83,9 +89,8 @@ impl Mode for Semantic {
8389 /// The exit code is based on the result of the output writer.
8490 fn run ( self ) -> anyhow:: Result < ExitCode > {
8591 // Set up the pipeline of compilation database entries.
86- let entries = self
87- . event_source
88- . generate ( )
92+ let entries = read ( self . event_source )
93+ . map ( |envelope| envelope. event . execution )
8994 . inspect ( |execution| log:: debug!( "execution: {}" , execution) )
9095 . flat_map ( |execution| self . interpreter . recognize ( & execution) )
9196 . inspect ( |semantic| log:: debug!( "semantic: {:?}" , semantic) )
@@ -98,46 +103,3 @@ impl Mode for Semantic {
98103 }
99104 }
100105}
101-
102- /// Responsible for reading the build events from the intercept mode.
103- ///
104- /// The file syntax is defined by the `events` module, and the parsing logic is implemented there.
105- /// Here we only handle the file opening and the error handling.
106- pub struct EventFileReader {
107- stream : Box < dyn Iterator < Item = Result < Envelope , Error > > > ,
108- }
109-
110- impl TryFrom < args:: BuildEvents > for EventFileReader {
111- type Error = anyhow:: Error ;
112-
113- /// Open the file and create a new instance of the event file reader.
114- ///
115- /// If the file cannot be opened, the error will be logged and escalated.
116- fn try_from ( value : args:: BuildEvents ) -> Result < Self , Self :: Error > {
117- let file_name = PathBuf :: from ( value. file_name ) ;
118- let file = OpenOptions :: new ( )
119- . read ( true )
120- . open ( file_name. as_path ( ) )
121- . map ( BufReader :: new)
122- . with_context ( || format ! ( "Failed to open input file: {:?}" , file_name) ) ?;
123- let stream = Box :: new ( StreamDeserializer :: new ( IoRead :: new ( file) ) ) ;
124-
125- Ok ( EventFileReader { stream } )
126- }
127- }
128-
129- impl EventFileReader {
130- /// Generate the build events from the file.
131- ///
132- /// Returns an iterator over the build events. Any error during the reading
133- /// of the file will be logged and the failed entries will be skipped.
134- pub fn generate ( self ) -> impl Iterator < Item = Execution > {
135- self . stream . filter_map ( |result| match result {
136- Ok ( value) => Some ( value. event . execution ) ,
137- Err ( error) => {
138- log:: error!( "Failed to read event: {:?}" , error) ;
139- None
140- }
141- } )
142- }
143- }
0 commit comments