logiguard fork: GPUI xdg-activation keyboard-focus serial fix
Some checks failed
Update All Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Triage Project Sync (#84) / Sync triage project (push) Has been cancelled
release_nightly / notify_on_failure (push) Has been cancelled
release_nightly / check_style (push) Has been cancelled
release_nightly / run_tests_windows (push) Has been cancelled
release_nightly / clippy_windows (push) Has been cancelled
release_nightly / bundle_linux_aarch64 (push) Has been cancelled
release_nightly / bundle_linux_x86_64 (push) Has been cancelled
release_nightly / bundle_mac_aarch64 (push) Has been cancelled
release_nightly / bundle_mac_x86_64 (push) Has been cancelled
release_nightly / bundle_windows_aarch64 (push) Has been cancelled
release_nightly / bundle_windows_x86_64 (push) Has been cancelled
release_nightly / build_nix_linux_x86_64 (push) Has been cancelled
release_nightly / build_nix_mac_aarch64 (push) Has been cancelled
release_nightly / update_nightly_tag (push) Has been cancelled
Hotfix Review Monitor / check-hotfix-reviews (push) Has been cancelled
Stale PR Review Reminder / check-stale-prs (push) Has been cancelled
Update Weekly Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Bump collab-staging Tag / update-collab-staging-tag (push) Has been cancelled
compliance_check / scheduled_compliance_check (push) Has been cancelled
Some checks failed
Update All Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Triage Project Sync (#84) / Sync triage project (push) Has been cancelled
release_nightly / notify_on_failure (push) Has been cancelled
release_nightly / check_style (push) Has been cancelled
release_nightly / run_tests_windows (push) Has been cancelled
release_nightly / clippy_windows (push) Has been cancelled
release_nightly / bundle_linux_aarch64 (push) Has been cancelled
release_nightly / bundle_linux_x86_64 (push) Has been cancelled
release_nightly / bundle_mac_aarch64 (push) Has been cancelled
release_nightly / bundle_mac_x86_64 (push) Has been cancelled
release_nightly / bundle_windows_aarch64 (push) Has been cancelled
release_nightly / bundle_windows_x86_64 (push) Has been cancelled
release_nightly / build_nix_linux_x86_64 (push) Has been cancelled
release_nightly / build_nix_mac_aarch64 (push) Has been cancelled
release_nightly / update_nightly_tag (push) Has been cancelled
Hotfix Review Monitor / check-hotfix-reviews (push) Has been cancelled
Stale PR Review Reminder / check-stale-prs (push) Has been cancelled
Update Weekly Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Bump collab-staging Tag / update-collab-staging-tag (push) Has been cancelled
compliance_check / scheduled_compliance_check (push) Has been cancelled
Single-commit orphan branch: full zed-industries/zed @ 8c74db0 source tree with a 3-file patch applied (no upstream history). Patch (crates/gpui_linux/src/linux/wayland/): - serial.rs: add SerialKind::KeyboardEnter - client.rs: store wl_keyboard.enter serial; add latest_serial_of() - window.rs: activate() uses keyboard-enter serial (Mutter focus gate) Mutter honors window activation only when the token carries the keyboard- focus serial from wl_keyboard.enter; GPUI used a stale mouse-press serial. See docs/tray-window-focus-wayland.md in logiguard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
249
tooling/xtask/src/tasks/setup_webrtc.rs
Normal file
249
tooling/xtask/src/tasks/setup_webrtc.rs
Normal file
@@ -0,0 +1,249 @@
|
||||
#![allow(clippy::disallowed_methods, reason = "tooling is exempt")]
|
||||
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use cargo_toml::Manifest;
|
||||
use clap::Parser;
|
||||
use regex::Regex;
|
||||
use toml_edit::{DocumentMut, Item, Table, value};
|
||||
|
||||
use crate::workspace::load_workspace;
|
||||
|
||||
const GITIGNORE_ENTRY: &str = ".webrtc-sys/";
|
||||
const LOCAL_DIR_NAME: &str = ".webrtc-sys";
|
||||
const ENV_VAR: &str = "LK_CUSTOM_WEBRTC";
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct SetupWebrtcArgs {
|
||||
/// Re-download even if the target directory already exists.
|
||||
#[arg(long)]
|
||||
force: bool,
|
||||
|
||||
/// Override the host triple component used for the release artifact
|
||||
/// (e.g. `mac-arm64-release`). Defaults to the current host.
|
||||
#[arg(long)]
|
||||
triple: Option<String>,
|
||||
|
||||
/// Skip writing to `~/.cargo/config.toml`. Useful when you only want the
|
||||
/// archive on disk and intend to set `LK_CUSTOM_WEBRTC` yourself.
|
||||
#[arg(long)]
|
||||
no_cargo_config: bool,
|
||||
}
|
||||
|
||||
pub fn run_setup_webrtc(args: SetupWebrtcArgs) -> Result<()> {
|
||||
let metadata = load_workspace()?;
|
||||
let workspace_root = metadata.workspace_root.as_std_path().to_path_buf();
|
||||
|
||||
let rev = read_webrtc_sys_rev(&workspace_root)?;
|
||||
eprintln!("Pinned livekit-rust-sdks rev: {rev}");
|
||||
|
||||
let tag = fetch_webrtc_tag(&rev)?;
|
||||
eprintln!("WEBRTC_TAG for that rev: {tag}");
|
||||
|
||||
let triple = match args.triple {
|
||||
Some(triple) => triple,
|
||||
None => host_webrtc_triple()?,
|
||||
};
|
||||
eprintln!("Target triple: {triple}");
|
||||
|
||||
let local_root = workspace_root.join(LOCAL_DIR_NAME);
|
||||
let tag_dir = local_root.join(&tag);
|
||||
let extracted_dir = tag_dir.join(&triple);
|
||||
|
||||
if extracted_dir.exists() && !args.force {
|
||||
eprintln!(
|
||||
"Already present at {}, skipping download.",
|
||||
extracted_dir.display()
|
||||
);
|
||||
} else {
|
||||
if extracted_dir.exists() {
|
||||
fs::remove_dir_all(&extracted_dir)
|
||||
.with_context(|| format!("removing stale {}", extracted_dir.display()))?;
|
||||
}
|
||||
fs::create_dir_all(&tag_dir).with_context(|| format!("creating {}", tag_dir.display()))?;
|
||||
download_and_extract(&tag, &triple, &tag_dir)?;
|
||||
}
|
||||
|
||||
let absolute = extracted_dir
|
||||
.canonicalize()
|
||||
.with_context(|| format!("canonicalizing {}", extracted_dir.display()))?;
|
||||
|
||||
ensure_gitignore_entry(&workspace_root)?;
|
||||
|
||||
if args.no_cargo_config {
|
||||
eprintln!(
|
||||
"Skipping ~/.cargo/config.toml update. Set {ENV_VAR}={} yourself.",
|
||||
absolute.display()
|
||||
);
|
||||
} else {
|
||||
update_cargo_config(&absolute)?;
|
||||
}
|
||||
|
||||
eprintln!();
|
||||
eprintln!("Done. {ENV_VAR} -> {}", absolute.display());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_webrtc_sys_rev(workspace_root: &Path) -> Result<String> {
|
||||
let manifest_path = workspace_root.join("Cargo.toml");
|
||||
let manifest = Manifest::from_path(&manifest_path)
|
||||
.with_context(|| format!("parsing {}", manifest_path.display()))?;
|
||||
|
||||
let patch = manifest
|
||||
.patch
|
||||
.get("crates-io")
|
||||
.context("workspace Cargo.toml has no [patch.crates-io] section")?;
|
||||
let dep = patch
|
||||
.get("webrtc-sys")
|
||||
.context("[patch.crates-io] is missing webrtc-sys")?;
|
||||
let detail = dep
|
||||
.detail()
|
||||
.context("webrtc-sys patch entry is not a table")?;
|
||||
detail
|
||||
.git
|
||||
.as_ref()
|
||||
.context("webrtc-sys patch is missing a git source")?;
|
||||
detail
|
||||
.rev
|
||||
.clone()
|
||||
.context("webrtc-sys patch is missing a `rev`")
|
||||
}
|
||||
|
||||
fn fetch_webrtc_tag(rev: &str) -> Result<String> {
|
||||
let url = format!(
|
||||
"https://raw.githubusercontent.com/zed-industries/livekit-rust-sdks/{rev}/webrtc-sys/build/src/lib.rs"
|
||||
);
|
||||
let body = curl_text(&url).with_context(|| format!("fetching {url}"))?;
|
||||
|
||||
let re =
|
||||
Regex::new(r#"pub\s+const\s+WEBRTC_TAG\s*:\s*&str\s*=\s*"([^"]+)""#).expect("static regex");
|
||||
let captures = re
|
||||
.captures(&body)
|
||||
.with_context(|| format!("could not find WEBRTC_TAG in {url}"))?;
|
||||
Ok(captures[1].to_string())
|
||||
}
|
||||
|
||||
fn host_webrtc_triple() -> Result<String> {
|
||||
let os = match std::env::consts::OS {
|
||||
"macos" => "mac",
|
||||
"linux" => "linux",
|
||||
"windows" => "win",
|
||||
other => bail!("unsupported host OS: {other}"),
|
||||
};
|
||||
let arch = match std::env::consts::ARCH {
|
||||
"aarch64" => "arm64",
|
||||
"x86_64" => "x64",
|
||||
other => bail!("unsupported host arch: {other}"),
|
||||
};
|
||||
Ok(format!("{os}-{arch}-release"))
|
||||
}
|
||||
|
||||
fn download_and_extract(tag: &str, triple: &str, into: &Path) -> Result<()> {
|
||||
let url = format!(
|
||||
"https://github.com/zed-industries/livekit-rust-sdks/releases/download/{tag}/webrtc-{triple}.zip"
|
||||
);
|
||||
let zip_path = into.join(format!("webrtc-{triple}.zip"));
|
||||
|
||||
eprintln!("Downloading {url}");
|
||||
let status = Command::new("curl")
|
||||
.args(["-fL", "--retry", "3", "--progress-bar", "-o"])
|
||||
.arg(&zip_path)
|
||||
.arg(&url)
|
||||
.status()
|
||||
.context("running curl")?;
|
||||
if !status.success() {
|
||||
bail!("curl exited with {status} while downloading {url}");
|
||||
}
|
||||
|
||||
eprintln!("Extracting into {}", into.display());
|
||||
let status = Command::new("unzip")
|
||||
.arg("-q")
|
||||
.arg("-o")
|
||||
.arg(&zip_path)
|
||||
.arg("-d")
|
||||
.arg(into)
|
||||
.status()
|
||||
.context("running unzip")?;
|
||||
if !status.success() {
|
||||
bail!(
|
||||
"unzip exited with {status} while extracting {}",
|
||||
zip_path.display()
|
||||
);
|
||||
}
|
||||
|
||||
fs::remove_file(&zip_path).ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn curl_text(url: &str) -> Result<String> {
|
||||
let output = Command::new("curl")
|
||||
.args(["-fsSL", url])
|
||||
.output()
|
||||
.context("running curl")?;
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"curl failed for {url} (exit {}): {}",
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stderr).trim(),
|
||||
);
|
||||
}
|
||||
String::from_utf8(output.stdout).context("curl returned non-UTF-8 body")
|
||||
}
|
||||
|
||||
fn ensure_gitignore_entry(workspace_root: &Path) -> Result<()> {
|
||||
let path = workspace_root.join(".gitignore");
|
||||
let existing =
|
||||
fs::read_to_string(&path).with_context(|| format!("reading {}", path.display()))?;
|
||||
if existing
|
||||
.lines()
|
||||
.any(|line| line.trim() == GITIGNORE_ENTRY || line.trim() == LOCAL_DIR_NAME)
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
let mut updated = existing;
|
||||
if !updated.ends_with('\n') {
|
||||
updated.push('\n');
|
||||
}
|
||||
updated.push_str(GITIGNORE_ENTRY);
|
||||
updated.push('\n');
|
||||
fs::write(&path, updated).with_context(|| format!("writing {}", path.display()))?;
|
||||
eprintln!("Added {GITIGNORE_ENTRY} to .gitignore");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_cargo_config(webrtc_path: &Path) -> Result<()> {
|
||||
let home = std::env::var_os("HOME")
|
||||
.or_else(|| std::env::var_os("USERPROFILE"))
|
||||
.context("could not determine home directory")?;
|
||||
let config_path = PathBuf::from(home).join(".cargo").join("config.toml");
|
||||
if config_path.exists() {
|
||||
bail!(
|
||||
"{} already exists; refusing to modify it. \
|
||||
Add `[env]\\n{ENV_VAR} = \"{}\"` yourself, \
|
||||
or re-run with --no-cargo-config.",
|
||||
config_path.display(),
|
||||
webrtc_path.display(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(parent) = config_path.parent() {
|
||||
fs::create_dir_all(parent).with_context(|| format!("creating {}", parent.display()))?;
|
||||
}
|
||||
|
||||
let mut doc = DocumentMut::new();
|
||||
let mut env_table = Table::new();
|
||||
env_table.set_implicit(false);
|
||||
let path_str = webrtc_path
|
||||
.to_str()
|
||||
.context("webrtc path is not valid UTF-8")?;
|
||||
env_table.insert(ENV_VAR, value(path_str));
|
||||
doc.insert("env", Item::Table(env_table));
|
||||
|
||||
fs::write(&config_path, doc.to_string())
|
||||
.with_context(|| format!("writing {}", config_path.display()))?;
|
||||
eprintln!("Wrote {} with {ENV_VAR}={path_str}", config_path.display());
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user