Restructure persistence of remote workspaces to make room for WSL and other non-ssh remote projects (#36714)

This is another pure refactor, to prepare for adding direct WSL support.

###  Todo

* [x] Represent `paths` in the same way for all workspaces, instead of
having a completely separate SSH representation
* [x] Adjust sqlite tables
    * [x] `ssh_projects` -> `ssh_connections` (drop paths)
    * [x] `workspaces.local_paths` -> `paths`
    * [x] remove duplicate path columns on `workspaces`
* [x] Add migrations for backward-compatibility

Release Notes:

- N/A

---------

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
Max Brunsfeld 2025-08-22 14:10:45 -07:00 committed by GitHub
parent 639417c2bc
commit f649c31bf9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 784 additions and 1080 deletions

View file

@ -47,8 +47,8 @@ use theme::{
use util::{ResultExt, TryFutureExt, maybe};
use uuid::Uuid;
use workspace::{
AppState, SerializedWorkspaceLocation, Toast, Workspace, WorkspaceSettings, WorkspaceStore,
notifications::NotificationId,
AppState, PathList, SerializedWorkspaceLocation, Toast, Workspace, WorkspaceSettings,
WorkspaceStore, notifications::NotificationId,
};
use zed::{
OpenListener, OpenRequest, RawOpenRequest, app_menus, build_window_options,
@ -949,15 +949,14 @@ async fn restore_or_create_workspace(app_state: Arc<AppState>, cx: &mut AsyncApp
if let Some(locations) = restorable_workspace_locations(cx, &app_state).await {
let mut tasks = Vec::new();
for location in locations {
for (location, paths) in locations {
match location {
SerializedWorkspaceLocation::Local(location, _) => {
SerializedWorkspaceLocation::Local => {
let app_state = app_state.clone();
let paths = location.paths().to_vec();
let task = cx.spawn(async move |cx| {
let open_task = cx.update(|cx| {
workspace::open_paths(
&paths,
&paths.paths(),
app_state,
workspace::OpenOptions::default(),
cx,
@ -979,7 +978,7 @@ async fn restore_or_create_workspace(app_state: Arc<AppState>, cx: &mut AsyncApp
match connection_options {
Ok(connection_options) => recent_projects::open_ssh_project(
connection_options,
ssh.paths.into_iter().map(PathBuf::from).collect(),
paths.paths().into_iter().map(PathBuf::from).collect(),
app_state,
workspace::OpenOptions::default(),
cx,
@ -1070,7 +1069,7 @@ async fn restore_or_create_workspace(app_state: Arc<AppState>, cx: &mut AsyncApp
pub(crate) async fn restorable_workspace_locations(
cx: &mut AsyncApp,
app_state: &Arc<AppState>,
) -> Option<Vec<SerializedWorkspaceLocation>> {
) -> Option<Vec<(SerializedWorkspaceLocation, PathList)>> {
let mut restore_behavior = cx
.update(|cx| WorkspaceSettings::get(None, cx).restore_on_startup)
.ok()?;