feat: finalize external workdir implementation formatting
This commit is contained in:
@@ -90,8 +90,15 @@ async fn external_local_provider_read_write_is_filesystem_only() {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(session.capabilities(), WorkdirSessionCapabilities::READ_WRITE);
|
assert_eq!(
|
||||||
assert!(!session.capabilities().supports(WorkdirSessionCapability::Command));
|
session.capabilities(),
|
||||||
|
WorkdirSessionCapabilities::READ_WRITE
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!session
|
||||||
|
.capabilities()
|
||||||
|
.supports(WorkdirSessionCapability::Command)
|
||||||
|
);
|
||||||
|
|
||||||
let observed = WorkdirSession::read(
|
let observed = WorkdirSession::read(
|
||||||
&session,
|
&session,
|
||||||
|
|||||||
@@ -26279,8 +26279,7 @@ mod tests {
|
|||||||
created_by: test_browser_request_actor().account_id,
|
created_by: test_browser_request_actor().account_id,
|
||||||
created_at: created_at.clone(),
|
created_at: created_at.clone(),
|
||||||
expires_at: Some(
|
expires_at: Some(
|
||||||
(now + Duration::milliseconds(50))
|
(now + Duration::milliseconds(50)).to_rfc3339_opts(SecondsFormat::Nanos, true),
|
||||||
.to_rfc3339_opts(SecondsFormat::Nanos, true),
|
|
||||||
),
|
),
|
||||||
generation: 1,
|
generation: 1,
|
||||||
status: "offline".to_string(),
|
status: "offline".to_string(),
|
||||||
@@ -26966,7 +26965,10 @@ mod tests {
|
|||||||
break (operation_id, operation);
|
break (operation_id, operation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
assert!(matches!(operation.as_inner(), WorkdirSessionOperation::Edit(_)));
|
assert!(matches!(
|
||||||
|
operation.as_inner(),
|
||||||
|
WorkdirSessionOperation::Edit(_)
|
||||||
|
));
|
||||||
let result = workdir::http::dispatch_workdir_session_operation(
|
let result = workdir::http::dispatch_workdir_session_operation(
|
||||||
&local_session,
|
&local_session,
|
||||||
operation.into_inner(),
|
operation.into_inner(),
|
||||||
@@ -27015,7 +27017,10 @@ mod tests {
|
|||||||
break (operation_id, operation);
|
break (operation_id, operation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
assert!(matches!(operation.as_inner(), WorkdirSessionOperation::Write(_)));
|
assert!(matches!(
|
||||||
|
operation.as_inner(),
|
||||||
|
WorkdirSessionOperation::Write(_)
|
||||||
|
));
|
||||||
let result = workdir::http::dispatch_workdir_session_operation(
|
let result = workdir::http::dispatch_workdir_session_operation(
|
||||||
&local_session,
|
&local_session,
|
||||||
operation.into_inner(),
|
operation.into_inner(),
|
||||||
|
|||||||
@@ -11969,9 +11969,7 @@ fn apply_ticket_targets_and_workdir_capabilities_schema(conn: &Connection) -> Re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn migrate_external_workdir_access_and_optional_expiry_v66_to_v67(
|
fn migrate_external_workdir_access_and_optional_expiry_v66_to_v67(conn: &Connection) -> Result<()> {
|
||||||
conn: &Connection,
|
|
||||||
) -> Result<()> {
|
|
||||||
let current = current_schema_version(conn)?;
|
let current = current_schema_version(conn)?;
|
||||||
if current != 66 {
|
if current != 66 {
|
||||||
return Err(Error::Store(format!(
|
return Err(Error::Store(format!(
|
||||||
@@ -12068,11 +12066,10 @@ fn migrate_external_workdir_access_and_optional_expiry_v66_to_v67(
|
|||||||
BEGIN SELECT RAISE(ABORT, 'runtime_removal_in_progress'); END;
|
BEGIN SELECT RAISE(ABORT, 'runtime_removal_in_progress'); END;
|
||||||
"#,
|
"#,
|
||||||
)?;
|
)?;
|
||||||
let violations = tx.query_row(
|
let violations =
|
||||||
"SELECT COUNT(*) FROM pragma_foreign_key_check",
|
tx.query_row("SELECT COUNT(*) FROM pragma_foreign_key_check", [], |row| {
|
||||||
[],
|
row.get::<_, i64>(0)
|
||||||
|row| row.get::<_, i64>(0),
|
})?;
|
||||||
)?;
|
|
||||||
if violations != 0 {
|
if violations != 0 {
|
||||||
return Err(Error::Store(format!(
|
return Err(Error::Store(format!(
|
||||||
"schema-67 migration left {violations} foreign-key violation(s)"
|
"schema-67 migration left {violations} foreign-key violation(s)"
|
||||||
@@ -14368,7 +14365,9 @@ mod tests {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|migration| migration.version)
|
.map(|migration| migration.version)
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
vec![52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67]
|
vec![
|
||||||
|
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67
|
||||||
|
]
|
||||||
);
|
);
|
||||||
SqliteWorkspaceStore::migrate_database(&path).unwrap();
|
SqliteWorkspaceStore::migrate_database(&path).unwrap();
|
||||||
let conn = Connection::open(&path).unwrap();
|
let conn = Connection::open(&path).unwrap();
|
||||||
|
|||||||
@@ -131,7 +131,9 @@ fn authenticated_server_api_client(
|
|||||||
fn permission_label(permission: server_api::ExternalWorkdirPermission) -> &'static str {
|
fn permission_label(permission: server_api::ExternalWorkdirPermission) -> &'static str {
|
||||||
match permission {
|
match permission {
|
||||||
server_api::ExternalWorkdirPermission::ReadOnly => "read-only",
|
server_api::ExternalWorkdirPermission::ReadOnly => "read-only",
|
||||||
server_api::ExternalWorkdirPermission::ReadWrite => "read-write (files only; commands disabled)",
|
server_api::ExternalWorkdirPermission::ReadWrite => {
|
||||||
|
"read-write (files only; commands disabled)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +235,8 @@ fn configure_interactively(
|
|||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
&format!("Workspace [{}; q to cancel]: ", initial_index + 1),
|
&format!("Workspace [{}; q to cancel]: ", initial_index + 1),
|
||||||
)? else {
|
)?
|
||||||
|
else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
if matches!(selection.as_str(), "q" | "quit" | "cancel") {
|
if matches!(selection.as_str(), "q" | "quit" | "cancel") {
|
||||||
@@ -264,7 +267,8 @@ fn configure_interactively(
|
|||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
&format!("Permission [r/w; current {current_permission}; q to cancel]: "),
|
&format!("Permission [r/w; current {current_permission}; q to cancel]: "),
|
||||||
)? else {
|
)?
|
||||||
|
else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
options.permission = match permission.as_str() {
|
options.permission = match permission.as_str() {
|
||||||
@@ -281,7 +285,8 @@ fn configure_interactively(
|
|||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
"TTL [empty keeps current; `none` is unlimited; q to cancel]: ",
|
"TTL [empty keeps current; `none` is unlimited; q to cancel]: ",
|
||||||
)? else {
|
)?
|
||||||
|
else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
options.ttl = match ttl.as_str() {
|
options.ttl = match ttl.as_str() {
|
||||||
@@ -418,7 +423,10 @@ pub(crate) async fn run(options: WorkdirShareOptions) -> Result<(), String> {
|
|||||||
println!("Permission: {}", permission_label(grant.permission));
|
println!("Permission: {}", permission_label(grant.permission));
|
||||||
println!(
|
println!(
|
||||||
"Expires at: {}",
|
"Expires at: {}",
|
||||||
grant.expires_at.as_deref().unwrap_or("never (until stopped or revoked)")
|
grant
|
||||||
|
.expires_at
|
||||||
|
.as_deref()
|
||||||
|
.unwrap_or("never (until stopped or revoked)")
|
||||||
);
|
);
|
||||||
|
|
||||||
let expires_at = grant
|
let expires_at = grant
|
||||||
@@ -939,14 +947,10 @@ mod tests {
|
|||||||
let mut input = std::io::Cursor::new(b"\n\n\nyes\n".to_vec());
|
let mut input = std::io::Cursor::new(b"\n\n\nyes\n".to_vec());
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
|
|
||||||
let selected = configure_interactively(
|
let selected =
|
||||||
share_options(),
|
configure_interactively(share_options(), &workspaces, &mut input, &mut output)
|
||||||
&workspaces,
|
.unwrap()
|
||||||
&mut input,
|
.unwrap();
|
||||||
&mut output,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(selected.workspace_id, "workspace-a");
|
assert_eq!(selected.workspace_id, "workspace-a");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -970,14 +974,10 @@ mod tests {
|
|||||||
let mut input = std::io::Cursor::new(b"2\nw\n15m\ny\n".to_vec());
|
let mut input = std::io::Cursor::new(b"2\nw\n15m\ny\n".to_vec());
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
|
|
||||||
let selected = configure_interactively(
|
let selected =
|
||||||
share_options(),
|
configure_interactively(share_options(), &workspaces, &mut input, &mut output)
|
||||||
&workspaces,
|
.unwrap()
|
||||||
&mut input,
|
.unwrap();
|
||||||
&mut output,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(selected.workspace_id, "workspace-b");
|
assert_eq!(selected.workspace_id, "workspace-b");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -993,14 +993,9 @@ mod tests {
|
|||||||
let mut declined = std::io::Cursor::new(b"\n\n\nno\n".to_vec());
|
let mut declined = std::io::Cursor::new(b"\n\n\nno\n".to_vec());
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
assert!(
|
assert!(
|
||||||
configure_interactively(
|
configure_interactively(share_options(), &workspaces, &mut declined, &mut output,)
|
||||||
share_options(),
|
.unwrap()
|
||||||
&workspaces,
|
.is_none()
|
||||||
&mut declined,
|
|
||||||
&mut output,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.is_none()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut eof = std::io::Cursor::new(Vec::<u8>::new());
|
let mut eof = std::io::Cursor::new(Vec::<u8>::new());
|
||||||
@@ -1014,8 +1009,16 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn interactive_share_fails_closed_without_input_and_prompt_ttys() {
|
fn interactive_share_fails_closed_without_input_and_prompt_ttys() {
|
||||||
assert!(ensure_interactive_tty(true, true).is_ok());
|
assert!(ensure_interactive_tty(true, true).is_ok());
|
||||||
assert!(ensure_interactive_tty(false, true).unwrap_err().contains("--non-interactive"));
|
assert!(
|
||||||
assert!(ensure_interactive_tty(true, false).unwrap_err().contains("--non-interactive"));
|
ensure_interactive_tty(false, true)
|
||||||
|
.unwrap_err()
|
||||||
|
.contains("--non-interactive")
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
ensure_interactive_tty(true, false)
|
||||||
|
.unwrap_err()
|
||||||
|
.contains("--non-interactive")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_server_api_client(base_url: &str) -> ServerApiClient {
|
fn test_server_api_client(base_url: &str) -> ServerApiClient {
|
||||||
|
|||||||
Reference in New Issue
Block a user