Skip to content

Commit dbaeb78

Browse files
committed
also write the events data to a temp file
1 parent 84aa26b commit dbaeb78

File tree

4 files changed

+42
-59
lines changed

4 files changed

+42
-59
lines changed

crates/volta-core/src/event.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
77

88
use crate::error::{ExitCode, VoltaError};
99
use crate::hook::Publish;
10-
use crate::monitor::Monitor;
10+
use crate::monitor::send_events;
1111
use crate::session::ActivityKind;
1212

1313
// the Event data that is serialized to JSON and sent the plugin
@@ -135,8 +135,7 @@ impl EventLog {
135135
// Note: This call to unimplemented is left in, as it's not a Fallible operation that can use ErrorKind::Unimplemented
136136
Some(&Publish::Url(_)) => unimplemented!(),
137137
Some(&Publish::Bin(ref command)) => {
138-
let mut monitor = Monitor::new(command);
139-
monitor.send_events(&self.events);
138+
send_events(command, &self.events);
140139
}
141140
None => {}
142141
}

crates/volta-core/src/monitor.rs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,42 @@
11
use std::io::Write;
2+
use std::path::PathBuf;
23
use std::process::{Child, Stdio};
34

45
use log::debug;
6+
use tempfile::NamedTempFile;
57

68
use crate::command::create_command;
79
use crate::event::Event;
810

9-
pub struct Monitor {
10-
monitor_process: Option<Child>,
11-
}
12-
13-
impl Monitor {
14-
/// Returns the current monitor.
15-
pub fn new(command: &str) -> Monitor {
16-
Monitor {
17-
monitor_process: spawn_process(command),
18-
}
19-
}
20-
21-
/// send event to the monitor process
22-
// if hook command is not configured, this is a no-op
23-
pub fn send_events(&mut self, events: &[Event]) {
24-
if let Some(ref mut child_process) = self.monitor_process {
25-
if let Some(ref mut p_stdin) = child_process.stdin.as_mut() {
26-
let json = serde_json::to_string(&events);
27-
28-
match json {
29-
Ok(data) => {
30-
// FIXME: tighten up this error message
31-
writeln!(p_stdin, "{}", data).expect("Writing data to plugin failed!");
32-
}
33-
Err(error) => {
34-
// FIXME: tighten up this error message
35-
debug!("There was a problem serializing the JSON data: {:?}", error);
36-
}
37-
};
38-
}
11+
/// send event to the spawned command process
12+
// if hook command is not configured, this is not called
13+
pub fn send_events(command: &str, events: &[Event]) {
14+
// TODO: make these expects into errors or whatever
15+
let events_json =
16+
serde_json::to_string_pretty(&events).expect("Problem serializing events JSON data");
17+
let mut events_file = NamedTempFile::new().expect("Could not create temp file for events");
18+
events_file
19+
.write_all(events_json.as_bytes())
20+
.expect("Writing data to file failed");
21+
// don't automatically delete this temp file please
22+
let path = events_file.into_temp_path();
23+
let tempfile_path = path.keep().expect("Could not persist temp file");
24+
25+
// spawn a child process, with the path to that temp file as an env var
26+
if let Some(ref mut child_process) = spawn_process(command, tempfile_path) {
27+
if let Some(ref mut p_stdin) = child_process.stdin.as_mut() {
28+
// still send the data over stdin
29+
writeln!(p_stdin, "{}", events_json).expect("Writing data to plugin failed!");
3930
}
4031
}
4132
}
4233

43-
fn spawn_process(command: &str) -> Option<Child> {
34+
fn spawn_process(command: &str, tempfile_path: PathBuf) -> Option<Child> {
4435
command.split(' ').take(1).next().and_then(|executable| {
4536
let mut child = create_command(executable);
4637
child.args(command.split(' ').skip(1));
4738
child.stdin(Stdio::piped());
39+
child.env("EVENTS_FILE", tempfile_path);
4840

4941
#[cfg(not(debug_assertions))]
5042
// Hide stdout and stderr of spawned process in release mode

tests/acceptance/hooks.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@ const PROJECT_PACKAGE_JSON: &str = r#"
2323
}
2424
}"#;
2525

26-
// scripts that read stdin, and write it to file 'events.json'
26+
// scripts that write events to file 'events.json'
2727
cfg_if::cfg_if! {
2828
if #[cfg(windows)] {
29+
// have not been able to read events from stdin with batch, powershell, etc.
30+
// so just copy the tempfile (path in EVENTS_FILE env var) to events.json
2931
const EVENTS_EXECUTABLE: &str = r#"@echo off
30-
setlocal
31-
break >events.json
32-
for /F "tokens=*" %%line in ('more') do (
33-
echo %%line >>events.json
34-
)"#;
32+
copy %%EVENTS_FILE%% events.json
33+
"#;
3534
const SCRIPT_FILENAME: &str = "write-events.bat";
3635
} else if #[cfg(unix)] {
36+
// read events from stdin
3737
const EVENTS_EXECUTABLE: &str = r#"#!/bin/bash
3838
# read Volta events from stdin, and write to events.json
3939
# (but first clear it out)
@@ -144,7 +144,7 @@ fn redirects_download() {
144144
.with_stderr_contains("[..]/hook/default/node/1.2.3")
145145
);
146146

147-
thread::sleep(time::Duration::from_millis(5000));
147+
thread::sleep(time::Duration::from_millis(500));
148148
assert_events(
149149
&s,
150150
vec![
@@ -174,7 +174,7 @@ fn merges_project_and_default_hooks() {
174174
.with_stderr_contains("[..]Could not download [email protected]")
175175
.with_stderr_contains("[..]/hook/project/yarn/3.2.1")
176176
);
177-
thread::sleep(time::Duration::from_millis(5000));
177+
thread::sleep(time::Duration::from_millis(500));
178178
assert_events(
179179
&s,
180180
vec![
@@ -193,7 +193,7 @@ fn merges_project_and_default_hooks() {
193193
.with_stderr_contains("[..]Could not download [email protected]")
194194
.with_stderr_contains("[..]/hook/default/node/10.12.1")
195195
);
196-
thread::sleep(time::Duration::from_millis(5000));
196+
thread::sleep(time::Duration::from_millis(500));
197197
assert_events(
198198
&s,
199199
vec![
@@ -230,7 +230,7 @@ fn merges_workspace_hooks() {
230230
.with_stderr_contains("[..]Could not download [email protected]")
231231
.with_stderr_contains("[..]/hook/project/yarn/3.1.4")
232232
);
233-
thread::sleep(time::Duration::from_millis(5000));
233+
thread::sleep(time::Duration::from_millis(500));
234234
assert_events(
235235
&s,
236236
vec![
@@ -249,7 +249,7 @@ fn merges_workspace_hooks() {
249249
.with_stderr_contains("[..]Could not download [email protected]")
250250
.with_stderr_contains("[..]/hook/workspace/npm/5.6.7")
251251
);
252-
thread::sleep(time::Duration::from_millis(5000));
252+
thread::sleep(time::Duration::from_millis(500));
253253
assert_events(
254254
&s,
255255
vec![

tests/acceptance/merged_platform.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,17 @@ const PLATFORM_WITH_YARN: &str = r#"{
5353
"yarn": "1.7.71"
5454
}"#;
5555

56-
// scripts that read stdin, and write it to file 'events.json'
5756
cfg_if::cfg_if! {
5857
if #[cfg(windows)] {
58+
// copy the tempfile (path in EVENTS_FILE env var) to events.json
5959
const EVENTS_EXECUTABLE: &str = r#"@echo off
60-
setlocal
61-
break >events.json
62-
for /F "tokens=*" %%line in ('more') do (
63-
echo %%line >>events.json
64-
)"#;
60+
copy %%EVENTS_FILE%% events.json
61+
"#;
6562
const SCRIPT_FILENAME: &str = "write-events.bat";
6663
} else if #[cfg(unix)] {
64+
// copy the tempfile (path in EVENTS_FILE env var) to events.json
6765
const EVENTS_EXECUTABLE: &str = r#"#!/bin/bash
68-
# read Volta events from stdin, and write to events.json
69-
# (but first clear it out)
70-
echo -n "" >events.json
71-
while read line
72-
do
73-
echo "$line" >>events.json
74-
done
66+
cp "$EVENTS_FILE" events.json
7567
"#;
7668
const SCRIPT_FILENAME: &str = "write-events.sh";
7769
} else {
@@ -259,7 +251,7 @@ fn uses_project_yarn_if_available() {
259251
.with_stderr_contains("[..]Yarn: 1.12.99 from project configuration")
260252
);
261253

262-
thread::sleep(time::Duration::from_millis(5000));
254+
thread::sleep(time::Duration::from_millis(500));
263255
assert_events(
264256
&s,
265257
vec![

0 commit comments

Comments
 (0)