Files
huskies/server/src/chat/transport/matrix/rebuild.rs
T
TimmyandClaude Fable 5 f39c4b7c4b Remove all alternate update paths — fleet redeploy is release + upgrade all
Killed:
- rebuild_and_restart (in-container cargo self-compile): the MCP tool,
  the `rebuild` chat command in all four transports, the web-ui bot
  command, and the underlying function. This was the path that caused
  the exec() deadlocks.
- upgrade_sled gateway MCP tool: second entry point to sled upgrades,
  defaulted to serving the gateway's own macOS binary to Linux sleds.
- GET /api/huskies-binary (both sled and gateway route trees): served
  current_exe(), wrong platform when the gateway is macOS. Superseded
  by /api/artifacts/ which now also serves on the gateway route tree.
- `huskies upgrade` CLI subcommand and --source flag: third way of
  doing the same download-and-replace. Escape hatch for a bricked sled
  is `docker cp` + restart.

Kept, distinct jobs: `project-rebuild` (container/image updates),
`rebuild gateway` + script/local-release (gateway self-update).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 16:46:11 +01:00

75 lines
2.1 KiB
Rust

//! `rebuild gateway` command parsing.
//!
//! The old `rebuild` command (in-container cargo build + restart of a sled)
//! was removed: fleet binary updates go through `release` + `upgrade all`
//! exclusively. Only the gateway self-rebuild command remains here.
use crate::chat::util::strip_bot_mention;
/// A parsed rebuild command.
#[derive(Debug, PartialEq)]
pub struct RebuildCommand;
/// Parse a "rebuild gateway" command from a raw message body.
///
/// Returns `Some(RebuildCommand)` only when the stripped message begins with
/// "rebuild gateway" (case-insensitive).
pub fn extract_rebuild_gateway_command(
message: &str,
bot_name: &str,
bot_user_id: &str,
) -> Option<RebuildCommand> {
let stripped = strip_bot_mention(message, bot_name, bot_user_id);
let trimmed = stripped
.trim()
.trim_start_matches(|c: char| !c.is_alphanumeric());
let (cmd, rest) = trimmed.split_once(char::is_whitespace)?;
if !cmd.eq_ignore_ascii_case("rebuild") {
return None;
}
let qualifier = rest
.trim()
.trim_start_matches(|c: char| !c.is_alphanumeric());
let first_word = match qualifier.split_once(char::is_whitespace) {
Some((w, _)) => w,
None => qualifier,
};
if first_word.eq_ignore_ascii_case("gateway") {
Some(RebuildCommand)
} else {
None
}
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extract_gateway_rebuild() {
let cmd =
extract_rebuild_gateway_command("Timmy rebuild gateway", "Timmy", "@timmy:home.local");
assert_eq!(cmd, Some(RebuildCommand));
}
#[test]
fn plain_rebuild_is_not_gateway_rebuild() {
let cmd = extract_rebuild_gateway_command("Timmy rebuild", "Timmy", "@timmy:home.local");
assert_eq!(cmd, None);
}
#[test]
fn non_rebuild_returns_none() {
let cmd = extract_rebuild_gateway_command("Timmy status", "Timmy", "@timmy:home.local");
assert_eq!(cmd, None);
}
}