runtime: use pod flag for session identity
This commit is contained in:
parent
b6af761da0
commit
15f54df0ba
|
|
@ -39,10 +39,6 @@ struct Cli {
|
||||||
#[arg(long, value_name = "PATH")]
|
#[arg(long, value_name = "PATH")]
|
||||||
project: Option<PathBuf>,
|
project: Option<PathBuf>,
|
||||||
|
|
||||||
/// Internal typed pod-name override for session restore launched by the TUI.
|
|
||||||
#[arg(long, value_name = "NAME", requires = "session", hide = true)]
|
|
||||||
session_pod_name: Option<String>,
|
|
||||||
|
|
||||||
/// Internal resolved manifest config for delegated child Pod spawning.
|
/// Internal resolved manifest config for delegated child Pod spawning.
|
||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
|
|
@ -85,7 +81,7 @@ struct Cli {
|
||||||
/// concurrent writers are prevented by the pod-registry.
|
/// concurrent writers are prevented by the pod-registry.
|
||||||
/// Mutually exclusive with `--adopt` (spawned children always start
|
/// Mutually exclusive with `--adopt` (spawned children always start
|
||||||
/// fresh).
|
/// fresh).
|
||||||
#[arg(long, value_name = "UUID", conflicts_with_all = ["adopt", "pod"])]
|
#[arg(long, value_name = "UUID", conflicts_with_all = ["adopt"])]
|
||||||
session: Option<SegmentId>,
|
session: Option<SegmentId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,9 +97,8 @@ fn runtime_workspace_root(cli: &Cli) -> Result<PathBuf, String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_pod_name(cli: &Cli, workspace_root: &Path) -> String {
|
fn runtime_pod_name(cli: &Cli, workspace_root: &Path) -> String {
|
||||||
cli.session_pod_name
|
cli.pod
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.or(cli.pod.as_deref())
|
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
.unwrap_or_else(|| default_pod_name_for_workspace(workspace_root))
|
.unwrap_or_else(|| default_pod_name_for_workspace(workspace_root))
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +166,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_session_restore_overrides(manifest: &mut PodManifest, cli: &Cli) -> Result<(), String> {
|
fn apply_session_restore_overrides(manifest: &mut PodManifest, cli: &Cli) -> Result<(), String> {
|
||||||
if let Some(pod_name) = cli.session_pod_name.as_deref().or(cli.pod.as_deref()) {
|
if let Some(pod_name) = cli.pod.as_deref() {
|
||||||
manifest.pod.name = pod_name.to_string();
|
manifest.pod.name = pod_name.to_string();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -733,12 +728,28 @@ permission = "write"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pod_flag_conflicts_with_session() {
|
fn pod_flag_is_runtime_identity_for_session_restore() {
|
||||||
let segment_id = session_store::new_segment_id();
|
let tmp = TempDir::new().unwrap();
|
||||||
let segment_id = segment_id.to_string();
|
let workspace = tmp.path().join("explicit-workspace");
|
||||||
let err = Cli::try_parse_from(["yoi pod", "--pod", "agent", "--session", &segment_id])
|
let store = tmp.path().join("sessions");
|
||||||
.unwrap_err();
|
std::fs::create_dir(&workspace).unwrap();
|
||||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
let segment_id = session_store::new_segment_id().to_string();
|
||||||
|
let cli = Cli::try_parse_from([
|
||||||
|
"yoi pod",
|
||||||
|
"--workspace",
|
||||||
|
workspace.to_str().unwrap(),
|
||||||
|
"--session",
|
||||||
|
&segment_id,
|
||||||
|
"--pod",
|
||||||
|
"explicit-name",
|
||||||
|
"--store",
|
||||||
|
store.to_str().unwrap(),
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(cli.session.unwrap().to_string(), segment_id);
|
||||||
|
assert_eq!(cli.pod.as_deref(), Some("explicit-name"));
|
||||||
|
assert_eq!(runtime_pod_name(&cli, &workspace), "explicit-name");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -835,6 +846,20 @@ permission = "write"
|
||||||
assert_eq!(cli.pod.as_deref(), Some("agent"));
|
assert_eq!(cli.pod.as_deref(), Some("agent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn old_session_pod_name_identity_alias_is_rejected() {
|
||||||
|
let segment_id = session_store::new_segment_id().to_string();
|
||||||
|
let err = Cli::try_parse_from([
|
||||||
|
"yoi pod",
|
||||||
|
"--session",
|
||||||
|
&segment_id,
|
||||||
|
"--session-pod-name",
|
||||||
|
"agent",
|
||||||
|
])
|
||||||
|
.unwrap_err();
|
||||||
|
assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn removed_profile_pod_name_alias_is_rejected() {
|
fn removed_profile_pod_name_alias_is_rejected() {
|
||||||
let err = Cli::try_parse_from(["yoi pod", "--profile-pod-name", "agent"]).unwrap_err();
|
let err = Cli::try_parse_from(["yoi pod", "--profile-pod-name", "agent"]).unwrap_err();
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,10 @@ pub enum LaunchMode {
|
||||||
Resume,
|
Resume,
|
||||||
/// `yoi --session <UUID>`: skip the picker, go straight to the
|
/// `yoi --session <UUID>`: skip the picker, go straight to the
|
||||||
/// resume name dialog with `id` baked in.
|
/// resume name dialog with `id` baked in.
|
||||||
ResumeWithSession(SegmentId),
|
ResumeWithSession {
|
||||||
|
id: SegmentId,
|
||||||
|
pod_name: Option<String>,
|
||||||
|
},
|
||||||
/// `yoi panel`: open the workspace panel from the current workspace.
|
/// `yoi panel`: open the workspace panel from the current workspace.
|
||||||
Panel,
|
Panel,
|
||||||
}
|
}
|
||||||
|
|
@ -93,8 +96,8 @@ pub async fn launch(options: LaunchOptions) -> ExitCode {
|
||||||
socket_override,
|
socket_override,
|
||||||
} => single_pod::run_pod_name(pod_name, socket_override, runtime_command).await,
|
} => single_pod::run_pod_name(pod_name, socket_override, runtime_command).await,
|
||||||
LaunchMode::Resume => single_pod::run_resume(runtime_command).await,
|
LaunchMode::Resume => single_pod::run_resume(runtime_command).await,
|
||||||
LaunchMode::ResumeWithSession(id) => {
|
LaunchMode::ResumeWithSession { id, pod_name } => {
|
||||||
single_pod::run_spawn(Some(id), None, None, runtime_command).await
|
single_pod::run_spawn(Some(id), pod_name, None, runtime_command).await
|
||||||
}
|
}
|
||||||
LaunchMode::Panel => single_pod::run_panel(runtime_command).await,
|
LaunchMode::Panel => single_pod::run_panel(runtime_command).await,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -297,11 +297,6 @@ fn parse_args_slice(args: &[String]) -> Result<Mode, ParseError> {
|
||||||
"--profile can only be used for fresh spawn".to_string(),
|
"--profile can only be used for fresh spawn".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if pod_name.is_some() && session.is_some() {
|
|
||||||
return Err(ParseError(
|
|
||||||
"--pod and --session are mutually exclusive".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if pod_name.is_some() && resume {
|
if pod_name.is_some() && resume {
|
||||||
return Err(ParseError(
|
return Err(ParseError(
|
||||||
"--pod and --resume are mutually exclusive".to_string(),
|
"--pod and --resume are mutually exclusive".to_string(),
|
||||||
|
|
@ -324,6 +319,12 @@ fn parse_args_slice(args: &[String]) -> Result<Mode, ParseError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let pod_name = pod_name.or(positional);
|
let pod_name = pod_name.or(positional);
|
||||||
|
if socket_override.is_some() && session.is_some() {
|
||||||
|
return Err(ParseError(
|
||||||
|
"--socket can only be used with --pod attach mode".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(profile) = profile {
|
if let Some(profile) = profile {
|
||||||
return Ok(Mode::Tui {
|
return Ok(Mode::Tui {
|
||||||
mode: LaunchMode::Spawn {
|
mode: LaunchMode::Spawn {
|
||||||
|
|
@ -333,6 +334,12 @@ fn parse_args_slice(args: &[String]) -> Result<Mode, ParseError> {
|
||||||
workspace_root,
|
workspace_root,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if let Some(id) = session {
|
||||||
|
return Ok(Mode::Tui {
|
||||||
|
mode: LaunchMode::ResumeWithSession { id, pod_name },
|
||||||
|
workspace_root,
|
||||||
|
});
|
||||||
|
}
|
||||||
if let Some(pod_name) = pod_name {
|
if let Some(pod_name) = pod_name {
|
||||||
return Ok(Mode::Tui {
|
return Ok(Mode::Tui {
|
||||||
mode: LaunchMode::PodName {
|
mode: LaunchMode::PodName {
|
||||||
|
|
@ -348,13 +355,6 @@ fn parse_args_slice(args: &[String]) -> Result<Mode, ParseError> {
|
||||||
workspace_root,
|
workspace_root,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(id) = session {
|
|
||||||
return Ok(Mode::Tui {
|
|
||||||
mode: LaunchMode::ResumeWithSession(id),
|
|
||||||
workspace_root,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Mode::Tui {
|
Ok(Mode::Tui {
|
||||||
mode: LaunchMode::Spawn {
|
mode: LaunchMode::Spawn {
|
||||||
pod_name: None,
|
pod_name: None,
|
||||||
|
|
@ -563,13 +563,29 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_rejects_pod_and_session() {
|
fn parse_session_accepts_explicit_runtime_pod_identity() {
|
||||||
let segment_id = session_store::new_segment_id().to_string();
|
let segment_id = session_store::new_segment_id();
|
||||||
let err = parse_args_from(["--pod", "agent", "--session", &segment_id]).unwrap_err();
|
match parse_args_from([
|
||||||
assert_eq!(
|
"--session",
|
||||||
err.to_string(),
|
&segment_id.to_string(),
|
||||||
"--pod and --session are mutually exclusive"
|
"--pod",
|
||||||
);
|
"explicit-name",
|
||||||
|
])
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
Mode::Tui {
|
||||||
|
mode:
|
||||||
|
LaunchMode::ResumeWithSession {
|
||||||
|
id,
|
||||||
|
pod_name: Some(pod_name),
|
||||||
|
},
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
assert_eq!(id, segment_id);
|
||||||
|
assert_eq!(pod_name, "explicit-name");
|
||||||
|
}
|
||||||
|
_ => panic!("expected ResumeWithSession mode with explicit pod name"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user