From 92560675b90be9d8131e610fc314927f4e075de6 Mon Sep 17 00:00:00 2001 From: Laszlo Nagy Date: Fri, 26 Apr 2024 21:44:00 +1000 Subject: [PATCH] fixme --- rust/intercept/Cargo.toml | 2 +- rust/intercept/src/bin/intercept.rs | 115 ++++++++++++++++++++++++++++ rust/intercept/src/collector.rs | 6 +- rust/intercept/src/ipc.rs | 4 +- rust/intercept/src/main.rs | 28 ------- 5 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 rust/intercept/src/bin/intercept.rs delete mode 100644 rust/intercept/src/main.rs diff --git a/rust/intercept/Cargo.toml b/rust/intercept/Cargo.toml index 663922b7..ee07c022 100644 --- a/rust/intercept/Cargo.toml +++ b/rust/intercept/Cargo.toml @@ -28,7 +28,7 @@ path = "src/lib.rs" [[bin]] name = "intercept" -path = "src/main.rs" +path = "src/bin/intercept.rs" [[bin]] name = "wrapper" diff --git a/rust/intercept/src/bin/intercept.rs b/rust/intercept/src/bin/intercept.rs new file mode 100644 index 00000000..994f3769 --- /dev/null +++ b/rust/intercept/src/bin/intercept.rs @@ -0,0 +1,115 @@ +/* Copyright (C) 2012-2023 by László Nagy + This file is part of Bear. + + Bear is a tool to generate compilation database for clang tooling. + + Bear is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bear is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +extern crate core; + +use std::io::Write; + +use anyhow::Result; +use clap::{arg, ArgAction, command}; +use crossbeam_channel::bounded; + +use intercept::ipc::{Envelope, Event, ReporterId}; +use intercept::collector::{EventCollector, EventCollectorOnTcp}; + +#[derive(Debug, PartialEq)] +struct Arguments { + command: Vec, + output: String, + config: Option, + verbose: u8, +} + +impl Arguments { + fn parse() -> Result { + let matches = command!() + .args(&[ + arg!( "Build command") + .action(ArgAction::Append) + .value_terminator("--") + .multiple_values(true) + .last(true) + .required(true), + arg!(-o --output "Path of the result file") + .default_value("events.json") + .hide_default_value(false), + arg!(-c --config "Path of the config file"), + arg!(-v --verbose ... "Sets the level of verbosity") + .action(ArgAction::Count), + ]) + .get_matches(); + + Arguments { + command: matches.get_values_of("COMMAND") + .expect("command is required") + .map(String::to_string) + .collect(), + output: matches.get_one::("output") + .expect("output is defaulted") + .clone(), + config: matches.get_one::("config") + .map(String::to_string), + verbose: matches.get_count("verbose"), + } + } +} + +fn run() -> Result { + let arguments = Arguments::parse()?; + + let collector = EventCollectorOnTcp::new()?; + let destination = collector.address()?; + + std::env::set_var("INTERCEPT_REPORT_DESTINATION", &destination.0); + std::env::set_var("INTERCEPT_VERBOSE", arguments.verbose.to_string()); + let mut build = std::process::Command::new(arguments.command[0].clone()) + .args(&arguments.command[1..]) + .envs(std::env::vars()) + .spawn()?; + + let (sender, mut receiver) = bounded::(10); + let collector_loop = std::thread::spawn(move || { + collector.collect(sender) + }); + let writer_loop = std::thread::spawn(move || { + let mut writer = std::fs::File::create(arguments.output)?; + loop { + let envelope = receiver.recv()?; + let _ = envelope.write_into(&mut writer)?; + writer.flush()?; + } + }); + + let build_status = build.wait()?; + collector.stop()?; + + collector_loop.join().unwrap()?; + writer_loop.join().unwrap()?; + + Ok(build_status.code().unwrap()) +} + +fn main() { + let exit_code = run().unwrap_or_else(|error| { + eprintln!("Error: {}", error); + 1 + }); + + std::process::exit(exit_code); +} diff --git a/rust/intercept/src/collector.rs b/rust/intercept/src/collector.rs index c91911f5..724f9adb 100644 --- a/rust/intercept/src/collector.rs +++ b/rust/intercept/src/collector.rs @@ -24,13 +24,13 @@ use crossbeam_channel::bounded; use super::ipc::{Envelope, SessionLocator}; -trait EventCollector { +pub trait EventCollector { fn address(&self) -> Result; fn collect(&self, destination: Sender) -> Result<(), anyhow::Error>; fn stop(&self) -> Result<(), anyhow::Error>; } -struct EventCollectorOnTcp { +pub struct EventCollectorOnTcp { control_input: Sender, control_output: Receiver, listener: TcpListener, @@ -46,7 +46,7 @@ impl EventCollectorOnTcp { Ok(result) } - pub fn send( + fn send( &self, mut socket: TcpStream, destination: Sender, diff --git a/rust/intercept/src/ipc.rs b/rust/intercept/src/ipc.rs index 5dddb1d4..e99e4286 100644 --- a/rust/intercept/src/ipc.rs +++ b/rust/intercept/src/ipc.rs @@ -92,7 +92,7 @@ impl Envelope { Ok(envelope) } - pub fn write_into(&self, mut writer: impl Write) -> Result<(), anyhow::Error> { + pub fn write_into(&self, mut writer: impl Write) -> Result { let serialized_envelope = serde_json::to_string(&self)?; let bytes = serialized_envelope.into_bytes(); let length = bytes.len() as u32; @@ -100,6 +100,6 @@ impl Envelope { writer.write_all(&length.to_be_bytes())?; writer.write_all(&bytes)?; - Ok(()) + Ok(length) } } diff --git a/rust/intercept/src/main.rs b/rust/intercept/src/main.rs deleted file mode 100644 index be4a342f..00000000 --- a/rust/intercept/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2012-2023 by László Nagy - This file is part of Bear. - - Bear is a tool to generate compilation database for clang tooling. - - Bear is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bear is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -extern crate core; - -use anyhow::Result; - -use intercept::ipc::{Envelope, Event, ReporterId}; - -fn main() -> Result<()> { - Ok(()) -}