Improve release and benchmark tooling

This commit is contained in:
DuProcess
2026-06-20 10:37:26 -04:00
parent 7884ea2796
commit b44ff8e773
12 changed files with 608 additions and 73 deletions
+92 -6
View File
@@ -67,11 +67,11 @@ fn terminal_size() -> (u16, u16) {
}
#[derive(Debug, Parser)]
#[command(name = "dosh-client")]
#[command(name = "dosh-client", version)]
struct Args {
#[arg()]
server: Option<String>,
#[arg()]
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
command: Vec<String>,
#[arg(long)]
session: Option<String>,
@@ -192,7 +192,7 @@ async fn main() -> Result<()> {
let args = Args::parse();
let config = load_client_config(None).unwrap_or_default();
if args.server.as_deref() == Some("update") {
return run_update(&config);
return run_update(&config, update_check_requested(&args.command)?);
}
if args.server.as_deref() == Some("import-ssh") {
return run_import_ssh(&config, &args.command);
@@ -1079,13 +1079,75 @@ fn run_sessions_command(
Ok(())
}
fn run_update(config: &dosh::config::ClientConfig) -> Result<()> {
fn update_check_requested(command: &[String]) -> Result<bool> {
match command {
[] => Ok(false),
[flag] if flag == "--check" || flag == "-n" => Ok(true),
_ => Err(anyhow!("usage: dosh update [--check]")),
}
}
fn release_artifact_name() -> &'static str {
match (std::env::consts::OS, std::env::consts::ARCH) {
("macos", "aarch64") => "dosh-macos-aarch64.tar.gz",
("macos", "x86_64") => "dosh-macos-x86_64.tar.gz",
("linux", "aarch64") => "dosh-linux-aarch64.tar.gz",
("linux", "x86_64") => "dosh-linux-x86_64.tar.gz",
("windows", "x86_64") => "dosh-windows-x86_64.zip",
("windows", "aarch64") => "dosh-windows-aarch64.zip",
_ => "dosh-unknown.tar.gz",
}
}
fn latest_release_download_url(repo: &str, artifact: &str) -> Option<String> {
let web = repo
.strip_suffix(".git")
.unwrap_or(repo)
.trim_end_matches('/');
if !web.starts_with("http://") && !web.starts_with("https://") {
return None;
}
Some(format!("{web}/releases/latest/download/{artifact}"))
}
fn url_reachable(url: &str) -> Result<bool> {
let status = Command::new("curl")
.arg("-fsIL")
.arg(url)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.with_context(|| format!("check {url}"))?;
Ok(status.success())
}
fn run_update(config: &dosh::config::ClientConfig, check_only: bool) -> Result<()> {
let repo = config
.update_repo
.clone()
.unwrap_or_else(|| "https://git.palav.dev/Palav/dosh.git".to_string());
let raw_base = raw_base_from_repo(&repo);
let installer = format!("{raw_base}/raw/branch/main/install.sh");
let artifact = release_artifact_name();
let binary_url = latest_release_download_url(&repo, artifact);
if check_only {
println!("dosh {}", env!("CARGO_PKG_VERSION"));
println!("repo: {repo}");
println!("installer: {installer}");
if let Some(binary_url) = &binary_url {
let status = if url_reachable(binary_url)? {
"available"
} else {
"missing"
};
println!("prebuilt: {status} ({artifact})");
println!("prebuilt_url: {binary_url}");
} else {
println!("prebuilt: unavailable for non-HTTP repo");
}
return Ok(());
}
let update_cache = dirs::cache_dir()
.unwrap_or_else(|| expand_tilde("~/.cache"))
.join("dosh")
@@ -4286,12 +4348,12 @@ const TERMINAL_CLEANUP: &[u8] = concat!(
mod tests {
use super::{
DisconnectStatus, DynamicForward, FrameBuffer, LocalForward, PredictMode, Predictor,
RemoteForward, SshConfig, StatusAction, auth_allows,
RemoteForward, SshConfig, StatusAction, auth_allows, latest_release_download_url,
load_first_native_identity_with_prompt, parse_dynamic_forward, parse_local_forward,
parse_remote_forward, parse_ssh_config, raw_contains_host_table, recv_response_until,
render_status_clear, render_status_overlay, requested_env, resolved_startup_command,
ssh_destination_host, ssh_username, ssh_with_user, startup_command,
toml_bare_key_or_quoted,
toml_bare_key_or_quoted, update_check_requested,
};
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
use dosh::native::EnvVar;
@@ -4839,6 +4901,30 @@ mod tests {
);
}
#[test]
fn update_check_accepts_only_check_flag() {
assert!(!update_check_requested(&[]).unwrap());
assert!(update_check_requested(&["--check".to_string()]).unwrap());
assert!(update_check_requested(&["-n".to_string()]).unwrap());
assert!(update_check_requested(&["--wat".to_string()]).is_err());
assert!(update_check_requested(&["--check".to_string(), "extra".to_string()]).is_err());
}
#[test]
fn release_download_url_uses_latest_release_asset() {
assert_eq!(
latest_release_download_url(
"https://git.palav.dev/Palav/dosh.git",
"dosh-linux-x86_64.tar.gz"
)
.unwrap(),
"https://git.palav.dev/Palav/dosh/releases/latest/download/dosh-linux-x86_64.tar.gz"
);
assert!(
latest_release_download_url("git@git.palav.dev:Palav/dosh.git", "artifact").is_none()
);
}
#[test]
fn resolved_startup_command_expands_global_extension() {
let mut config = ClientConfig::default();