Skip to content

Commit 876a8b3

Browse files
committed
[rust] Include mixed output (INFO, WARN, DEBUG, etc. to stderr and minimal JSON to stdout)
1 parent 4b6af2e commit 876a8b3

File tree

4 files changed

+79
-20
lines changed

4 files changed

+79
-20
lines changed

rust/src/logger.rs

+51-15
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use crate::config::BooleanKey;
1919
use crate::metadata::now_unix_timestamp;
2020
use env_logger::fmt::Color;
21-
use env_logger::Target::Stdout;
21+
use env_logger::Target::{Stderr, Stdout};
2222
use env_logger::DEFAULT_FILTER_ENV;
2323
use log::Level;
2424
use log::LevelFilter::{Debug, Info, Trace};
@@ -27,7 +27,6 @@ use std::cell::RefCell;
2727
use std::env;
2828
use std::fmt::Display;
2929
use std::io::Write;
30-
use std::ops::Deref;
3130
use Color::{Blue, Cyan, Green, Red, Yellow};
3231

3332
pub const DRIVER_PATH: &str = "Driver path: ";
@@ -39,6 +38,7 @@ enum OutputType {
3938
Logger,
4039
Json,
4140
Shell,
41+
Mixed,
4242
}
4343

4444
#[derive(Default)]
@@ -47,6 +47,7 @@ pub struct Logger {
4747
trace: bool,
4848
output: OutputType,
4949
json: RefCell<JsonOutput>,
50+
minimal_json: RefCell<MinimalJson>,
5051
}
5152

5253
#[derive(Default, Serialize, Deserialize)]
@@ -70,6 +71,12 @@ pub struct JsonOutput {
7071
pub result: Result,
7172
}
7273

74+
#[derive(Default, Serialize, Deserialize)]
75+
pub struct MinimalJson {
76+
pub driver_path: String,
77+
pub browser_path: String,
78+
}
79+
7380
impl Logger {
7481
pub fn new() -> Self {
7582
let debug = BooleanKey("debug", false).get_value();
@@ -83,11 +90,13 @@ impl Logger {
8390
output_type = OutputType::Json;
8491
} else if output.eq_ignore_ascii_case("shell") {
8592
output_type = OutputType::Shell;
93+
} else if output.eq_ignore_ascii_case("mixed") {
94+
output_type = OutputType::Mixed;
8695
} else {
8796
output_type = OutputType::Logger;
8897
}
8998
match output_type {
90-
OutputType::Logger => {
99+
OutputType::Logger | OutputType::Mixed => {
91100
if env::var(DEFAULT_FILTER_ENV).unwrap_or_default().is_empty() {
92101
let mut filter = match debug {
93102
true => Debug,
@@ -96,9 +105,14 @@ impl Logger {
96105
if trace {
97106
filter = Trace
98107
}
108+
let target = if output_type == OutputType::Logger {
109+
Stdout
110+
} else {
111+
Stderr
112+
};
99113
env_logger::Builder::new()
100114
.filter_module(env!("CARGO_CRATE_NAME"), filter)
101-
.target(Stdout)
115+
.target(target)
102116
.format(|buf, record| {
103117
let mut level_style = buf.style();
104118
match record.level() {
@@ -141,6 +155,7 @@ impl Logger {
141155
browser_path: "".to_string(),
142156
},
143157
}),
158+
minimal_json: RefCell::new(Default::default()),
144159
}
145160
}
146161

@@ -178,12 +193,11 @@ impl Logger {
178193
}
179194
if level == Level::Info || level <= Level::Error {
180195
if message.starts_with(DRIVER_PATH) {
181-
let driver_path = message.replace(DRIVER_PATH, "");
182-
self.json.borrow_mut().result.driver_path = driver_path.to_owned();
183-
self.json.borrow_mut().result.message = driver_path;
196+
self.json.borrow_mut().result.driver_path =
197+
self.clean_driver_path(&message);
184198
} else if message.starts_with(BROWSER_PATH) {
185-
let browser_path = message.replace(BROWSER_PATH, "");
186-
self.json.borrow_mut().result.browser_path = browser_path;
199+
self.json.borrow_mut().result.browser_path =
200+
self.clean_browser_path(&message);
187201
} else {
188202
self.json.borrow_mut().result.message = message;
189203
}
@@ -197,11 +211,28 @@ impl Logger {
197211
}
198212
}
199213
_ => {
214+
if self.output == OutputType::Mixed && level == Level::Info {
215+
if message.starts_with(DRIVER_PATH) {
216+
self.minimal_json.borrow_mut().driver_path =
217+
self.clean_driver_path(&message);
218+
} else if message.starts_with(BROWSER_PATH) {
219+
self.minimal_json.borrow_mut().browser_path =
220+
self.clean_browser_path(&message);
221+
}
222+
}
200223
log::log!(level, "{}", message);
201224
}
202225
}
203226
}
204227

228+
fn clean_driver_path(&self, message: &str) -> String {
229+
message.replace(DRIVER_PATH, "")
230+
}
231+
232+
fn clean_browser_path(&self, message: &str) -> String {
233+
message.replace(BROWSER_PATH, "")
234+
}
235+
205236
fn create_json_log(&self, message: String, level: Level) -> Logs {
206237
Logs {
207238
level: level.to_string().to_uppercase(),
@@ -210,17 +241,22 @@ impl Logger {
210241
}
211242
}
212243

244+
fn get_json_blog<T>(&self, json_output: &T) -> String
245+
where
246+
T: Serialize,
247+
{
248+
serde_json::to_string_pretty(json_output).unwrap()
249+
}
250+
213251
pub fn set_code(&self, code: i32) {
214252
self.json.borrow_mut().result.code = code;
215253
}
216254

217255
pub fn flush(&self) {
218-
let json_output = &self.json.borrow();
219-
let json = json_output.deref();
220-
if !json.logs.is_empty() {
221-
print!("{}", serde_json::to_string_pretty(json).unwrap());
222-
} else if self.output == OutputType::Json {
223-
panic!("JSON output has been specified, but no entries have been collected")
256+
if self.output == OutputType::Json {
257+
println!("{}", self.get_json_blog(&self.json));
258+
} else if self.output == OutputType::Mixed {
259+
println!("{}", self.get_json_blog(&self.minimal_json));
224260
}
225261
}
226262
}

rust/src/main.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ struct Cli {
7777
#[clap(long, value_parser)]
7878
browser_mirror_url: Option<String>,
7979

80-
/// Output type: LOGGER (using INFO, WARN, etc.), JSON (custom JSON notation), or SHELL (Unix-like)
80+
/// Output type: LOGGER (using INFO, WARN, etc.), JSON (custom JSON notation), SHELL (Unix-like),
81+
/// or MIXED (INFO, WARN, DEBUG, etc. to stderr and minimal JSON to stdout)
8182
#[clap(long, value_parser, default_value = "LOGGER")]
8283
output: String,
8384

rust/tests/grid_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn grid_latest_test() {
4343
let output_code = json.result.code;
4444
assert_eq!(output_code, 0);
4545

46-
let jar = Path::new(&json.result.message);
46+
let jar = Path::new(&json.result.driver_path);
4747
assert!(jar.exists());
4848

4949
let jar_name = jar.file_name().unwrap().to_str().unwrap();
@@ -66,7 +66,7 @@ fn grid_version_test(#[case] grid_version: &str) {
6666
println!("{}", output);
6767

6868
let json: JsonOutput = serde_json::from_str(output).unwrap();
69-
let jar = Path::new(&json.result.message);
69+
let jar = Path::new(&json.result.driver_path);
7070
let jar_name = jar.file_name().unwrap().to_str().unwrap();
7171
assert!(jar_name.contains(grid_version));
7272
}

rust/tests/output_tests.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// under the License.
1717

1818
use assert_cmd::Command;
19-
use selenium_manager::logger::{JsonOutput, DRIVER_PATH};
19+
use selenium_manager::logger::{JsonOutput, MinimalJson, DRIVER_PATH};
2020
use std::path::Path;
2121
use std::str;
2222

@@ -38,7 +38,7 @@ fn json_output_test() {
3838
let output_code = json.result.code;
3939
assert_eq!(output_code, 0);
4040

41-
let driver = Path::new(&json.result.message);
41+
let driver = Path::new(&json.result.driver_path);
4242
assert!(driver.exists());
4343
}
4444

@@ -55,3 +55,25 @@ fn shell_output_test() {
5555
println!("{}", output);
5656
assert!(output.contains(DRIVER_PATH));
5757
}
58+
59+
#[test]
60+
fn mixed_output_test() {
61+
let mut cmd = Command::new(env!("CARGO_BIN_EXE_selenium-manager"));
62+
cmd.args(["--browser", "chrome", "--output", "mixed"])
63+
.assert()
64+
.success()
65+
.code(0);
66+
67+
let stdout = &cmd.unwrap().stdout;
68+
let output = str::from_utf8(stdout).unwrap();
69+
println!("stdout: {}", output);
70+
71+
let json: MinimalJson = serde_json::from_str(output).unwrap();
72+
let driver = Path::new(&json.driver_path);
73+
assert!(driver.exists());
74+
75+
let stderr = &cmd.unwrap().stderr;
76+
let err_output = str::from_utf8(stderr).unwrap();
77+
println!("stderr: {}", err_output);
78+
assert!(!err_output.is_empty());
79+
}

0 commit comments

Comments
 (0)