diff --git a/Cargo.lock b/Cargo.lock index ea07819..2396871 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1203,7 +1203,7 @@ dependencies = [ [[package]] name = "ostiary" -version = "1.1.1" +version = "1.1.2" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index 748f607..8ddf249 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ostiary" -version = "1.1.1" +version = "1.1.2" edition = "2024" [dependencies] diff --git a/src/main.rs b/src/main.rs index 7e8bc4b..cf8885e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -170,44 +170,60 @@ async fn run_exec( /// Runs before ratatui starts. Prompts for endpoint URL and name on first launch. fn prompt_first_endpoint() -> Result<(String, String)> { - use std::io::Write; + use std::io::{BufRead, BufReader, Write}; - println!(); - println!(" ╔══════════════════════════════════╗"); - println!(" ║ Ostiary — первый запуск ║"); - println!(" ╚══════════════════════════════════╝"); - println!(); - println!(" Конфиг будет сохранён в:"); - println!(" {}", config::config_path().display()); - println!(); + // Open /dev/tty directly so input works even when launched via `curl | bash` + // (where stdin is the pipe carrying the script, not the keyboard). + let tty = std::fs::OpenOptions::new() + .read(true) + .write(true) + .open("/dev/tty") + .map_err(|e| anyhow::anyhow!( + "Не удалось открыть терминал ({e}). Запустите ostiary напрямую." + ))?; + let mut out = tty.try_clone()?; + let mut reader = BufReader::new(tty); + + writeln!(out)?; + writeln!(out, " ╔══════════════════════════════════╗")?; + writeln!(out, " ║ Ostiary — первый запуск ║")?; + writeln!(out, " ╚══════════════════════════════════╝")?; + writeln!(out)?; + writeln!(out, " Конфиг будет сохранён в:")?; + writeln!(out, " {}", config::config_path().display())?; + writeln!(out)?; let name = loop { - print!(" Название эндпоинта: "); - std::io::stdout().flush()?; + write!(out, " Название эндпоинта: ")?; + out.flush()?; let mut buf = String::new(); - std::io::stdin().read_line(&mut buf)?; + if reader.read_line(&mut buf)? == 0 { + anyhow::bail!("Неожиданный конец ввода."); + } let val = buf.trim().to_string(); if val.is_empty() { - println!(" Название не может быть пустым. Попробуйте ещё раз.\n"); + writeln!(out, " Название не может быть пустым. Попробуйте ещё раз.\n")?; continue; } break val; }; let url = loop { - print!(" URL эндпоинта: "); - std::io::stdout().flush()?; + write!(out, " URL эндпоинта: ")?; + out.flush()?; let mut buf = String::new(); - std::io::stdin().read_line(&mut buf)?; + if reader.read_line(&mut buf)? == 0 { + anyhow::bail!("Неожиданный конец ввода."); + } let val = buf.trim().to_string(); if val.is_empty() { - println!(" URL не может быть пустым. Попробуйте ещё раз.\n"); + writeln!(out, " URL не может быть пустым. Попробуйте ещё раз.\n")?; continue; } break val; }; - println!(); + writeln!(out)?; Ok((url, name)) }