Skip to content

Commit 42f0d90

Browse files
committed
Guard non-interactive send CLI output
1 parent 3ff0481 commit 42f0d90

2 files changed

Lines changed: 31 additions & 4 deletions

File tree

src/bin/sendmer.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use sendmer::core::args::{
1414
use sendmer::core::cli_helper::CliEventEmitter;
1515
use sendmer::core::{receiver, sender};
1616
use sendmer::{AppHandle, ReceiveOptions, SendOptions};
17+
use std::io::IsTerminal;
1718
use std::sync::Arc;
1819

1920
#[tokio::main]
@@ -83,7 +84,7 @@ async fn send(args: SendArgs) -> anyhow::Result<()> {
8384
println!("to get this data, use");
8485
println!("sendmer receive {}", res.ticket);
8586
#[cfg(feature = "clipboard")]
86-
handle_key_press(args.clipboard, res.ticket.to_string());
87+
maybe_handle_key_press(args.clipboard, res.ticket.to_string());
8788
tokio::signal::ctrl_c().await?;
8889
res.shutdown().await
8990
}
@@ -157,6 +158,14 @@ fn maybe_show_secret(common: &CommonArgs) -> anyhow::Result<()> {
157158
Ok(())
158159
}
159160

161+
#[cfg(feature = "clipboard")]
162+
fn maybe_handle_key_press(set_clipboard: bool, ticket: String) {
163+
if !(std::io::stdin().is_terminal() && std::io::stdout().is_terminal()) {
164+
return;
165+
}
166+
handle_key_press(set_clipboard, ticket);
167+
}
168+
160169
#[cfg(feature = "clipboard")]
161170
fn handle_key_press(set_clipboard: bool, ticket: String) {
162171
#[cfg(any(unix, windows))]

tests/cli.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,30 +68,48 @@ impl RunningSend {
6868
.current_dir(cwd)
6969
.env_remove("RUST_LOG")
7070
.stdout(Stdio::piped())
71-
.stderr(Stdio::null())
71+
.stderr(Stdio::piped())
7272
.spawn()?;
7373
Ok(Self { child })
7474
}
7575

7676
fn read_ticket(&mut self) -> BlobTicket {
7777
let stdout = self.child.stdout.as_mut().expect("send stdout");
78-
for _ in 0..8 {
78+
let mut seen_output = String::new();
79+
for _ in 0..32 {
7980
let output = read_ascii_lines(1, stdout).expect("send output line");
81+
if output.is_empty() {
82+
let status = self.child.try_wait().expect("send status check");
83+
let stderr = self.read_stderr();
84+
panic!(
85+
"send exited before printing a valid ticket; status={status:?}, stdout={seen_output:?}, stderr={stderr:?}"
86+
);
87+
}
8088
let output = String::from_utf8(output).expect("utf-8 send output");
89+
seen_output.push_str(&output);
8190
if let Some(ticket) = output
8291
.split_ascii_whitespace()
8392
.find_map(|token| BlobTicket::from_str(token).ok())
8493
{
8594
return ticket;
8695
}
8796
}
88-
panic!("valid ticket not found in send output");
97+
let stderr = self.read_stderr();
98+
panic!("valid ticket not found in send output; stdout={seen_output:?}, stderr={stderr:?}");
8999
}
90100

91101
fn cleanup(&mut self) {
92102
let _ = self.child.kill();
93103
let _ = self.child.wait();
94104
}
105+
106+
fn read_stderr(&mut self) -> String {
107+
let mut stderr = String::new();
108+
if let Some(mut pipe) = self.child.stderr.take() {
109+
let _ = pipe.read_to_string(&mut stderr);
110+
}
111+
stderr
112+
}
95113
}
96114

97115
impl Drop for RunningSend {

0 commit comments

Comments
 (0)