fix(cli): dev command stderr text overflow on Windows, closes #3995 (#4000)

This commit is contained in:
Lucas Fernandes Nogueira 2022-04-29 09:28:13 -07:00 committed by GitHub
parent cf22f4ca5d
commit 094534d138
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 109 additions and 16 deletions

View File

@ -0,0 +1,6 @@
---
"cli.rs": patch
"cli.js": patch
---
Fixes text overflow on `tauri dev` on Windows.

View File

@ -3389,7 +3389,7 @@ dependencies = [
[[package]]
name = "tauri"
version = "1.0.0-rc.7"
version = "1.0.0-rc.8"
dependencies = [
"anyhow",
"attohttpc",
@ -3446,7 +3446,7 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "1.0.0-rc.6"
version = "1.0.0-rc.7"
dependencies = [
"anyhow",
"cargo_toml",

View File

@ -12,7 +12,7 @@ tauri-build = { path = "../../../core/tauri-build", features = ["isolation"] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { path = "../../../core/tauri", features = ["api-all", "cli", "http-multipart", "icon-ico", "icon-png", "isolation", "macos-private-api", "reqwest-client", "system-tray", "updater", "global-shortcut"] }
tauri = { path = "../../../core/tauri", features = ["api-all", "cli", "global-shortcut", "http-multipart", "icon-ico", "icon-png", "isolation", "macos-private-api", "reqwest-client", "system-tray", "updater"] }
tiny_http = "0.11"
[features]

View File

@ -2740,6 +2740,7 @@ dependencies = [
"ureq",
"url",
"valico",
"winapi 0.3.9",
"zeroize",
]

View File

@ -52,7 +52,6 @@ os_info = "3.2"
semver = "1.0"
regex = "1.5.5"
lazy_static = "1"
libc = "0.2"
terminal_size = "0.1"
unicode-width = "0.1"
tempfile = "3"
@ -67,10 +66,14 @@ ctrlc = "3.2"
[target."cfg(windows)".dependencies]
encode_unicode = "0.3"
winapi = { version = "0.3", features = ["handleapi", "processenv", "winbase", "wincon", "winnt"] }
[target."cfg(target_os = \"linux\")".build-dependencies]
heck = "0.4"
[target."cfg(unix)".dependencies]
libc = "0.2"
[build-dependencies]
tauri-utils = { version = "1.0.0-rc.0", features = [ "schema", "isolation" ], path = "../../core/tauri-utils" }
schemars = { version = "0.8", features = [ "url" ] }

View File

@ -23,7 +23,7 @@ use std::{
env::set_current_dir,
ffi::OsStr,
fs::FileType,
io::BufReader,
io::{BufReader, Write},
path::{Path, PathBuf},
process::{exit, Command},
sync::{
@ -320,7 +320,6 @@ fn lookup<F: FnMut(FileType, PathBuf)>(dir: &Path, mut f: F) {
default_gitignore.push(".gitignore");
if !default_gitignore.exists() {
if let Ok(mut file) = std::fs::File::create(default_gitignore.clone()) {
use std::io::Write;
let _ = file.write_all(TAURI_DEV_WATCHER_GITIGNORE);
}
}
@ -422,7 +421,7 @@ fn kill_before_dev_process() {
if !kill_children_script_path.exists() {
if let Ok(mut file) = std::fs::File::create(&kill_children_script_path) {
use std::{io::Write, os::unix::fs::PermissionsExt};
use std::os::unix::fs::PermissionsExt;
let _ = file.write_all(KILL_CHILDREN_SCRIPT);
let mut permissions = file.metadata().unwrap().permissions();
permissions.set_mode(0o770);
@ -448,9 +447,15 @@ fn start_app(
command
.env(
"CARGO_TERM_PROGRESS_WIDTH",
terminal_size::terminal_size()
.map(|(w, _)| w.0)
.unwrap_or(80)
terminal::stderr_width()
.map(|width| {
if cfg!(windows) {
std::cmp::min(60, width)
} else {
width
}
})
.unwrap_or(if cfg!(windows) { 60 } else { 80 })
.to_string(),
)
.env("CARGO_TERM_PROGRESS_WHEN", "always");
@ -506,19 +511,18 @@ fn start_app(
std::thread::spawn(move || {
let mut buf = Vec::new();
let mut lines = stderr_lines_.lock().unwrap();
let mut io_stderr = std::io::stderr();
loop {
buf.clear();
match tauri_utils::io::read_line(&mut stderr, &mut buf) {
Ok(s) if s == 0 => break,
_ => (),
}
let line = String::from_utf8_lossy(&buf).into_owned();
if line.ends_with('\r') {
eprint!("{}", line);
} else {
eprintln!("{}", line);
let _ = io_stderr.write_all(&buf);
if !buf.ends_with(&[b'\r']) {
let _ = io_stderr.write_all(b"\n");
}
lines.push(line);
lines.push(String::from_utf8_lossy(&buf).into_owned());
}
});
@ -554,3 +558,82 @@ fn start_app(
Ok(child_arc)
}
// taken from https://github.com/rust-lang/cargo/blob/78b10d4e611ab0721fc3aeaf0edd5dd8f4fdc372/src/cargo/core/shell.rs#L514
#[cfg(unix)]
mod terminal {
use std::mem;
pub fn stderr_width() -> Option<usize> {
unsafe {
let mut winsize: libc::winsize = mem::zeroed();
// The .into() here is needed for FreeBSD which defines TIOCGWINSZ
// as c_uint but ioctl wants c_ulong.
#[allow(clippy::useless_conversion)]
if libc::ioctl(libc::STDERR_FILENO, libc::TIOCGWINSZ.into(), &mut winsize) < 0 {
return None;
}
if winsize.ws_col > 0 {
Some(winsize.ws_col as usize)
} else {
None
}
}
}
}
// taken from https://github.com/rust-lang/cargo/blob/78b10d4e611ab0721fc3aeaf0edd5dd8f4fdc372/src/cargo/core/shell.rs#L543
#[cfg(windows)]
mod terminal {
use std::{cmp, mem, ptr};
use winapi::um::fileapi::*;
use winapi::um::handleapi::*;
use winapi::um::processenv::*;
use winapi::um::winbase::*;
use winapi::um::wincon::*;
use winapi::um::winnt::*;
pub fn stderr_width() -> Option<usize> {
unsafe {
let stdout = GetStdHandle(STD_ERROR_HANDLE);
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem::zeroed();
if GetConsoleScreenBufferInfo(stdout, &mut csbi) != 0 {
return Some((csbi.srWindow.Right - csbi.srWindow.Left) as usize);
}
// On mintty/msys/cygwin based terminals, the above fails with
// INVALID_HANDLE_VALUE. Use an alternate method which works
// in that case as well.
let h = CreateFileA(
"CONOUT$\0".as_ptr() as *const CHAR,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
ptr::null_mut(),
OPEN_EXISTING,
0,
ptr::null_mut(),
);
if h == INVALID_HANDLE_VALUE {
return None;
}
let mut csbi: CONSOLE_SCREEN_BUFFER_INFO = mem::zeroed();
let rc = GetConsoleScreenBufferInfo(h, &mut csbi);
CloseHandle(h);
if rc != 0 {
let width = (csbi.srWindow.Right - csbi.srWindow.Left) as usize;
// Unfortunately cygwin/mintty does not set the size of the
// backing console to match the actual window size. This
// always reports a size of 80 or 120 (not sure what
// determines that). Use a conservative max of 60 which should
// work in most circumstances. ConEmu does some magic to
// resize the console correctly, but there's no reasonable way
// to detect which kind of terminal we are running in, or if
// GetConsoleScreenBufferInfo returns accurate information.
return Some(cmp::min(60, width));
}
None
}
}
}