Files
ghostty-rs/crates/ghostty-cli/src/version.rs
T
ddidderr f76179f49a fix: +show-face u21/UTF-8 semantics, Zig output buffering, isAbsolute
Resolves RV14 (docs/rewrite/notes/review-rv14-codex.md, final-Z17.md):
- +show-face --cp parses as u21 (new U21 field type): out-of-range
  values give an invalid-value diagnostic and exit 1 instead of a panic;
  --string accepts raw bytes and fails with error.InvalidUtf8 after the
  codepoint lookup like Zig.
- CLI actions write through ZigWriter, a model of Zig 0.15's buffered
  File.writer (fixed buffer, drain on overflow, explicit flush), so
  stdout/stderr interleave in Zig's flush order (+show-face, help,
  version, validate-config, show-config, list-*, ssh-cache, crash-report,
  edit-config, new-window).
- Zig 0.15.2 std.fs.path.isAbsolute port (Windows: \theme and /theme are
  absolute) replaces Path::is_absolute at every Zig isAbsolute site.
- io_uring is available iff a 256-entry ring can be created, like
  libxev; the reactor falls back to IORING_OP_TIMEOUT without EXT_ARG.
- Windows basename (`λ:theme`) verified against 0.15.2 (test added).

Test Plan:
- cargo test --workspace --no-fail-fast
- diff +show-face outputs (pipe) against /usr/bin/ghostty
2026-10-12 15:15:18 +02:00

124 lines
4.2 KiB
Rust

//! `+version` (ZIG/src/cli/version.zig).
use std::io::{IsTerminal, Write};
use crate::{
build_info::{self, BuildInfo},
error::Error,
};
/// The `version` command is used to display information about Ghostty. Recognized as
/// either `+version` or `--version`.
pub fn run(_args: &[impl AsRef<[u8]>]) -> Result<u8, Error> {
let stdout = std::io::stdout();
let tty = stdout.is_terminal();
let mut out = crate::zig_writer::ZigWriter::new(crate::zig_writer::stdout_sink(), 1024);
write_version(&mut out, &build_info::get(), tty)?;
out.flush()?;
Ok(0)
}
fn version_na(v: Option<crate::build_info::Version>) -> String {
v.map_or_else(|| "unknown".to_string(), |v| v.to_string())
}
/// Write the version text.
pub fn write_version(out: &mut dyn Write, info: &BuildInfo, tty: bool) -> std::io::Result<()> {
if tty {
if let Some(commit) = &info.commit {
write!(
out,
"\x1b]8;;https://github.com/ghostty-org/ghostty/commit/{commit}\x1b\\"
)?;
}
}
write!(out, "Ghostty {}\n\n", info.version_string)?;
if tty {
write!(out, "\x1b]8;;\x1b\\")?;
}
writeln!(out, "Version")?;
writeln!(out, " - version: {}", info.version_string)?;
writeln!(out, " - channel: {}", info.release_channel)?;
writeln!(out, "Build Config")?;
// The Zig build prints its compiler version here.
writeln!(out, " - Rust version : {}", env!("GHOSTTY_RUSTC_VERSION"))?;
writeln!(out, " - build mode : {}", info.build_mode)?;
writeln!(out, " - app runtime : {}", info.app_runtime)?;
writeln!(out, " - font engine : {}", info.font_backend)?;
writeln!(out, " - renderer : {}", info.renderer)?;
writeln!(out, " - libxev : {}", ghostty_os::xev::backend())?;
if info.app_runtime == ".gtk" {
let kernel_info = ghostty_os::get_kernel_info();
writeln!(
out,
" - kernel version: {}",
kernel_info
.as_deref()
.unwrap_or("Kernel information unavailable")
)?;
let de = match ghostty_os::desktop_environment() {
ghostty_os::DesktopEnvironment::Gnome => "gnome",
ghostty_os::DesktopEnvironment::Macos => "macos",
ghostty_os::DesktopEnvironment::Other => "other",
ghostty_os::DesktopEnvironment::Windows => "windows",
};
writeln!(out, " - desktop env : {de}")?;
writeln!(out, " - GTK version :")?;
writeln!(out, " build : {}", version_na(info.gtk_build))?;
writeln!(out, " runtime : {}", version_na(info.gtk_runtime))?;
writeln!(out, " - libadwaita : enabled")?;
writeln!(out, " build : {}", version_na(info.adw_build))?;
writeln!(out, " runtime : {}", version_na(info.adw_runtime))?;
writeln!(
out,
" - libX11 : {}",
if info.x11 { "enabled" } else { "disabled" }
)?;
writeln!(
out,
" - libwayland : {}",
if info.wayland { "enabled" } else { "disabled" }
)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
#![allow(clippy::unwrap_used)]
use super::*;
#[test]
fn version_output_layout() {
let mut buf = Vec::new();
let info = BuildInfo {
version_string: "1.3.1".into(),
commit: None,
release_channel: "stable".into(),
..BuildInfo::default()
};
write_version(&mut buf, &info, false).unwrap();
let s = String::from_utf8(buf).unwrap();
assert!(s.starts_with(
"Ghostty 1.3.1\n\nVersion\n - version: 1.3.1\n - channel: stable\nBuild Config\n"
));
assert!(s.contains(" - libwayland : enabled\n"));
}
#[test]
fn version_tty_link() {
let info = BuildInfo {
commit: Some("abc".into()),
..BuildInfo::default()
};
let mut buf = Vec::new();
write_version(&mut buf, &info, true).unwrap();
let s = String::from_utf8(buf).unwrap();
assert!(
s.starts_with("\x1b]8;;https://github.com/ghostty-org/ghostty/commit/abc\x1b\\Ghostty")
);
}
}