feat: add peer pod handshake command
This commit is contained in:
@@ -1204,6 +1204,22 @@ impl App {
|
||||
});
|
||||
}
|
||||
Event::PodsListed { .. } | Event::PodRestored { .. } => {}
|
||||
Event::PeerRegistered { result } => {
|
||||
let source = result
|
||||
.get("source")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.unwrap_or("this Pod");
|
||||
let peer = result
|
||||
.get("peer")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.unwrap_or("peer Pod");
|
||||
self.flash_actionbar_notice(
|
||||
format!("Peer handshake registered: `{source}` ↔ `{peer}`"),
|
||||
ActionbarNoticeLevel::Info,
|
||||
ActionbarNoticeSource::Tui,
|
||||
Duration::from_secs(4),
|
||||
);
|
||||
}
|
||||
Event::Shutdown => {
|
||||
self.mark_orphan_compacts_incomplete();
|
||||
self.quit = true;
|
||||
|
||||
@@ -156,6 +156,15 @@ impl CommandRegistry {
|
||||
can_execute: rewind_available,
|
||||
executor: rewind_command,
|
||||
});
|
||||
registry.register(CommandSpec {
|
||||
name: "peer",
|
||||
aliases: &[],
|
||||
usage: "peer <pod-name>",
|
||||
description: "Make another existing Pod visible as a reciprocal peer.",
|
||||
argument_parser: peer_args,
|
||||
can_execute: peer_available,
|
||||
executor: peer_command,
|
||||
});
|
||||
registry
|
||||
}
|
||||
|
||||
@@ -302,6 +311,17 @@ fn rewind_args(raw: &str) -> Result<CommandArgs, CommandDiagnostic> {
|
||||
}
|
||||
}
|
||||
|
||||
fn peer_args(raw: &str) -> Result<CommandArgs, CommandDiagnostic> {
|
||||
let args = CommandArgs::parse_whitespace(raw);
|
||||
if args.argv().len() == 1 {
|
||||
Ok(args)
|
||||
} else {
|
||||
Err(CommandDiagnostic::new(
|
||||
"Invalid arguments. Usage: peer <pod-name>",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn compact_available(environment: &CommandEnvironment) -> Result<(), CommandDiagnostic> {
|
||||
if !environment.connected {
|
||||
return Err(CommandDiagnostic::new(
|
||||
@@ -335,6 +355,20 @@ fn rewind_available(environment: &CommandEnvironment) -> Result<(), CommandDiagn
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn peer_available(environment: &CommandEnvironment) -> Result<(), CommandDiagnostic> {
|
||||
if !environment.connected {
|
||||
return Err(CommandDiagnostic::new(
|
||||
"Cannot register a peer before the Pod is connected.",
|
||||
));
|
||||
}
|
||||
if environment.running {
|
||||
return Err(CommandDiagnostic::new(
|
||||
"Cannot register a peer while the Pod is running.",
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn help_command(invocation: CommandInvocation<'_>) -> CommandExecution {
|
||||
if let Some(name) = invocation.args.argv().first() {
|
||||
let Some(command) = invocation.registry.find(name) else {
|
||||
@@ -394,6 +428,20 @@ fn rewind_command(invocation: CommandInvocation<'_>) -> CommandExecution {
|
||||
}
|
||||
}
|
||||
|
||||
fn peer_command(invocation: CommandInvocation<'_>) -> CommandExecution {
|
||||
let _ = invocation.command;
|
||||
let _ = invocation.environment;
|
||||
let name = invocation.args.argv()[0].clone();
|
||||
CommandExecution {
|
||||
method: Some(Method::RegisterPeer { name: name.clone() }),
|
||||
diagnostics: vec![CommandDiagnostic::new(format!(
|
||||
"peer handshake requested with `{name}`"
|
||||
))],
|
||||
exit_command_mode: true,
|
||||
clear_input: true,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -501,4 +549,38 @@ mod tests {
|
||||
let result = registry.dispatch("rewind", &paused);
|
||||
assert!(matches!(result.method, Some(Method::ListRewindTargets)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peer_command_returns_register_peer_method() {
|
||||
let registry = CommandRegistry::builtins();
|
||||
let result = registry.dispatch("peer reviewer", &env());
|
||||
assert!(matches!(
|
||||
result.method,
|
||||
Some(Method::RegisterPeer { ref name }) if name == "reviewer"
|
||||
));
|
||||
assert!(result.exit_command_mode);
|
||||
assert!(result.clear_input);
|
||||
assert!(result.diagnostics[0].message.contains("peer handshake"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peer_invalid_arguments_are_local_diagnostic() {
|
||||
let registry = CommandRegistry::builtins();
|
||||
for command in ["peer", "peer one two"] {
|
||||
let result = registry.dispatch(command, &env());
|
||||
assert!(result.method.is_none());
|
||||
assert!(!result.exit_command_mode);
|
||||
assert!(result.diagnostics[0].message.contains("Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peer_rejects_running() {
|
||||
let registry = CommandRegistry::builtins();
|
||||
let mut running = env();
|
||||
running.running = true;
|
||||
let result = registry.dispatch("peer reviewer", &running);
|
||||
assert!(result.method.is_none());
|
||||
assert!(result.diagnostics[0].message.contains("running"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user