Rename RemoteProject -> DevServerProject (#11301)

Co-Authored-By: Mikayla <mikayla@zed.dev>

In a fit of ill-advisedness I called these things remote projects;
forgetting that remote project is also what we call collaboratively
shared projects.

Release Notes:

- N/A

---------

Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Bennet <bennetbo@gmx.de>
This commit is contained in:
Conrad Irwin 2024-05-02 11:00:08 -06:00 committed by GitHub
parent d61c47d2a9
commit 9bac64a9c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
46 changed files with 834 additions and 771 deletions

34
Cargo.lock generated
View File

@ -2272,6 +2272,7 @@ dependencies = [
"collections", "collections",
"ctor", "ctor",
"dashmap", "dashmap",
"dev_server_projects",
"editor", "editor",
"env_logger", "env_logger",
"envy", "envy",
@ -2301,7 +2302,6 @@ dependencies = [
"prost", "prost",
"rand 0.8.5", "rand 0.8.5",
"release_channel", "release_channel",
"remote_projects",
"reqwest", "reqwest",
"rpc", "rpc",
"rustc-demangle", "rustc-demangle",
@ -2344,6 +2344,7 @@ dependencies = [
"clock", "clock",
"collections", "collections",
"db", "db",
"dev_server_projects",
"editor", "editor",
"emojis", "emojis",
"extensions_ui", "extensions_ui",
@ -2359,7 +2360,6 @@ dependencies = [
"pretty_assertions", "pretty_assertions",
"project", "project",
"recent_projects", "recent_projects",
"remote_projects",
"rich_text", "rich_text",
"rpc", "rpc",
"schemars", "schemars",
@ -3177,6 +3177,18 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "dev_server_projects"
version = "0.1.0"
dependencies = [
"anyhow",
"client",
"gpui",
"rpc",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "diagnostics" name = "diagnostics"
version = "0.1.0" version = "0.1.0"
@ -7793,6 +7805,7 @@ name = "recent_projects"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dev_server_projects",
"editor", "editor",
"feature_flags", "feature_flags",
"fuzzy", "fuzzy",
@ -7802,7 +7815,6 @@ dependencies = [
"ordered-float 2.10.0", "ordered-float 2.10.0",
"picker", "picker",
"project", "project",
"remote_projects",
"rpc", "rpc",
"serde", "serde",
"serde_json", "serde_json",
@ -7937,18 +7949,6 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "remote_projects"
version = "0.1.0"
dependencies = [
"anyhow",
"client",
"gpui",
"rpc",
"serde",
"serde_json",
]
[[package]] [[package]]
name = "rend" name = "rend"
version = "0.4.0" version = "0.4.0"
@ -12407,6 +12407,7 @@ dependencies = [
"collections", "collections",
"db", "db",
"derive_more", "derive_more",
"dev_server_projects",
"env_logger", "env_logger",
"fs", "fs",
"futures 0.3.28", "futures 0.3.28",
@ -12419,7 +12420,6 @@ dependencies = [
"parking_lot", "parking_lot",
"postage", "postage",
"project", "project",
"remote_projects",
"schemars", "schemars",
"serde", "serde",
"serde_json", "serde_json",
@ -12682,6 +12682,7 @@ dependencies = [
"copilot", "copilot",
"copilot_ui", "copilot_ui",
"db", "db",
"dev_server_projects",
"diagnostics", "diagnostics",
"editor", "editor",
"env_logger", "env_logger",
@ -12719,7 +12720,6 @@ dependencies = [
"quick_action_bar", "quick_action_bar",
"recent_projects", "recent_projects",
"release_channel", "release_channel",
"remote_projects",
"rope", "rope",
"search", "search",
"serde", "serde",

View File

@ -69,7 +69,7 @@ members = [
"crates/refineable", "crates/refineable",
"crates/refineable/derive_refineable", "crates/refineable/derive_refineable",
"crates/release_channel", "crates/release_channel",
"crates/remote_projects", "crates/dev_server_projects",
"crates/rich_text", "crates/rich_text",
"crates/rope", "crates/rope",
"crates/rpc", "crates/rpc",
@ -207,7 +207,7 @@ project_symbols = { path = "crates/project_symbols" }
quick_action_bar = { path = "crates/quick_action_bar" } quick_action_bar = { path = "crates/quick_action_bar" }
recent_projects = { path = "crates/recent_projects" } recent_projects = { path = "crates/recent_projects" }
release_channel = { path = "crates/release_channel" } release_channel = { path = "crates/release_channel" }
remote_projects = { path = "crates/remote_projects" } dev_server_projects = { path = "crates/dev_server_projects" }
rich_text = { path = "crates/rich_text" } rich_text = { path = "crates/rich_text" }
rope = { path = "crates/rope" } rope = { path = "crates/rope" }
rpc = { path = "crates/rpc" } rpc = { path = "crates/rpc" }

View File

@ -1203,11 +1203,12 @@ impl Room {
project: Model<Project>, project: Model<Project>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Task<Result<u64>> { ) -> Task<Result<u64>> {
let request = if let Some(remote_project_id) = project.read(cx).remote_project_id() { let request = if let Some(dev_server_project_id) = project.read(cx).dev_server_project_id()
{
self.client.request(proto::ShareProject { self.client.request(proto::ShareProject {
room_id: self.id(), room_id: self.id(),
worktrees: vec![], worktrees: vec![],
remote_project_id: Some(remote_project_id.0), dev_server_project_id: Some(dev_server_project_id.0),
}) })
} else { } else {
if let Some(project_id) = project.read(cx).remote_id() { if let Some(project_id) = project.read(cx).remote_id() {
@ -1217,7 +1218,7 @@ impl Room {
self.client.request(proto::ShareProject { self.client.request(proto::ShareProject {
room_id: self.id(), room_id: self.id(),
worktrees: project.read(cx).worktree_metadata_protos(cx), worktrees: project.read(cx).worktree_metadata_protos(cx),
remote_project_id: None, dev_server_project_id: None,
}) })
}; };

View File

@ -33,7 +33,7 @@ pub struct DevServerId(pub u64);
#[derive( #[derive(
Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, serde::Serialize, serde::Deserialize,
)] )]
pub struct RemoteProjectId(pub u64); pub struct DevServerProjectId(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParticipantIndex(pub u32); pub struct ParticipantIndex(pub u32);

View File

@ -93,7 +93,7 @@ notifications = { workspace = true, features = ["test-support"] }
pretty_assertions.workspace = true pretty_assertions.workspace = true
project = { workspace = true, features = ["test-support"] } project = { workspace = true, features = ["test-support"] }
release_channel.workspace = true release_channel.workspace = true
remote_projects.workspace = true dev_server_projects.workspace = true
rpc = { workspace = true, features = ["test-support"] } rpc = { workspace = true, features = ["test-support"] }
sea-orm = { version = "0.12.x", features = ["sqlx-sqlite"] } sea-orm = { version = "0.12.x", features = ["sqlx-sqlite"] }
serde_json.workspace = true serde_json.workspace = true

View File

@ -51,7 +51,7 @@ CREATE TABLE "projects" (
"host_connection_server_id" INTEGER REFERENCES servers (id) ON DELETE CASCADE, "host_connection_server_id" INTEGER REFERENCES servers (id) ON DELETE CASCADE,
"unregistered" BOOLEAN NOT NULL DEFAULT FALSE, "unregistered" BOOLEAN NOT NULL DEFAULT FALSE,
"hosted_project_id" INTEGER REFERENCES hosted_projects (id), "hosted_project_id" INTEGER REFERENCES hosted_projects (id),
"remote_project_id" INTEGER REFERENCES remote_projects(id) "dev_server_project_id" INTEGER REFERENCES dev_server_projects(id)
); );
CREATE INDEX "index_projects_on_host_connection_server_id" ON "projects" ("host_connection_server_id"); CREATE INDEX "index_projects_on_host_connection_server_id" ON "projects" ("host_connection_server_id");
CREATE INDEX "index_projects_on_host_connection_id_and_host_connection_server_id" ON "projects" ("host_connection_id", "host_connection_server_id"); CREATE INDEX "index_projects_on_host_connection_id_and_host_connection_server_id" ON "projects" ("host_connection_id", "host_connection_server_id");
@ -410,10 +410,8 @@ CREATE TABLE dev_servers (
hashed_token TEXT NOT NULL hashed_token TEXT NOT NULL
); );
CREATE TABLE remote_projects ( CREATE TABLE dev_server_projects (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
dev_server_id INTEGER NOT NULL REFERENCES dev_servers(id), dev_server_id INTEGER NOT NULL REFERENCES dev_servers(id),
path TEXT NOT NULL path TEXT NOT NULL
); );
ALTER TABLE hosted_projects ADD COLUMN remote_project_id INTEGER REFERENCES remote_projects(id);

View File

@ -0,0 +1,11 @@
CREATE TABLE dev_server_projects (
id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 100),
dev_server_id INT NOT NULL REFERENCES dev_servers(id) ON DELETE CASCADE,
path TEXT NOT NULL
);
INSERT INTO dev_server_projects OVERRIDING SYSTEM VALUE SELECT * FROM remote_projects;
ALTER TABLE dev_server_projects ADD CONSTRAINT uix_dev_server_projects_dev_server_id_path UNIQUE(dev_server_id, path);
ALTER TABLE projects ADD COLUMN dev_server_project_id INTEGER REFERENCES dev_server_projects(id);
UPDATE projects SET dev_server_project_id = remote_project_id;

View File

@ -762,7 +762,7 @@ pub struct Project {
pub collaborators: Vec<ProjectCollaborator>, pub collaborators: Vec<ProjectCollaborator>,
pub worktrees: BTreeMap<u64, Worktree>, pub worktrees: BTreeMap<u64, Worktree>,
pub language_servers: Vec<proto::LanguageServer>, pub language_servers: Vec<proto::LanguageServer>,
pub remote_project_id: Option<RemoteProjectId>, pub dev_server_project_id: Option<DevServerProjectId>,
} }
pub struct ProjectCollaborator { pub struct ProjectCollaborator {

View File

@ -84,7 +84,7 @@ id_type!(NotificationId);
id_type!(NotificationKindId); id_type!(NotificationKindId);
id_type!(ProjectCollaboratorId); id_type!(ProjectCollaboratorId);
id_type!(ProjectId); id_type!(ProjectId);
id_type!(RemoteProjectId); id_type!(DevServerProjectId);
id_type!(ReplicaId); id_type!(ReplicaId);
id_type!(RoomId); id_type!(RoomId);
id_type!(RoomParticipantId); id_type!(RoomParticipantId);

View File

@ -5,6 +5,7 @@ pub mod buffers;
pub mod channels; pub mod channels;
pub mod contacts; pub mod contacts;
pub mod contributors; pub mod contributors;
pub mod dev_server_projects;
pub mod dev_servers; pub mod dev_servers;
pub mod embeddings; pub mod embeddings;
pub mod extensions; pub mod extensions;
@ -13,7 +14,6 @@ pub mod messages;
pub mod notifications; pub mod notifications;
pub mod projects; pub mod projects;
pub mod rate_buckets; pub mod rate_buckets;
pub mod remote_projects;
pub mod rooms; pub mod rooms;
pub mod servers; pub mod servers;
pub mod users; pub mod users;

View File

@ -0,0 +1,295 @@
use anyhow::anyhow;
use rpc::{proto, ConnectionId};
use sea_orm::{
ActiveModelTrait, ActiveValue, ColumnTrait, Condition, DatabaseTransaction, EntityTrait,
ModelTrait, QueryFilter,
};
use crate::db::ProjectId;
use super::{
dev_server, dev_server_project, project, project_collaborator, worktree, Database, DevServerId,
DevServerProjectId, RejoinedProject, ResharedProject, ServerId, UserId,
};
impl Database {
pub async fn get_dev_server_project(
&self,
dev_server_project_id: DevServerProjectId,
) -> crate::Result<dev_server_project::Model> {
self.transaction(|tx| async move {
Ok(
dev_server_project::Entity::find_by_id(dev_server_project_id)
.one(&*tx)
.await?
.ok_or_else(|| {
anyhow!("no dev server project with id {}", dev_server_project_id)
})?,
)
})
.await
}
pub async fn get_projects_for_dev_server(
&self,
dev_server_id: DevServerId,
) -> crate::Result<Vec<proto::DevServerProject>> {
self.transaction(|tx| async move {
let servers = dev_server_project::Entity::find()
.filter(dev_server_project::Column::DevServerId.eq(dev_server_id))
.find_also_related(project::Entity)
.all(&*tx)
.await?;
Ok(servers
.into_iter()
.map(|(dev_server_project, project)| proto::DevServerProject {
id: dev_server_project.id.to_proto(),
project_id: project.map(|p| p.id.to_proto()),
dev_server_id: dev_server_project.dev_server_id.to_proto(),
path: dev_server_project.path,
})
.collect())
})
.await
}
pub async fn dev_server_project_ids_for_user(
&self,
user_id: UserId,
tx: &DatabaseTransaction,
) -> crate::Result<Vec<DevServerProjectId>> {
let dev_servers = dev_server::Entity::find()
.filter(dev_server::Column::UserId.eq(user_id))
.find_with_related(dev_server_project::Entity)
.all(tx)
.await?;
Ok(dev_servers
.into_iter()
.flat_map(|(_, projects)| projects.into_iter().map(|p| p.id))
.collect())
}
pub async fn owner_for_dev_server_project(
&self,
dev_server_project_id: DevServerProjectId,
tx: &DatabaseTransaction,
) -> crate::Result<UserId> {
let dev_server = dev_server_project::Entity::find_by_id(dev_server_project_id)
.find_also_related(dev_server::Entity)
.one(tx)
.await?
.and_then(|(_, dev_server)| dev_server)
.ok_or_else(|| anyhow!("no dev server project"))?;
Ok(dev_server.user_id)
}
pub async fn get_stale_dev_server_projects(
&self,
connection: ConnectionId,
) -> crate::Result<Vec<ProjectId>> {
self.transaction(|tx| async move {
let projects = project::Entity::find()
.filter(
Condition::all()
.add(project::Column::HostConnectionId.eq(connection.id))
.add(project::Column::HostConnectionServerId.eq(connection.owner_id)),
)
.all(&*tx)
.await?;
Ok(projects.into_iter().map(|p| p.id).collect())
})
.await
}
pub async fn create_dev_server_project(
&self,
dev_server_id: DevServerId,
path: &str,
user_id: UserId,
) -> crate::Result<(dev_server_project::Model, proto::DevServerProjectsUpdate)> {
self.transaction(|tx| async move {
let dev_server = dev_server::Entity::find_by_id(dev_server_id)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("no dev server with id {}", dev_server_id))?;
if dev_server.user_id != user_id {
return Err(anyhow!("not your dev server"))?;
}
let project = dev_server_project::Entity::insert(dev_server_project::ActiveModel {
id: ActiveValue::NotSet,
dev_server_id: ActiveValue::Set(dev_server_id),
path: ActiveValue::Set(path.to_string()),
})
.exec_with_returning(&*tx)
.await?;
let status = self
.dev_server_projects_update_internal(user_id, &tx)
.await?;
Ok((project, status))
})
.await
}
pub async fn share_dev_server_project(
&self,
dev_server_project_id: DevServerProjectId,
dev_server_id: DevServerId,
connection: ConnectionId,
worktrees: &[proto::WorktreeMetadata],
) -> crate::Result<(
proto::DevServerProject,
UserId,
proto::DevServerProjectsUpdate,
)> {
self.transaction(|tx| async move {
let dev_server = dev_server::Entity::find_by_id(dev_server_id)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("no dev server with id {}", dev_server_id))?;
let dev_server_project = dev_server_project::Entity::find_by_id(dev_server_project_id)
.one(&*tx)
.await?
.ok_or_else(|| {
anyhow!("no dev server project with id {}", dev_server_project_id)
})?;
if dev_server_project.dev_server_id != dev_server_id {
return Err(anyhow!("dev server project shared from wrong server"))?;
}
let project = project::ActiveModel {
room_id: ActiveValue::Set(None),
host_user_id: ActiveValue::Set(None),
host_connection_id: ActiveValue::set(Some(connection.id as i32)),
host_connection_server_id: ActiveValue::set(Some(ServerId(
connection.owner_id as i32,
))),
id: ActiveValue::NotSet,
hosted_project_id: ActiveValue::Set(None),
dev_server_project_id: ActiveValue::Set(Some(dev_server_project_id)),
}
.insert(&*tx)
.await?;
if !worktrees.is_empty() {
worktree::Entity::insert_many(worktrees.iter().map(|worktree| {
worktree::ActiveModel {
id: ActiveValue::set(worktree.id as i64),
project_id: ActiveValue::set(project.id),
abs_path: ActiveValue::set(worktree.abs_path.clone()),
root_name: ActiveValue::set(worktree.root_name.clone()),
visible: ActiveValue::set(worktree.visible),
scan_id: ActiveValue::set(0),
completed_scan_id: ActiveValue::set(0),
}
}))
.exec(&*tx)
.await?;
}
let status = self
.dev_server_projects_update_internal(dev_server.user_id, &tx)
.await?;
Ok((
dev_server_project.to_proto(Some(project)),
dev_server.user_id,
status,
))
})
.await
}
pub async fn reshare_dev_server_projects(
&self,
reshared_projects: &Vec<proto::UpdateProject>,
dev_server_id: DevServerId,
connection: ConnectionId,
) -> crate::Result<Vec<ResharedProject>> {
// todo!() project_transaction? (maybe we can make the lock per-dev-server instead of per-project?)
self.transaction(|tx| async move {
let mut ret = Vec::new();
for reshared_project in reshared_projects {
let project_id = ProjectId::from_proto(reshared_project.project_id);
let (project, dev_server_project) = project::Entity::find_by_id(project_id)
.find_also_related(dev_server_project::Entity)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("project does not exist"))?;
if dev_server_project.map(|rp| rp.dev_server_id) != Some(dev_server_id) {
return Err(anyhow!("dev server project reshared from wrong server"))?;
}
let Ok(old_connection_id) = project.host_connection() else {
return Err(anyhow!("dev server project was not shared"))?;
};
project::Entity::update(project::ActiveModel {
id: ActiveValue::set(project_id),
host_connection_id: ActiveValue::set(Some(connection.id as i32)),
host_connection_server_id: ActiveValue::set(Some(ServerId(
connection.owner_id as i32,
))),
..Default::default()
})
.exec(&*tx)
.await?;
let collaborators = project
.find_related(project_collaborator::Entity)
.all(&*tx)
.await?;
self.update_project_worktrees(project_id, &reshared_project.worktrees, &tx)
.await?;
ret.push(super::ResharedProject {
id: project_id,
old_connection_id,
collaborators: collaborators
.iter()
.map(|collaborator| super::ProjectCollaborator {
connection_id: collaborator.connection(),
user_id: collaborator.user_id,
replica_id: collaborator.replica_id,
is_host: collaborator.is_host,
})
.collect(),
worktrees: reshared_project.worktrees.clone(),
});
}
Ok(ret)
})
.await
}
pub async fn rejoin_dev_server_projects(
&self,
rejoined_projects: &Vec<proto::RejoinProject>,
user_id: UserId,
connection_id: ConnectionId,
) -> crate::Result<Vec<RejoinedProject>> {
// todo!() project_transaction? (maybe we can make the lock per-dev-server instead of per-project?)
self.transaction(|tx| async move {
let mut ret = Vec::new();
for rejoined_project in rejoined_projects {
if let Some(project) = self
.rejoin_project_internal(&tx, rejoined_project, user_id, connection_id)
.await?
{
ret.push(project);
}
}
Ok(ret)
})
.await
}
}

View File

@ -3,7 +3,7 @@ use sea_orm::{
ActiveValue, ColumnTrait, DatabaseTransaction, EntityTrait, IntoActiveModel, QueryFilter, ActiveValue, ColumnTrait, DatabaseTransaction, EntityTrait, IntoActiveModel, QueryFilter,
}; };
use super::{dev_server, remote_project, Database, DevServerId, UserId}; use super::{dev_server, dev_server_project, Database, DevServerId, UserId};
impl Database { impl Database {
pub async fn get_dev_server( pub async fn get_dev_server(
@ -29,43 +29,43 @@ impl Database {
.await .await
} }
pub async fn remote_projects_update( pub async fn dev_server_projects_update(
&self, &self,
user_id: UserId, user_id: UserId,
) -> crate::Result<proto::RemoteProjectsUpdate> { ) -> crate::Result<proto::DevServerProjectsUpdate> {
self.transaction( self.transaction(|tx| async move {
|tx| async move { self.remote_projects_update_internal(user_id, &tx).await }, self.dev_server_projects_update_internal(user_id, &tx).await
) })
.await .await
} }
pub async fn remote_projects_update_internal( pub async fn dev_server_projects_update_internal(
&self, &self,
user_id: UserId, user_id: UserId,
tx: &DatabaseTransaction, tx: &DatabaseTransaction,
) -> crate::Result<proto::RemoteProjectsUpdate> { ) -> crate::Result<proto::DevServerProjectsUpdate> {
let dev_servers = dev_server::Entity::find() let dev_servers = dev_server::Entity::find()
.filter(dev_server::Column::UserId.eq(user_id)) .filter(dev_server::Column::UserId.eq(user_id))
.all(tx) .all(tx)
.await?; .await?;
let remote_projects = remote_project::Entity::find() let dev_server_projects = dev_server_project::Entity::find()
.filter( .filter(
remote_project::Column::DevServerId dev_server_project::Column::DevServerId
.is_in(dev_servers.iter().map(|d| d.id).collect::<Vec<_>>()), .is_in(dev_servers.iter().map(|d| d.id).collect::<Vec<_>>()),
) )
.find_also_related(super::project::Entity) .find_also_related(super::project::Entity)
.all(tx) .all(tx)
.await?; .await?;
Ok(proto::RemoteProjectsUpdate { Ok(proto::DevServerProjectsUpdate {
dev_servers: dev_servers dev_servers: dev_servers
.into_iter() .into_iter()
.map(|d| d.to_proto(proto::DevServerStatus::Offline)) .map(|d| d.to_proto(proto::DevServerStatus::Offline))
.collect(), .collect(),
remote_projects: remote_projects dev_server_projects: dev_server_projects
.into_iter() .into_iter()
.map(|(remote_project, project)| remote_project.to_proto(project)) .map(|(dev_server_project, project)| dev_server_project.to_proto(project))
.collect(), .collect(),
}) })
} }
@ -75,7 +75,7 @@ impl Database {
name: &str, name: &str,
hashed_access_token: &str, hashed_access_token: &str,
user_id: UserId, user_id: UserId,
) -> crate::Result<(dev_server::Model, proto::RemoteProjectsUpdate)> { ) -> crate::Result<(dev_server::Model, proto::DevServerProjectsUpdate)> {
self.transaction(|tx| async move { self.transaction(|tx| async move {
let dev_server = dev_server::Entity::insert(dev_server::ActiveModel { let dev_server = dev_server::Entity::insert(dev_server::ActiveModel {
id: ActiveValue::NotSet, id: ActiveValue::NotSet,
@ -86,9 +86,11 @@ impl Database {
.exec_with_returning(&*tx) .exec_with_returning(&*tx)
.await?; .await?;
let remote_projects = self.remote_projects_update_internal(user_id, &tx).await?; let dev_server_projects = self
.dev_server_projects_update_internal(user_id, &tx)
.await?;
Ok((dev_server, remote_projects)) Ok((dev_server, dev_server_projects))
}) })
.await .await
} }
@ -97,7 +99,7 @@ impl Database {
&self, &self,
id: DevServerId, id: DevServerId,
user_id: UserId, user_id: UserId,
) -> crate::Result<proto::RemoteProjectsUpdate> { ) -> crate::Result<proto::DevServerProjectsUpdate> {
self.transaction(|tx| async move { self.transaction(|tx| async move {
let Some(dev_server) = dev_server::Entity::find_by_id(id).one(&*tx).await? else { let Some(dev_server) = dev_server::Entity::find_by_id(id).one(&*tx).await? else {
return Err(anyhow::anyhow!("no dev server with id {}", id))?; return Err(anyhow::anyhow!("no dev server with id {}", id))?;
@ -106,8 +108,8 @@ impl Database {
return Err(anyhow::anyhow!(proto::ErrorCode::Forbidden))?; return Err(anyhow::anyhow!(proto::ErrorCode::Forbidden))?;
} }
remote_project::Entity::delete_many() dev_server_project::Entity::delete_many()
.filter(remote_project::Column::DevServerId.eq(id)) .filter(dev_server_project::Column::DevServerId.eq(id))
.exec(&*tx) .exec(&*tx)
.await?; .await?;
@ -115,9 +117,11 @@ impl Database {
.exec(&*tx) .exec(&*tx)
.await?; .await?;
let remote_projects = self.remote_projects_update_internal(user_id, &tx).await?; let dev_server_projects = self
.dev_server_projects_update_internal(user_id, &tx)
.await?;
Ok(remote_projects) Ok(dev_server_projects)
}) })
.await .await
} }

View File

@ -30,7 +30,7 @@ impl Database {
room_id: RoomId, room_id: RoomId,
connection: ConnectionId, connection: ConnectionId,
worktrees: &[proto::WorktreeMetadata], worktrees: &[proto::WorktreeMetadata],
remote_project_id: Option<RemoteProjectId>, dev_server_project_id: Option<DevServerProjectId>,
) -> Result<TransactionGuard<(ProjectId, proto::Room)>> { ) -> Result<TransactionGuard<(ProjectId, proto::Room)>> {
self.room_transaction(room_id, |tx| async move { self.room_transaction(room_id, |tx| async move {
let participant = room_participant::Entity::find() let participant = room_participant::Entity::find()
@ -59,9 +59,9 @@ impl Database {
return Err(anyhow!("guests cannot share projects"))?; return Err(anyhow!("guests cannot share projects"))?;
} }
if let Some(remote_project_id) = remote_project_id { if let Some(dev_server_project_id) = dev_server_project_id {
let project = project::Entity::find() let project = project::Entity::find()
.filter(project::Column::RemoteProjectId.eq(Some(remote_project_id))) .filter(project::Column::DevServerProjectId.eq(Some(dev_server_project_id)))
.one(&*tx) .one(&*tx)
.await? .await?
.ok_or_else(|| anyhow!("no remote project"))?; .ok_or_else(|| anyhow!("no remote project"))?;
@ -92,7 +92,7 @@ impl Database {
))), ))),
id: ActiveValue::NotSet, id: ActiveValue::NotSet,
hosted_project_id: ActiveValue::Set(None), hosted_project_id: ActiveValue::Set(None),
remote_project_id: ActiveValue::Set(None), dev_server_project_id: ActiveValue::Set(None),
} }
.insert(&*tx) .insert(&*tx)
.await?; .await?;
@ -155,11 +155,11 @@ impl Database {
.await?; .await?;
return Ok((room, guest_connection_ids)); return Ok((room, guest_connection_ids));
} }
if let Some(remote_project_id) = project.remote_project_id { if let Some(dev_server_project_id) = project.dev_server_project_id {
if let Some(user_id) = user_id { if let Some(user_id) = user_id {
if user_id if user_id
!= self != self
.owner_for_remote_project(remote_project_id, &tx) .owner_for_dev_server_project(dev_server_project_id, &tx)
.await? .await?
{ {
Err(anyhow!("cannot unshare a project hosted by another user"))? Err(anyhow!("cannot unshare a project hosted by another user"))?
@ -797,7 +797,7 @@ impl Database {
name: language_server.name, name: language_server.name,
}) })
.collect(), .collect(),
remote_project_id: project.remote_project_id, dev_server_project_id: project.dev_server_project_id,
}; };
Ok((project, replica_id as ReplicaId)) Ok((project, replica_id as ReplicaId))
} }
@ -957,8 +957,8 @@ impl Database {
capability: Capability, capability: Capability,
tx: &DatabaseTransaction, tx: &DatabaseTransaction,
) -> Result<(project::Model, ChannelRole)> { ) -> Result<(project::Model, ChannelRole)> {
let (mut project, remote_project) = project::Entity::find_by_id(project_id) let (mut project, dev_server_project) = project::Entity::find_by_id(project_id)
.find_also_related(remote_project::Entity) .find_also_related(dev_server_project::Entity)
.one(tx) .one(tx)
.await? .await?
.ok_or_else(|| anyhow!("no such project"))?; .ok_or_else(|| anyhow!("no such project"))?;
@ -986,8 +986,8 @@ impl Database {
} else { } else {
None None
}; };
let role_from_remote_project = if let Some(remote_project) = remote_project { let role_from_dev_server = if let Some(dev_server_project) = dev_server_project {
let dev_server = dev_server::Entity::find_by_id(remote_project.dev_server_id) let dev_server = dev_server::Entity::find_by_id(dev_server_project.dev_server_id)
.one(tx) .one(tx)
.await? .await?
.ok_or_else(|| anyhow!("no such channel"))?; .ok_or_else(|| anyhow!("no such channel"))?;
@ -1011,7 +1011,7 @@ impl Database {
None None
}; };
let role = role_from_remote_project let role = role_from_dev_server
.or(role_from_room) .or(role_from_room)
.unwrap_or(ChannelRole::Banned); .unwrap_or(ChannelRole::Banned);

View File

@ -1,283 +1 @@
use anyhow::anyhow;
use rpc::{proto, ConnectionId};
use sea_orm::{
ActiveModelTrait, ActiveValue, ColumnTrait, Condition, DatabaseTransaction, EntityTrait,
ModelTrait, QueryFilter,
};
use crate::db::ProjectId;
use super::{
dev_server, project, project_collaborator, remote_project, worktree, Database, DevServerId,
RejoinedProject, RemoteProjectId, ResharedProject, ServerId, UserId,
};
impl Database {
pub async fn get_remote_project(
&self,
remote_project_id: RemoteProjectId,
) -> crate::Result<remote_project::Model> {
self.transaction(|tx| async move {
Ok(remote_project::Entity::find_by_id(remote_project_id)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("no remote project with id {}", remote_project_id))?)
})
.await
}
pub async fn get_remote_projects_for_dev_server(
&self,
dev_server_id: DevServerId,
) -> crate::Result<Vec<proto::RemoteProject>> {
self.transaction(|tx| async move {
let servers = remote_project::Entity::find()
.filter(remote_project::Column::DevServerId.eq(dev_server_id))
.find_also_related(project::Entity)
.all(&*tx)
.await?;
Ok(servers
.into_iter()
.map(|(remote_project, project)| proto::RemoteProject {
id: remote_project.id.to_proto(),
project_id: project.map(|p| p.id.to_proto()),
dev_server_id: remote_project.dev_server_id.to_proto(),
path: remote_project.path,
})
.collect())
})
.await
}
pub async fn remote_project_ids_for_user(
&self,
user_id: UserId,
tx: &DatabaseTransaction,
) -> crate::Result<Vec<RemoteProjectId>> {
let dev_servers = dev_server::Entity::find()
.filter(dev_server::Column::UserId.eq(user_id))
.find_with_related(remote_project::Entity)
.all(tx)
.await?;
Ok(dev_servers
.into_iter()
.flat_map(|(_, projects)| projects.into_iter().map(|p| p.id))
.collect())
}
pub async fn owner_for_remote_project(
&self,
remote_project_id: RemoteProjectId,
tx: &DatabaseTransaction,
) -> crate::Result<UserId> {
let dev_server = remote_project::Entity::find_by_id(remote_project_id)
.find_also_related(dev_server::Entity)
.one(tx)
.await?
.and_then(|(_, dev_server)| dev_server)
.ok_or_else(|| anyhow!("no remote project"))?;
Ok(dev_server.user_id)
}
pub async fn get_stale_dev_server_projects(
&self,
connection: ConnectionId,
) -> crate::Result<Vec<ProjectId>> {
self.transaction(|tx| async move {
let projects = project::Entity::find()
.filter(
Condition::all()
.add(project::Column::HostConnectionId.eq(connection.id))
.add(project::Column::HostConnectionServerId.eq(connection.owner_id)),
)
.all(&*tx)
.await?;
Ok(projects.into_iter().map(|p| p.id).collect())
})
.await
}
pub async fn create_remote_project(
&self,
dev_server_id: DevServerId,
path: &str,
user_id: UserId,
) -> crate::Result<(remote_project::Model, proto::RemoteProjectsUpdate)> {
self.transaction(|tx| async move {
let dev_server = dev_server::Entity::find_by_id(dev_server_id)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("no dev server with id {}", dev_server_id))?;
if dev_server.user_id != user_id {
return Err(anyhow!("not your dev server"))?;
}
let project = remote_project::Entity::insert(remote_project::ActiveModel {
id: ActiveValue::NotSet,
dev_server_id: ActiveValue::Set(dev_server_id),
path: ActiveValue::Set(path.to_string()),
})
.exec_with_returning(&*tx)
.await?;
let status = self.remote_projects_update_internal(user_id, &tx).await?;
Ok((project, status))
})
.await
}
pub async fn share_remote_project(
&self,
remote_project_id: RemoteProjectId,
dev_server_id: DevServerId,
connection: ConnectionId,
worktrees: &[proto::WorktreeMetadata],
) -> crate::Result<(proto::RemoteProject, UserId, proto::RemoteProjectsUpdate)> {
self.transaction(|tx| async move {
let dev_server = dev_server::Entity::find_by_id(dev_server_id)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("no dev server with id {}", dev_server_id))?;
let remote_project = remote_project::Entity::find_by_id(remote_project_id)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("no remote project with id {}", remote_project_id))?;
if remote_project.dev_server_id != dev_server_id {
return Err(anyhow!("remote project shared from wrong server"))?;
}
let project = project::ActiveModel {
room_id: ActiveValue::Set(None),
host_user_id: ActiveValue::Set(None),
host_connection_id: ActiveValue::set(Some(connection.id as i32)),
host_connection_server_id: ActiveValue::set(Some(ServerId(
connection.owner_id as i32,
))),
id: ActiveValue::NotSet,
hosted_project_id: ActiveValue::Set(None),
remote_project_id: ActiveValue::Set(Some(remote_project_id)),
}
.insert(&*tx)
.await?;
if !worktrees.is_empty() {
worktree::Entity::insert_many(worktrees.iter().map(|worktree| {
worktree::ActiveModel {
id: ActiveValue::set(worktree.id as i64),
project_id: ActiveValue::set(project.id),
abs_path: ActiveValue::set(worktree.abs_path.clone()),
root_name: ActiveValue::set(worktree.root_name.clone()),
visible: ActiveValue::set(worktree.visible),
scan_id: ActiveValue::set(0),
completed_scan_id: ActiveValue::set(0),
}
}))
.exec(&*tx)
.await?;
}
let status = self
.remote_projects_update_internal(dev_server.user_id, &tx)
.await?;
Ok((
remote_project.to_proto(Some(project)),
dev_server.user_id,
status,
))
})
.await
}
pub async fn reshare_remote_projects(
&self,
reshared_projects: &Vec<proto::UpdateProject>,
dev_server_id: DevServerId,
connection: ConnectionId,
) -> crate::Result<Vec<ResharedProject>> {
// todo!() project_transaction? (maybe we can make the lock per-dev-server instead of per-project?)
self.transaction(|tx| async move {
let mut ret = Vec::new();
for reshared_project in reshared_projects {
let project_id = ProjectId::from_proto(reshared_project.project_id);
let (project, remote_project) = project::Entity::find_by_id(project_id)
.find_also_related(remote_project::Entity)
.one(&*tx)
.await?
.ok_or_else(|| anyhow!("project does not exist"))?;
if remote_project.map(|rp| rp.dev_server_id) != Some(dev_server_id) {
return Err(anyhow!("remote project reshared from wrong server"))?;
}
let Ok(old_connection_id) = project.host_connection() else {
return Err(anyhow!("remote project was not shared"))?;
};
project::Entity::update(project::ActiveModel {
id: ActiveValue::set(project_id),
host_connection_id: ActiveValue::set(Some(connection.id as i32)),
host_connection_server_id: ActiveValue::set(Some(ServerId(
connection.owner_id as i32,
))),
..Default::default()
})
.exec(&*tx)
.await?;
let collaborators = project
.find_related(project_collaborator::Entity)
.all(&*tx)
.await?;
self.update_project_worktrees(project_id, &reshared_project.worktrees, &tx)
.await?;
ret.push(super::ResharedProject {
id: project_id,
old_connection_id,
collaborators: collaborators
.iter()
.map(|collaborator| super::ProjectCollaborator {
connection_id: collaborator.connection(),
user_id: collaborator.user_id,
replica_id: collaborator.replica_id,
is_host: collaborator.is_host,
})
.collect(),
worktrees: reshared_project.worktrees.clone(),
});
}
Ok(ret)
})
.await
}
pub async fn rejoin_remote_projects(
&self,
rejoined_projects: &Vec<proto::RejoinProject>,
user_id: UserId,
connection_id: ConnectionId,
) -> crate::Result<Vec<RejoinedProject>> {
// todo!() project_transaction? (maybe we can make the lock per-dev-server instead of per-project?)
self.transaction(|tx| async move {
let mut ret = Vec::new();
for rejoined_project in rejoined_projects {
if let Some(project) = self
.rejoin_project_internal(&tx, rejoined_project, user_id, connection_id)
.await?
{
ret.push(project);
}
}
Ok(ret)
})
.await
}
}

View File

@ -851,17 +851,17 @@ impl Database {
.await?; .await?;
// if any project in the room has a remote-project-id that belongs to a dev server that this user owns. // if any project in the room has a remote-project-id that belongs to a dev server that this user owns.
let remote_projects_for_user = self let dev_server_projects_for_user = self
.remote_project_ids_for_user(leaving_participant.user_id, &tx) .dev_server_project_ids_for_user(leaving_participant.user_id, &tx)
.await?; .await?;
let remote_projects_to_unshare = project::Entity::find() let dev_server_projects_to_unshare = project::Entity::find()
.filter( .filter(
Condition::all() Condition::all()
.add(project::Column::RoomId.eq(room_id)) .add(project::Column::RoomId.eq(room_id))
.add( .add(
project::Column::RemoteProjectId project::Column::DevServerProjectId
.is_in(remote_projects_for_user.clone()), .is_in(dev_server_projects_for_user.clone()),
), ),
) )
.all(&*tx) .all(&*tx)
@ -892,7 +892,7 @@ impl Database {
} }
if (collaborator.is_host && collaborator.connection() == connection) if (collaborator.is_host && collaborator.connection() == connection)
|| remote_projects_to_unshare.contains(&collaborator.project_id) || dev_server_projects_to_unshare.contains(&collaborator.project_id)
{ {
left_project.should_unshare = true; left_project.should_unshare = true;
} }
@ -936,9 +936,9 @@ impl Database {
.exec(&*tx) .exec(&*tx)
.await?; .await?;
if !remote_projects_to_unshare.is_empty() { if !dev_server_projects_to_unshare.is_empty() {
project::Entity::update_many() project::Entity::update_many()
.filter(project::Column::Id.is_in(remote_projects_to_unshare)) .filter(project::Column::Id.is_in(dev_server_projects_to_unshare))
.set(project::ActiveModel { .set(project::ActiveModel {
room_id: ActiveValue::Set(None), room_id: ActiveValue::Set(None),
..Default::default() ..Default::default()
@ -1316,8 +1316,10 @@ impl Database {
project.worktree_root_names.push(db_worktree.root_name); project.worktree_root_names.push(db_worktree.root_name);
} }
} }
} else if let Some(remote_project_id) = db_project.remote_project_id { } else if let Some(dev_server_project_id) = db_project.dev_server_project_id {
let host = self.owner_for_remote_project(remote_project_id, tx).await?; let host = self
.owner_for_dev_server_project(dev_server_project_id, tx)
.await?;
if let Some((_, participant)) = participants if let Some((_, participant)) = participants
.iter_mut() .iter_mut()
.find(|(_, v)| v.user_id == host.to_proto()) .find(|(_, v)| v.user_id == host.to_proto())

View File

@ -11,6 +11,7 @@ pub mod channel_message_mention;
pub mod contact; pub mod contact;
pub mod contributor; pub mod contributor;
pub mod dev_server; pub mod dev_server;
pub mod dev_server_project;
pub mod embedding; pub mod embedding;
pub mod extension; pub mod extension;
pub mod extension_version; pub mod extension_version;
@ -25,7 +26,6 @@ pub mod observed_channel_messages;
pub mod project; pub mod project;
pub mod project_collaborator; pub mod project_collaborator;
pub mod rate_buckets; pub mod rate_buckets;
pub mod remote_project;
pub mod room; pub mod room;
pub mod room_participant; pub mod room_participant;
pub mod server; pub mod server;

View File

@ -16,11 +16,11 @@ impl ActiveModelBehavior for ActiveModel {}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm(has_many = "super::remote_project::Entity")] #[sea_orm(has_many = "super::dev_server_project::Entity")]
RemoteProject, RemoteProject,
} }
impl Related<super::remote_project::Entity> for Entity { impl Related<super::dev_server_project::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::RemoteProject.def() Relation::RemoteProject.def()
} }

View File

@ -1,13 +1,13 @@
use super::project; use super::project;
use crate::db::{DevServerId, RemoteProjectId}; use crate::db::{DevServerId, DevServerProjectId};
use rpc::proto; use rpc::proto;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
#[sea_orm(table_name = "remote_projects")] #[sea_orm(table_name = "dev_server_projects")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key)] #[sea_orm(primary_key)]
pub id: RemoteProjectId, pub id: DevServerProjectId,
pub dev_server_id: DevServerId, pub dev_server_id: DevServerId,
pub path: String, pub path: String,
} }
@ -39,8 +39,8 @@ impl Related<super::dev_server::Entity> for Entity {
} }
impl Model { impl Model {
pub fn to_proto(&self, project: Option<project::Model>) -> proto::RemoteProject { pub fn to_proto(&self, project: Option<project::Model>) -> proto::DevServerProject {
proto::RemoteProject { proto::DevServerProject {
id: self.id.to_proto(), id: self.id.to_proto(),
project_id: project.map(|p| p.id.to_proto()), project_id: project.map(|p| p.id.to_proto()),
dev_server_id: self.dev_server_id.to_proto(), dev_server_id: self.dev_server_id.to_proto(),

View File

@ -1,4 +1,4 @@
use crate::db::{HostedProjectId, ProjectId, RemoteProjectId, Result, RoomId, ServerId, UserId}; use crate::db::{DevServerProjectId, HostedProjectId, ProjectId, Result, RoomId, ServerId, UserId};
use anyhow::anyhow; use anyhow::anyhow;
use rpc::ConnectionId; use rpc::ConnectionId;
use sea_orm::entity::prelude::*; use sea_orm::entity::prelude::*;
@ -13,7 +13,7 @@ pub struct Model {
pub host_connection_id: Option<i32>, pub host_connection_id: Option<i32>,
pub host_connection_server_id: Option<ServerId>, pub host_connection_server_id: Option<ServerId>,
pub hosted_project_id: Option<HostedProjectId>, pub hosted_project_id: Option<HostedProjectId>,
pub remote_project_id: Option<RemoteProjectId>, pub dev_server_project_id: Option<DevServerProjectId>,
} }
impl Model { impl Model {
@ -58,9 +58,9 @@ pub enum Relation {
)] )]
HostedProject, HostedProject,
#[sea_orm( #[sea_orm(
belongs_to = "super::remote_project::Entity", belongs_to = "super::dev_server_project::Entity",
from = "Column::RemoteProjectId", from = "Column::DevServerProjectId",
to = "super::remote_project::Column::Id" to = "super::dev_server_project::Column::Id"
)] )]
RemoteProject, RemoteProject,
} }
@ -101,7 +101,7 @@ impl Related<super::hosted_project::Entity> for Entity {
} }
} }
impl Related<super::remote_project::Entity> for Entity { impl Related<super::dev_server_project::Entity> for Entity {
fn to() -> RelationDef { fn to() -> RelationDef {
Relation::RemoteProject.def() Relation::RemoteProject.def()
} }

View File

@ -4,9 +4,9 @@ use crate::{
auth, auth,
db::{ db::{
self, dev_server, BufferId, Capability, Channel, ChannelId, ChannelRole, ChannelsForUser, self, dev_server, BufferId, Capability, Channel, ChannelId, ChannelRole, ChannelsForUser,
CreatedChannelMessage, Database, DevServerId, InviteMemberResult, MembershipUpdated, CreatedChannelMessage, Database, DevServerId, DevServerProjectId, InviteMemberResult,
MessageId, NotificationId, PrincipalId, Project, ProjectId, RejoinedProject, MembershipUpdated, MessageId, NotificationId, PrincipalId, Project, ProjectId,
RemoteProjectId, RemoveChannelMemberResult, ReplicaId, RespondToChannelInvite, RoomId, RejoinedProject, RemoveChannelMemberResult, ReplicaId, RespondToChannelInvite, RoomId,
ServerId, UpdatedChannelMessage, User, UserId, ServerId, UpdatedChannelMessage, User, UserId,
}, },
executor::Executor, executor::Executor,
@ -411,11 +411,11 @@ impl Server {
.add_message_handler(unshare_project) .add_message_handler(unshare_project)
.add_request_handler(user_handler(join_project)) .add_request_handler(user_handler(join_project))
.add_request_handler(user_handler(join_hosted_project)) .add_request_handler(user_handler(join_hosted_project))
.add_request_handler(user_handler(rejoin_remote_projects)) .add_request_handler(user_handler(rejoin_dev_server_projects))
.add_request_handler(user_handler(create_remote_project)) .add_request_handler(user_handler(create_dev_server_project))
.add_request_handler(user_handler(create_dev_server)) .add_request_handler(user_handler(create_dev_server))
.add_request_handler(user_handler(delete_dev_server)) .add_request_handler(user_handler(delete_dev_server))
.add_request_handler(dev_server_handler(share_remote_project)) .add_request_handler(dev_server_handler(share_dev_server_project))
.add_request_handler(dev_server_handler(shutdown_dev_server)) .add_request_handler(dev_server_handler(shutdown_dev_server))
.add_request_handler(dev_server_handler(reconnect_dev_server)) .add_request_handler(dev_server_handler(reconnect_dev_server))
.add_message_handler(user_message_handler(leave_project)) .add_message_handler(user_message_handler(leave_project))
@ -1067,12 +1067,12 @@ impl Server {
.await?; .await?;
} }
let (contacts, channels_for_user, channel_invites, remote_projects) = let (contacts, channels_for_user, channel_invites, dev_server_projects) =
future::try_join4( future::try_join4(
self.app_state.db.get_contacts(user.id), self.app_state.db.get_contacts(user.id),
self.app_state.db.get_channels_for_user(user.id), self.app_state.db.get_channels_for_user(user.id),
self.app_state.db.get_channel_invites_for_user(user.id), self.app_state.db.get_channel_invites_for_user(user.id),
self.app_state.db.remote_projects_update(user.id), self.app_state.db.dev_server_projects_update(user.id),
) )
.await?; .await?;
@ -1095,7 +1095,7 @@ impl Server {
build_channels_update(channels_for_user, channel_invites), build_channels_update(channels_for_user, channel_invites),
)?; )?;
} }
send_remote_projects_update(user.id, remote_projects, session).await; send_dev_server_projects_update(user.id, dev_server_projects, session).await;
if let Some(incoming_call) = if let Some(incoming_call) =
self.app_state.db.incoming_call_for_user(user.id).await? self.app_state.db.incoming_call_for_user(user.id).await?
@ -1117,7 +1117,7 @@ impl Server {
let projects = self let projects = self
.app_state .app_state
.db .db
.get_remote_projects_for_dev_server(dev_server.id) .get_projects_for_dev_server(dev_server.id)
.await?; .await?;
self.peer self.peer
.send(connection_id, proto::DevServerInstructions { projects })?; .send(connection_id, proto::DevServerInstructions { projects })?;
@ -1125,9 +1125,9 @@ impl Server {
let status = self let status = self
.app_state .app_state
.db .db
.remote_projects_update(dev_server.user_id) .dev_server_projects_update(dev_server.user_id)
.await?; .await?;
send_remote_projects_update(dev_server.user_id, status, &session).await; send_dev_server_projects_update(dev_server.user_id, status, &session).await;
} }
} }
@ -1970,8 +1970,8 @@ async fn share_project(
session.connection_id, session.connection_id,
&request.worktrees, &request.worktrees,
request request
.remote_project_id .dev_server_project_id
.map(|id| RemoteProjectId::from_proto(id)), .map(|id| DevServerProjectId::from_proto(id)),
) )
.await?; .await?;
response.send(proto::ShareProjectResponse { response.send(proto::ShareProjectResponse {
@ -2023,26 +2023,26 @@ async fn unshare_project_internal(
} }
/// DevServer makes a project available online /// DevServer makes a project available online
async fn share_remote_project( async fn share_dev_server_project(
request: proto::ShareRemoteProject, request: proto::ShareDevServerProject,
response: Response<proto::ShareRemoteProject>, response: Response<proto::ShareDevServerProject>,
session: DevServerSession, session: DevServerSession,
) -> Result<()> { ) -> Result<()> {
let (remote_project, user_id, status) = session let (dev_server_project, user_id, status) = session
.db() .db()
.await .await
.share_remote_project( .share_dev_server_project(
RemoteProjectId::from_proto(request.remote_project_id), DevServerProjectId::from_proto(request.dev_server_project_id),
session.dev_server_id(), session.dev_server_id(),
session.connection_id, session.connection_id,
&request.worktrees, &request.worktrees,
) )
.await?; .await?;
let Some(project_id) = remote_project.project_id else { let Some(project_id) = dev_server_project.project_id else {
return Err(anyhow!("failed to share remote project"))?; return Err(anyhow!("failed to share remote project"))?;
}; };
send_remote_projects_update(user_id, status, &session).await; send_dev_server_projects_update(user_id, status, &session).await;
response.send(proto::ShareProjectResponse { project_id })?; response.send(proto::ShareProjectResponse { project_id })?;
@ -2135,9 +2135,9 @@ fn join_project_internal(
collaborators: collaborators.clone(), collaborators: collaborators.clone(),
language_servers: project.language_servers.clone(), language_servers: project.language_servers.clone(),
role: project.role.into(), role: project.role.into(),
remote_project_id: project dev_server_project_id: project
.remote_project_id .dev_server_project_id
.map(|remote_project_id| remote_project_id.0 as u64), .map(|dev_server_project_id| dev_server_project_id.0 as u64),
})?; })?;
for (worktree_id, worktree) in mem::take(&mut project.worktrees) { for (worktree_id, worktree) in mem::take(&mut project.worktrees) {
@ -2249,9 +2249,9 @@ async fn join_hosted_project(
join_project_internal(response, session, &mut project, &replica_id) join_project_internal(response, session, &mut project, &replica_id)
} }
async fn create_remote_project( async fn create_dev_server_project(
request: proto::CreateRemoteProject, request: proto::CreateDevServerProject,
response: Response<proto::CreateRemoteProject>, response: Response<proto::CreateDevServerProject>,
session: UserSession, session: UserSession,
) -> Result<()> { ) -> Result<()> {
let dev_server_id = DevServerId(request.dev_server_id as i32); let dev_server_id = DevServerId(request.dev_server_id as i32);
@ -2272,14 +2272,14 @@ async fn create_remote_project(
.forward_request( .forward_request(
session.connection_id, session.connection_id,
dev_server_connection_id, dev_server_connection_id,
proto::ValidateRemoteProjectRequest { path: path.clone() }, proto::ValidateDevServerProjectRequest { path: path.clone() },
) )
.await?; .await?;
let (remote_project, update) = session let (dev_server_project, update) = session
.db() .db()
.await .await
.create_remote_project( .create_dev_server_project(
DevServerId(request.dev_server_id as i32), DevServerId(request.dev_server_id as i32),
&request.path, &request.path,
session.user_id(), session.user_id(),
@ -2289,7 +2289,7 @@ async fn create_remote_project(
let projects = session let projects = session
.db() .db()
.await .await
.get_remote_projects_for_dev_server(remote_project.dev_server_id) .get_projects_for_dev_server(dev_server_project.dev_server_id)
.await?; .await?;
session.peer.send( session.peer.send(
@ -2297,10 +2297,10 @@ async fn create_remote_project(
proto::DevServerInstructions { projects }, proto::DevServerInstructions { projects },
)?; )?;
send_remote_projects_update(session.user_id(), update, &session).await; send_dev_server_projects_update(session.user_id(), update, &session).await;
response.send(proto::CreateRemoteProjectResponse { response.send(proto::CreateDevServerProjectResponse {
remote_project: Some(remote_project.to_proto(None)), dev_server_project: Some(dev_server_project.to_proto(None)),
})?; })?;
Ok(()) Ok(())
} }
@ -2319,7 +2319,7 @@ async fn create_dev_server(
.create_dev_server(&request.name, &hashed_access_token, session.user_id()) .create_dev_server(&request.name, &hashed_access_token, session.user_id())
.await?; .await?;
send_remote_projects_update(session.user_id(), status, &session).await; send_dev_server_projects_update(session.user_id(), status, &session).await;
response.send(proto::CreateDevServerResponse { response.send(proto::CreateDevServerResponse {
dev_server_id: dev_server.id.0 as u64, dev_server_id: dev_server.id.0 as u64,
@ -2357,20 +2357,20 @@ async fn delete_dev_server(
.delete_dev_server(dev_server_id, session.user_id()) .delete_dev_server(dev_server_id, session.user_id())
.await?; .await?;
send_remote_projects_update(session.user_id(), status, &session).await; send_dev_server_projects_update(session.user_id(), status, &session).await;
response.send(proto::Ack {})?; response.send(proto::Ack {})?;
Ok(()) Ok(())
} }
async fn rejoin_remote_projects( async fn rejoin_dev_server_projects(
request: proto::RejoinRemoteProjects, request: proto::RejoinRemoteProjects,
response: Response<proto::RejoinRemoteProjects>, response: Response<proto::RejoinRemoteProjects>,
session: UserSession, session: UserSession,
) -> Result<()> { ) -> Result<()> {
let mut rejoined_projects = { let mut rejoined_projects = {
let db = session.db().await; let db = session.db().await;
db.rejoin_remote_projects( db.rejoin_dev_server_projects(
&request.rejoined_projects, &request.rejoined_projects,
session.user_id(), session.user_id(),
session.0.connection_id, session.0.connection_id,
@ -2394,7 +2394,7 @@ async fn reconnect_dev_server(
) -> Result<()> { ) -> Result<()> {
let reshared_projects = { let reshared_projects = {
let db = session.db().await; let db = session.db().await;
db.reshare_remote_projects( db.reshare_dev_server_projects(
&request.reshared_projects, &request.reshared_projects,
session.dev_server_id(), session.dev_server_id(),
session.0.connection_id, session.0.connection_id,
@ -2467,14 +2467,14 @@ async fn shutdown_dev_server_internal(
connection_id: ConnectionId, connection_id: ConnectionId,
session: &Session, session: &Session,
) -> Result<()> { ) -> Result<()> {
let (remote_projects, dev_server) = { let (dev_server_projects, dev_server) = {
let db = session.db().await; let db = session.db().await;
let remote_projects = db.get_remote_projects_for_dev_server(dev_server_id).await?; let dev_server_projects = db.get_projects_for_dev_server(dev_server_id).await?;
let dev_server = db.get_dev_server(dev_server_id).await?; let dev_server = db.get_dev_server(dev_server_id).await?;
(remote_projects, dev_server) (dev_server_projects, dev_server)
}; };
for project_id in remote_projects.iter().filter_map(|p| p.project_id) { for project_id in dev_server_projects.iter().filter_map(|p| p.project_id) {
unshare_project_internal( unshare_project_internal(
ProjectId::from_proto(project_id), ProjectId::from_proto(project_id),
connection_id, connection_id,
@ -2492,9 +2492,9 @@ async fn shutdown_dev_server_internal(
let status = session let status = session
.db() .db()
.await .await
.remote_projects_update(dev_server.user_id) .dev_server_projects_update(dev_server.user_id)
.await?; .await?;
send_remote_projects_update(dev_server.user_id, status, &session).await; send_dev_server_projects_update(dev_server.user_id, status, &session).await;
Ok(()) Ok(())
} }
@ -4908,9 +4908,9 @@ fn channel_updated(
); );
} }
async fn send_remote_projects_update( async fn send_dev_server_projects_update(
user_id: UserId, user_id: UserId,
mut status: proto::RemoteProjectsUpdate, mut status: proto::DevServerProjectsUpdate,
session: &Session, session: &Session,
) { ) {
let pool = session.connection_pool().await; let pool = session.connection_pool().await;
@ -4973,9 +4973,13 @@ async fn lost_dev_server_connection(session: &DevServerSession) -> Result<()> {
} }
let user_id = session.dev_server().user_id; let user_id = session.dev_server().user_id;
let update = session.db().await.remote_projects_update(user_id).await?; let update = session
.db()
.await
.dev_server_projects_update(user_id)
.await?;
send_remote_projects_update(user_id, update, session).await; send_dev_server_projects_update(user_id, update, session).await;
Ok(()) Ok(())
} }

View File

@ -246,7 +246,7 @@ async fn test_channel_notes_participant_indices(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b); let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
// Clients A and B open the same file. // Clients A and B open the same file.

View File

@ -16,7 +16,7 @@ use super::TestClient;
async fn test_dev_server(cx: &mut gpui::TestAppContext, cx2: &mut gpui::TestAppContext) { async fn test_dev_server(cx: &mut gpui::TestAppContext, cx2: &mut gpui::TestAppContext) {
let (server, client) = TestServer::start1(cx).await; let (server, client) = TestServer::start1(cx).await;
let store = cx.update(|cx| remote_projects::Store::global(cx).clone()); let store = cx.update(|cx| dev_server_projects::Store::global(cx).clone());
let resp = store let resp = store
.update(cx, |store, cx| { .update(cx, |store, cx| {
@ -51,7 +51,7 @@ async fn test_dev_server(cx: &mut gpui::TestAppContext, cx2: &mut gpui::TestAppC
store store
.update(cx, |store, cx| { .update(cx, |store, cx| {
store.create_remote_project( store.create_dev_server_project(
client::DevServerId(resp.dev_server_id), client::DevServerId(resp.dev_server_id),
"/remote".to_string(), "/remote".to_string(),
cx, cx,
@ -64,10 +64,10 @@ async fn test_dev_server(cx: &mut gpui::TestAppContext, cx2: &mut gpui::TestAppC
let remote_workspace = store let remote_workspace = store
.update(cx, |store, cx| { .update(cx, |store, cx| {
let projects = store.remote_projects(); let projects = store.dev_server_projects();
assert_eq!(projects.len(), 1); assert_eq!(projects.len(), 1);
assert_eq!(projects[0].path, "/remote"); assert_eq!(projects[0].path, "/remote");
workspace::join_remote_project( workspace::join_dev_server_project(
projects[0].project_id.unwrap(), projects[0].project_id.unwrap(),
client.app_state.clone(), client.app_state.clone(),
None, None,
@ -110,7 +110,7 @@ async fn test_dev_server_env_files(
let (server, client1, client2, channel_id) = TestServer::start2(cx1, cx2).await; let (server, client1, client2, channel_id) = TestServer::start2(cx1, cx2).await;
let (_dev_server, remote_workspace) = let (_dev_server, remote_workspace) =
create_remote_project(&server, client1.app_state.clone(), cx1, cx3).await; create_dev_server_project(&server, client1.app_state.clone(), cx1, cx3).await;
cx1.executor().run_until_parked(); cx1.executor().run_until_parked();
@ -157,13 +157,13 @@ async fn test_dev_server_env_files(
}); });
} }
async fn create_remote_project( async fn create_dev_server_project(
server: &TestServer, server: &TestServer,
client_app_state: Arc<AppState>, client_app_state: Arc<AppState>,
cx: &mut TestAppContext, cx: &mut TestAppContext,
cx_devserver: &mut TestAppContext, cx_devserver: &mut TestAppContext,
) -> (TestClient, WindowHandle<Workspace>) { ) -> (TestClient, WindowHandle<Workspace>) {
let store = cx.update(|cx| remote_projects::Store::global(cx).clone()); let store = cx.update(|cx| dev_server_projects::Store::global(cx).clone());
let resp = store let resp = store
.update(cx, |store, cx| { .update(cx, |store, cx| {
@ -190,7 +190,7 @@ async fn create_remote_project(
store store
.update(cx, |store, cx| { .update(cx, |store, cx| {
store.create_remote_project( store.create_dev_server_project(
client::DevServerId(resp.dev_server_id), client::DevServerId(resp.dev_server_id),
"/remote".to_string(), "/remote".to_string(),
cx, cx,
@ -203,10 +203,10 @@ async fn create_remote_project(
let workspace = store let workspace = store
.update(cx, |store, cx| { .update(cx, |store, cx| {
let projects = store.remote_projects(); let projects = store.dev_server_projects();
assert_eq!(projects.len(), 1); assert_eq!(projects.len(), 1);
assert_eq!(projects[0].path, "/remote"); assert_eq!(projects[0].path, "/remote");
workspace::join_remote_project( workspace::join_dev_server_project(
projects[0].project_id.unwrap(), projects[0].project_id.unwrap(),
client_app_state, client_app_state,
None, None,
@ -230,7 +230,7 @@ async fn test_dev_server_leave_room(
let (server, client1, client2, channel_id) = TestServer::start2(cx1, cx2).await; let (server, client1, client2, channel_id) = TestServer::start2(cx1, cx2).await;
let (_dev_server, remote_workspace) = let (_dev_server, remote_workspace) =
create_remote_project(&server, client1.app_state.clone(), cx1, cx3).await; create_dev_server_project(&server, client1.app_state.clone(), cx1, cx3).await;
cx1.update(|cx| { cx1.update(|cx| {
workspace::join_channel( workspace::join_channel(
@ -275,7 +275,7 @@ async fn test_dev_server_reconnect(
.await; .await;
let (_dev_server, remote_workspace) = let (_dev_server, remote_workspace) =
create_remote_project(&server, client1.app_state.clone(), cx1, cx3).await; create_dev_server_project(&server, client1.app_state.clone(), cx1, cx3).await;
cx1.update(|cx| { cx1.update(|cx| {
workspace::join_channel( workspace::join_channel(
@ -299,12 +299,12 @@ async fn test_dev_server_reconnect(
let client2 = server.create_client(cx2, "user_a").await; let client2 = server.create_client(cx2, "user_a").await;
let store = cx2.update(|cx| remote_projects::Store::global(cx).clone()); let store = cx2.update(|cx| dev_server_projects::Store::global(cx).clone());
store store
.update(cx2, |store, cx| { .update(cx2, |store, cx| {
let projects = store.remote_projects(); let projects = store.dev_server_projects();
workspace::join_remote_project( workspace::join_dev_server_project(
projects[0].project_id.unwrap(), projects[0].project_id.unwrap(),
client2.app_state.clone(), client2.app_state.clone(),
None, None,
@ -316,7 +316,7 @@ async fn test_dev_server_reconnect(
} }
#[gpui::test] #[gpui::test]
async fn test_create_remote_project_path_validation( async fn test_create_dev_server_project_path_validation(
cx1: &mut gpui::TestAppContext, cx1: &mut gpui::TestAppContext,
cx2: &mut gpui::TestAppContext, cx2: &mut gpui::TestAppContext,
cx3: &mut gpui::TestAppContext, cx3: &mut gpui::TestAppContext,
@ -328,11 +328,11 @@ async fn test_create_remote_project_path_validation(
// Creating a project with a path that does exist should not fail // Creating a project with a path that does exist should not fail
let (_dev_server, _) = let (_dev_server, _) =
create_remote_project(&server, client1.app_state.clone(), cx1, cx2).await; create_dev_server_project(&server, client1.app_state.clone(), cx1, cx2).await;
cx1.executor().run_until_parked(); cx1.executor().run_until_parked();
let store = cx1.update(|cx| remote_projects::Store::global(cx).clone()); let store = cx1.update(|cx| dev_server_projects::Store::global(cx).clone());
let resp = store let resp = store
.update(cx1, |store, cx| { .update(cx1, |store, cx| {
@ -350,7 +350,7 @@ async fn test_create_remote_project_path_validation(
// Creating a remote project with a path that does not exist should fail // Creating a remote project with a path that does not exist should fail
let result = store let result = store
.update(cx1, |store, cx| { .update(cx1, |store, cx| {
store.create_remote_project( store.create_dev_server_project(
client::DevServerId(resp.dev_server_id), client::DevServerId(resp.dev_server_id),
"/notfound".to_string(), "/notfound".to_string(),
cx, cx,
@ -363,7 +363,7 @@ async fn test_create_remote_project_path_validation(
let error = result.unwrap_err(); let error = result.unwrap_err();
assert!(matches!( assert!(matches!(
error.error_code(), error.error_code(),
ErrorCode::RemoteProjectPathDoesNotExist ErrorCode::DevServerProjectPathDoesNotExist
)); ));
} }
@ -373,7 +373,7 @@ async fn test_save_as_remote(cx1: &mut gpui::TestAppContext, cx2: &mut gpui::Tes
// Creating a project with a path that does exist should not fail // Creating a project with a path that does exist should not fail
let (dev_server, remote_workspace) = let (dev_server, remote_workspace) =
create_remote_project(&server, client1.app_state.clone(), cx1, cx2).await; create_dev_server_project(&server, client1.app_state.clone(), cx1, cx2).await;
let mut cx = VisualTestContext::from_window(remote_workspace.into(), cx1); let mut cx = VisualTestContext::from_window(remote_workspace.into(), cx1);
@ -405,7 +405,7 @@ async fn test_new_file_remote(cx1: &mut gpui::TestAppContext, cx2: &mut gpui::Te
// Creating a project with a path that does exist should not fail // Creating a project with a path that does exist should not fail
let (dev_server, remote_workspace) = let (dev_server, remote_workspace) =
create_remote_project(&server, client1.app_state.clone(), cx1, cx2).await; create_dev_server_project(&server, client1.app_state.clone(), cx1, cx2).await;
let mut cx = VisualTestContext::from_window(remote_workspace.into(), cx1); let mut cx = VisualTestContext::from_window(remote_workspace.into(), cx1);

View File

@ -78,7 +78,7 @@ async fn test_host_disconnect(
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
cx_a.background_executor.run_until_parked(); cx_a.background_executor.run_until_parked();
assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared())); assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
@ -199,7 +199,7 @@ async fn test_newline_above_or_below_does_not_move_guest_cursor(
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a buffer as client A // Open a buffer as client A
let buffer_a = project_a let buffer_a = project_a
@ -315,7 +315,7 @@ async fn test_collaborating_with_completion(cx_a: &mut TestAppContext, cx_b: &mu
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a file in an editor as the guest. // Open a file in an editor as the guest.
let buffer_b = project_b let buffer_b = project_b
@ -572,7 +572,7 @@ async fn test_collaborating_with_code_actions(
.unwrap(); .unwrap();
// Join the project as client B. // Join the project as client B.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b); let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
let editor_b = workspace_b let editor_b = workspace_b
.update(cx_b, |workspace, cx| { .update(cx_b, |workspace, cx| {
@ -787,7 +787,7 @@ async fn test_collaborating_with_renames(cx_a: &mut TestAppContext, cx_b: &mut T
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b); let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
let editor_b = workspace_b let editor_b = workspace_b
@ -1036,7 +1036,7 @@ async fn test_language_server_statuses(cx_a: &mut TestAppContext, cx_b: &mut Tes
.await .await
.unwrap(); .unwrap();
executor.run_until_parked(); executor.run_until_parked();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
project_b.read_with(cx_b, |project, _| { project_b.read_with(cx_b, |project, _| {
let status = project.language_server_statuses().next().unwrap(); let status = project.language_server_statuses().next().unwrap();
@ -1133,7 +1133,7 @@ async fn test_share_project(
.unwrap(); .unwrap();
let client_b_peer_id = client_b.peer_id().unwrap(); let client_b_peer_id = client_b.peer_id().unwrap();
let project_b = client_b let project_b = client_b
.build_remote_project(initial_project.id, cx_b) .build_dev_server_project(initial_project.id, cx_b)
.await; .await;
let replica_id_b = project_b.read_with(cx_b, |project, _| project.replica_id()); let replica_id_b = project_b.read_with(cx_b, |project, _| project.replica_id());
@ -1237,7 +1237,7 @@ async fn test_share_project(
.await .await
.unwrap(); .unwrap();
let _project_c = client_c let _project_c = client_c
.build_remote_project(initial_project.id, cx_c) .build_dev_server_project(initial_project.id, cx_c)
.await; .await;
// Client B closes the editor, and client A sees client B's selections removed. // Client B closes the editor, and client A sees client B's selections removed.
@ -1297,7 +1297,7 @@ async fn test_on_input_format_from_host_to_guest(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a file in an editor as the host. // Open a file in an editor as the host.
let buffer_a = project_a let buffer_a = project_a
@ -1417,7 +1417,7 @@ async fn test_on_input_format_from_guest_to_host(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a file in an editor as the guest. // Open a file in an editor as the guest.
let buffer_b = project_b let buffer_b = project_b
@ -1578,7 +1578,7 @@ async fn test_mutual_editor_inlay_hint_cache_update(
.unwrap(); .unwrap();
// Client B joins the project // Client B joins the project
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -1838,7 +1838,7 @@ async fn test_inlay_hint_refresh_is_forwarded(
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -2014,7 +2014,7 @@ struct Row10;"#};
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -2312,7 +2312,7 @@ async fn test_git_blame_is_forwarded(cx_a: &mut TestAppContext, cx_b: &mut TestA
.unwrap(); .unwrap();
// Join the project as client B. // Join the project as client B.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b); let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
let editor_b = workspace_b let editor_b = workspace_b
.update(cx_b, |workspace, cx| { .update(cx_b, |workspace, cx| {

View File

@ -73,7 +73,7 @@ async fn test_basic_following(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -161,7 +161,7 @@ async fn test_basic_following(
executor.run_until_parked(); executor.run_until_parked();
let active_call_c = cx_c.read(ActiveCall::global); let active_call_c = cx_c.read(ActiveCall::global);
let project_c = client_c.build_remote_project(project_id, cx_c).await; let project_c = client_c.build_dev_server_project(project_id, cx_c).await;
let (workspace_c, cx_c) = client_c.build_workspace(&project_c, cx_c); let (workspace_c, cx_c) = client_c.build_workspace(&project_c, cx_c);
active_call_c active_call_c
.update(cx_c, |call, cx| call.set_location(Some(&project_c), cx)) .update(cx_c, |call, cx| call.set_location(Some(&project_c), cx))
@ -174,7 +174,7 @@ async fn test_basic_following(
cx_d.executor().run_until_parked(); cx_d.executor().run_until_parked();
let active_call_d = cx_d.read(ActiveCall::global); let active_call_d = cx_d.read(ActiveCall::global);
let project_d = client_d.build_remote_project(project_id, cx_d).await; let project_d = client_d.build_dev_server_project(project_id, cx_d).await;
let (workspace_d, cx_d) = client_d.build_workspace(&project_d, cx_d); let (workspace_d, cx_d) = client_d.build_workspace(&project_d, cx_d);
active_call_d active_call_d
.update(cx_d, |call, cx| call.set_location(Some(&project_d), cx)) .update(cx_d, |call, cx| call.set_location(Some(&project_d), cx))
@ -567,7 +567,7 @@ async fn test_following_tab_order(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -684,7 +684,7 @@ async fn test_peers_following_each_other(cx_a: &mut TestAppContext, cx_b: &mut T
.unwrap(); .unwrap();
// Client B joins the project. // Client B joins the project.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -1197,7 +1197,7 @@ async fn test_auto_unfollowing(cx_a: &mut TestAppContext, cx_b: &mut TestAppCont
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await
@ -1333,7 +1333,7 @@ async fn test_peers_simultaneously_following_each_other(
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b); let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
executor.run_until_parked(); executor.run_until_parked();
@ -1683,7 +1683,7 @@ async fn test_following_into_excluded_file(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
active_call_b active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx)) .update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await .await

View File

@ -1375,7 +1375,7 @@ async fn test_unshare_project(
.unwrap(); .unwrap();
let worktree_a = project_a.read_with(cx_a, |project, _| project.worktrees().next().unwrap()); let worktree_a = project_a.read_with(cx_a, |project, _| project.worktrees().next().unwrap());
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
executor.run_until_parked(); executor.run_until_parked();
assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared())); assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
@ -1395,7 +1395,7 @@ async fn test_unshare_project(
assert!(project_b.read_with(cx_b, |project, _| project.is_disconnected())); assert!(project_b.read_with(cx_b, |project, _| project.is_disconnected()));
// Client C opens the project. // Client C opens the project.
let project_c = client_c.build_remote_project(project_id, cx_c).await; let project_c = client_c.build_dev_server_project(project_id, cx_c).await;
// When client A unshares the project, client C's project becomes read-only. // When client A unshares the project, client C's project becomes read-only.
project_a project_a
@ -1412,7 +1412,7 @@ async fn test_unshare_project(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_c2 = client_c.build_remote_project(project_id, cx_c).await; let project_c2 = client_c.build_dev_server_project(project_id, cx_c).await;
executor.run_until_parked(); executor.run_until_parked();
assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared())); assert!(worktree_a.read_with(cx_a, |tree, _| tree.as_local().unwrap().is_shared()));
@ -1516,9 +1516,9 @@ async fn test_project_reconnect(
.await .await
.unwrap(); .unwrap();
let project_b1 = client_b.build_remote_project(project1_id, cx_b).await; let project_b1 = client_b.build_dev_server_project(project1_id, cx_b).await;
let project_b2 = client_b.build_remote_project(project2_id, cx_b).await; let project_b2 = client_b.build_dev_server_project(project2_id, cx_b).await;
let project_b3 = client_b.build_remote_project(project3_id, cx_b).await; let project_b3 = client_b.build_dev_server_project(project3_id, cx_b).await;
executor.run_until_parked(); executor.run_until_parked();
let worktree1_id = worktree_a1.read_with(cx_a, |worktree, _| { let worktree1_id = worktree_a1.read_with(cx_a, |worktree, _| {
@ -2314,8 +2314,8 @@ async fn test_propagate_saves_and_fs_changes(
.unwrap(); .unwrap();
// Join that worktree as clients B and C. // Join that worktree as clients B and C.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let project_c = client_c.build_remote_project(project_id, cx_c).await; let project_c = client_c.build_dev_server_project(project_id, cx_c).await;
let worktree_b = project_b.read_with(cx_b, |p, _| p.worktrees().next().unwrap()); let worktree_b = project_b.read_with(cx_b, |p, _| p.worktrees().next().unwrap());
@ -2539,7 +2539,7 @@ async fn test_git_diff_base_change(
.await .await
.unwrap(); .unwrap();
let project_remote = client_b.build_remote_project(project_id, cx_b).await; let project_remote = client_b.build_dev_server_project(project_id, cx_b).await;
let diff_base = " let diff_base = "
one one
@ -2771,7 +2771,7 @@ async fn test_git_branch_name(
.await .await
.unwrap(); .unwrap();
let project_remote = client_b.build_remote_project(project_id, cx_b).await; let project_remote = client_b.build_dev_server_project(project_id, cx_b).await;
client_a client_a
.fs() .fs()
.set_branch_name(Path::new("/dir/.git"), Some("branch-1")); .set_branch_name(Path::new("/dir/.git"), Some("branch-1"));
@ -2816,7 +2816,7 @@ async fn test_git_branch_name(
assert_branch(Some("branch-2"), project, cx) assert_branch(Some("branch-2"), project, cx)
}); });
let project_remote_c = client_c.build_remote_project(project_id, cx_c).await; let project_remote_c = client_c.build_dev_server_project(project_id, cx_c).await;
executor.run_until_parked(); executor.run_until_parked();
project_remote_c.read_with(cx_c, |project, cx| { project_remote_c.read_with(cx_c, |project, cx| {
@ -2871,7 +2871,7 @@ async fn test_git_status_sync(
.await .await
.unwrap(); .unwrap();
let project_remote = client_b.build_remote_project(project_id, cx_b).await; let project_remote = client_b.build_dev_server_project(project_id, cx_b).await;
// Wait for it to catch up to the new status // Wait for it to catch up to the new status
executor.run_until_parked(); executor.run_until_parked();
@ -2947,7 +2947,7 @@ async fn test_git_status_sync(
}); });
// And synchronization while joining // And synchronization while joining
let project_remote_c = client_c.build_remote_project(project_id, cx_c).await; let project_remote_c = client_c.build_dev_server_project(project_id, cx_c).await;
executor.run_until_parked(); executor.run_until_parked();
project_remote_c.read_with(cx_c, |project, cx| { project_remote_c.read_with(cx_c, |project, cx| {
@ -2995,7 +2995,7 @@ async fn test_fs_operations(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let worktree_a = project_a.read_with(cx_a, |project, _| project.worktrees().next().unwrap()); let worktree_a = project_a.read_with(cx_a, |project, _| project.worktrees().next().unwrap());
@ -3289,7 +3289,7 @@ async fn test_local_settings(
executor.run_until_parked(); executor.run_until_parked();
// As client B, join that project and observe the local settings. // As client B, join that project and observe the local settings.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let worktree_b = project_b.read_with(cx_b, |project, _| project.worktrees().next().unwrap()); let worktree_b = project_b.read_with(cx_b, |project, _| project.worktrees().next().unwrap());
executor.run_until_parked(); executor.run_until_parked();
@ -3412,7 +3412,7 @@ async fn test_buffer_conflict_after_save(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a buffer as client B // Open a buffer as client B
let buffer_b = project_b let buffer_b = project_b
@ -3476,7 +3476,7 @@ async fn test_buffer_reloading(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a buffer as client B // Open a buffer as client B
let buffer_b = project_b let buffer_b = project_b
@ -3530,7 +3530,7 @@ async fn test_editing_while_guest_opens_buffer(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open a buffer as client A // Open a buffer as client A
let buffer_a = project_a let buffer_a = project_a
@ -3578,7 +3578,7 @@ async fn test_leaving_worktree_while_opening_buffer(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// See that a guest has joined as client A. // See that a guest has joined as client A.
executor.run_until_parked(); executor.run_until_parked();
@ -3625,7 +3625,7 @@ async fn test_canceling_buffer_opening(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let buffer_a = project_a let buffer_a = project_a
.update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx)) .update(cx_a, |p, cx| p.open_buffer((worktree_id, "a.txt"), cx))
@ -3682,8 +3682,8 @@ async fn test_leaving_project(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b1 = client_b.build_remote_project(project_id, cx_b).await; let project_b1 = client_b.build_dev_server_project(project_id, cx_b).await;
let project_c = client_c.build_remote_project(project_id, cx_c).await; let project_c = client_c.build_dev_server_project(project_id, cx_c).await;
// Client A sees that a guest has joined. // Client A sees that a guest has joined.
executor.run_until_parked(); executor.run_until_parked();
@ -3724,7 +3724,7 @@ async fn test_leaving_project(
}); });
// Client B re-joins the project and can open buffers as before. // Client B re-joins the project and can open buffers as before.
let project_b2 = client_b.build_remote_project(project_id, cx_b).await; let project_b2 = client_b.build_dev_server_project(project_id, cx_b).await;
executor.run_until_parked(); executor.run_until_parked();
project_a.read_with(cx_a, |project, _| { project_a.read_with(cx_a, |project, _| {
@ -3900,7 +3900,7 @@ async fn test_collaborating_with_diagnostics(
); );
// Join the worktree as client B. // Join the worktree as client B.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Wait for server to see the diagnostics update. // Wait for server to see the diagnostics update.
executor.run_until_parked(); executor.run_until_parked();
@ -3925,7 +3925,7 @@ async fn test_collaborating_with_diagnostics(
}); });
// Join project as client C and observe the diagnostics. // Join project as client C and observe the diagnostics.
let project_c = client_c.build_remote_project(project_id, cx_c).await; let project_c = client_c.build_dev_server_project(project_id, cx_c).await;
executor.run_until_parked(); executor.run_until_parked();
let project_c_diagnostic_summaries = let project_c_diagnostic_summaries =
Rc::new(RefCell::new(project_c.read_with(cx_c, |project, cx| { Rc::new(RefCell::new(project_c.read_with(cx_c, |project, cx| {
@ -4133,7 +4133,7 @@ async fn test_collaborating_with_lsp_progress_updates_and_diagnostics_ordering(
.unwrap(); .unwrap();
// Join the project as client B and open all three files. // Join the project as client B and open all three files.
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let guest_buffers = futures::future::try_join_all(file_names.iter().map(|file_name| { let guest_buffers = futures::future::try_join_all(file_names.iter().map(|file_name| {
project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, file_name), cx)) project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, file_name), cx))
})) }))
@ -4239,7 +4239,7 @@ async fn test_reloading_buffer_manually(
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)); let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap(); let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
@ -4337,7 +4337,7 @@ async fn test_formatting_buffer(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)); let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap(); let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
@ -4457,7 +4457,7 @@ async fn test_prettier_formatting_buffer(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)); let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap(); let buffer_b = cx_b.executor().spawn(open_buffer).await.unwrap();
@ -4560,7 +4560,7 @@ async fn test_definition(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open the file on client B. // Open the file on client B.
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)); let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
@ -4705,7 +4705,7 @@ async fn test_references(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open the file on client B. // Open the file on client B.
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "one.rs"), cx)); let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "one.rs"), cx));
@ -4862,7 +4862,7 @@ async fn test_project_search(
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Perform a search as the guest. // Perform a search as the guest.
let mut results = HashMap::default(); let mut results = HashMap::default();
@ -4943,7 +4943,7 @@ async fn test_document_highlights(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open the file on client B. // Open the file on client B.
let open_b = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)); let open_b = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx));
@ -5065,7 +5065,7 @@ async fn test_lsp_hover(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Open the file as the guest // Open the file as the guest
let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx)); let open_buffer = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "main.rs"), cx));
@ -5242,7 +5242,7 @@ async fn test_project_symbols(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
// Cause the language server to start. // Cause the language server to start.
let open_buffer_task = let open_buffer_task =
@ -5337,7 +5337,7 @@ async fn test_open_buffer_while_getting_definition_pointing_to_it(
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx)) .update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await .await
.unwrap(); .unwrap();
let project_b = client_b.build_remote_project(project_id, cx_b).await; let project_b = client_b.build_dev_server_project(project_id, cx_b).await;
let open_buffer_task = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx)); let open_buffer_task = project_b.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx));
let buffer_b1 = cx_b.executor().spawn(open_buffer_task).await.unwrap(); let buffer_b1 = cx_b.executor().spawn(open_buffer_task).await.unwrap();

View File

@ -217,19 +217,20 @@ impl RandomizedTest for ProjectCollaborationTest {
0..=70 => { 0..=70 => {
// Open a remote project // Open a remote project
if let Some(room) = call.read_with(cx, |call, _| call.room().cloned()) { if let Some(room) = call.read_with(cx, |call, _| call.room().cloned()) {
let existing_remote_project_ids = cx.read(|cx| { let existing_dev_server_project_ids = cx.read(|cx| {
client client
.remote_projects() .dev_server_projects()
.iter() .iter()
.map(|p| p.read(cx).remote_id().unwrap()) .map(|p| p.read(cx).remote_id().unwrap())
.collect::<Vec<_>>() .collect::<Vec<_>>()
}); });
let new_remote_projects = room.read_with(cx, |room, _| { let new_dev_server_projects = room.read_with(cx, |room, _| {
room.remote_participants() room.remote_participants()
.values() .values()
.flat_map(|participant| { .flat_map(|participant| {
participant.projects.iter().filter_map(|project| { participant.projects.iter().filter_map(|project| {
if existing_remote_project_ids.contains(&project.id) { if existing_dev_server_project_ids.contains(&project.id)
{
None None
} else { } else {
Some(( Some((
@ -241,9 +242,9 @@ impl RandomizedTest for ProjectCollaborationTest {
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
}); });
if !new_remote_projects.is_empty() { if !new_dev_server_projects.is_empty() {
let (host_id, first_root_name) = let (host_id, first_root_name) =
new_remote_projects.choose(rng).unwrap().clone(); new_dev_server_projects.choose(rng).unwrap().clone();
break ClientOperation::OpenRemoteProject { break ClientOperation::OpenRemoteProject {
host_id, host_id,
first_root_name, first_root_name,
@ -259,8 +260,8 @@ impl RandomizedTest for ProjectCollaborationTest {
// Close a remote project // Close a remote project
71..=80 => { 71..=80 => {
if !client.remote_projects().is_empty() { if !client.dev_server_projects().is_empty() {
let project = client.remote_projects().choose(rng).unwrap().clone(); let project = client.dev_server_projects().choose(rng).unwrap().clone();
let first_root_name = root_name_for_project(&project, cx); let first_root_name = root_name_for_project(&project, cx);
break ClientOperation::CloseRemoteProject { break ClientOperation::CloseRemoteProject {
project_root_name: first_root_name, project_root_name: first_root_name,
@ -595,12 +596,12 @@ impl RandomizedTest for ProjectCollaborationTest {
); );
let ix = client let ix = client
.remote_projects() .dev_server_projects()
.iter() .iter()
.position(|p| p == &project) .position(|p| p == &project)
.unwrap(); .unwrap();
cx.update(|_| { cx.update(|_| {
client.remote_projects_mut().remove(ix); client.dev_server_projects_mut().remove(ix);
client.buffers().retain(|p, _| *p != project); client.buffers().retain(|p, _| *p != project);
drop(project); drop(project);
}); });
@ -642,7 +643,7 @@ impl RandomizedTest for ProjectCollaborationTest {
); );
let project = project.await?; let project = project.await?;
client.remote_projects_mut().push(project.clone()); client.dev_server_projects_mut().push(project.clone());
} }
ClientOperation::CreateWorktreeEntry { ClientOperation::CreateWorktreeEntry {
@ -1142,7 +1143,7 @@ impl RandomizedTest for ProjectCollaborationTest {
async fn on_quiesce(_: &mut TestServer, clients: &mut [(Rc<TestClient>, TestAppContext)]) { async fn on_quiesce(_: &mut TestServer, clients: &mut [(Rc<TestClient>, TestAppContext)]) {
for (client, client_cx) in clients.iter() { for (client, client_cx) in clients.iter() {
for guest_project in client.remote_projects().iter() { for guest_project in client.dev_server_projects().iter() {
guest_project.read_with(client_cx, |guest_project, cx| { guest_project.read_with(client_cx, |guest_project, cx| {
let host_project = clients.iter().find_map(|(client, cx)| { let host_project = clients.iter().find_map(|(client, cx)| {
let project = client let project = client
@ -1487,8 +1488,9 @@ fn project_for_root_name(
if let Some(ix) = project_ix_for_root_name(client.local_projects().deref(), root_name, cx) { if let Some(ix) = project_ix_for_root_name(client.local_projects().deref(), root_name, cx) {
return Some(client.local_projects()[ix].clone()); return Some(client.local_projects()[ix].clone());
} }
if let Some(ix) = project_ix_for_root_name(client.remote_projects().deref(), root_name, cx) { if let Some(ix) = project_ix_for_root_name(client.dev_server_projects().deref(), root_name, cx)
return Some(client.remote_projects()[ix].clone()); {
return Some(client.dev_server_projects()[ix].clone());
} }
None None
} }
@ -1578,7 +1580,7 @@ fn choose_random_project(client: &TestClient, rng: &mut StdRng) -> Option<Model<
.local_projects() .local_projects()
.deref() .deref()
.iter() .iter()
.chain(client.remote_projects().iter()) .chain(client.dev_server_projects().iter())
.choose(rng) .choose(rng)
.cloned() .cloned()
} }

View File

@ -533,7 +533,7 @@ impl<T: RandomizedTest> TestPlan<T> {
deterministic.finish_waiting(); deterministic.finish_waiting();
server.allow_connections(); server.allow_connections();
for project in client.remote_projects().iter() { for project in client.dev_server_projects().iter() {
project.read_with(&client_cx, |project, _| { project.read_with(&client_cx, |project, _| {
assert!( assert!(
project.is_disconnected(), project.is_disconnected(),

View File

@ -64,7 +64,7 @@ pub struct TestClient {
#[derive(Default)] #[derive(Default)]
struct TestClientState { struct TestClientState {
local_projects: Vec<Model<Project>>, local_projects: Vec<Model<Project>>,
remote_projects: Vec<Model<Project>>, dev_server_projects: Vec<Model<Project>>,
buffers: HashMap<Model<Project>, HashSet<Model<language::Buffer>>>, buffers: HashMap<Model<Project>, HashSet<Model<language::Buffer>>>,
channel_buffers: HashSet<Model<ChannelBuffer>>, channel_buffers: HashSet<Model<ChannelBuffer>>,
} }
@ -290,7 +290,7 @@ impl TestServer {
collab_ui::init(&app_state, cx); collab_ui::init(&app_state, cx);
file_finder::init(cx); file_finder::init(cx);
menu::init(); menu::init();
remote_projects::init(client.clone(), cx); dev_server_projects::init(client.clone(), cx);
settings::KeymapFile::load_asset(os_keymap, cx).unwrap(); settings::KeymapFile::load_asset(os_keymap, cx).unwrap();
}); });
@ -735,16 +735,18 @@ impl TestClient {
Ref::map(self.state.borrow(), |state| &state.local_projects) Ref::map(self.state.borrow(), |state| &state.local_projects)
} }
pub fn remote_projects(&self) -> impl Deref<Target = Vec<Model<Project>>> + '_ { pub fn dev_server_projects(&self) -> impl Deref<Target = Vec<Model<Project>>> + '_ {
Ref::map(self.state.borrow(), |state| &state.remote_projects) Ref::map(self.state.borrow(), |state| &state.dev_server_projects)
} }
pub fn local_projects_mut(&self) -> impl DerefMut<Target = Vec<Model<Project>>> + '_ { pub fn local_projects_mut(&self) -> impl DerefMut<Target = Vec<Model<Project>>> + '_ {
RefMut::map(self.state.borrow_mut(), |state| &mut state.local_projects) RefMut::map(self.state.borrow_mut(), |state| &mut state.local_projects)
} }
pub fn remote_projects_mut(&self) -> impl DerefMut<Target = Vec<Model<Project>>> + '_ { pub fn dev_server_projects_mut(&self) -> impl DerefMut<Target = Vec<Model<Project>>> + '_ {
RefMut::map(self.state.borrow_mut(), |state| &mut state.remote_projects) RefMut::map(self.state.borrow_mut(), |state| {
&mut state.dev_server_projects
})
} }
pub fn buffers_for_project<'a>( pub fn buffers_for_project<'a>(
@ -869,7 +871,7 @@ impl TestClient {
}) })
} }
pub async fn build_remote_project( pub async fn build_dev_server_project(
&self, &self,
host_project_id: u64, host_project_id: u64,
guest_cx: &mut TestAppContext, guest_cx: &mut TestAppContext,

View File

@ -50,7 +50,7 @@ parking_lot.workspace = true
picker.workspace = true picker.workspace = true
project.workspace = true project.workspace = true
recent_projects.workspace = true recent_projects.workspace = true
remote_projects.workspace = true dev_server_projects.workspace = true
rich_text.workspace = true rich_text.workspace = true
rpc.workspace = true rpc.workspace = true
schemars.workspace = true schemars.workspace = true

View File

@ -171,8 +171,8 @@ impl Render for CollabTitlebarItem {
let room = room.read(cx); let room = room.read(cx);
let project = self.project.read(cx); let project = self.project.read(cx);
let is_local = project.is_local(); let is_local = project.is_local();
let is_remote_project = project.remote_project_id().is_some(); let is_dev_server_project = project.dev_server_project_id().is_some();
let is_shared = (is_local || is_remote_project) && project.is_shared(); let is_shared = (is_local || is_dev_server_project) && project.is_shared();
let is_muted = room.is_muted(); let is_muted = room.is_muted();
let is_deafened = room.is_deafened().unwrap_or(false); let is_deafened = room.is_deafened().unwrap_or(false);
let is_screen_sharing = room.is_screen_sharing(); let is_screen_sharing = room.is_screen_sharing();
@ -180,7 +180,7 @@ impl Render for CollabTitlebarItem {
let can_share_projects = room.can_share_projects(); let can_share_projects = room.can_share_projects();
this.when( this.when(
(is_local || is_remote_project) && can_share_projects, (is_local || is_dev_server_project) && can_share_projects,
|this| { |this| {
this.child( this.child(
Button::new( Button::new(
@ -379,11 +379,11 @@ impl CollabTitlebarItem {
if let Some(dev_server) = if let Some(dev_server) =
self.project self.project
.read(cx) .read(cx)
.remote_project_id() .dev_server_project_id()
.and_then(|remote_project_id| { .and_then(|dev_server_project_id| {
remote_projects::Store::global(cx) dev_server_projects::Store::global(cx)
.read(cx) .read(cx)
.dev_server_for_project(remote_project_id) .dev_server_for_project(dev_server_project_id)
}) })
{ {
return Some( return Some(
@ -403,7 +403,7 @@ impl CollabTitlebarItem {
.tooltip(move |cx| Tooltip::text("Project is hosted on a dev server", cx)) .tooltip(move |cx| Tooltip::text("Project is hosted on a dev server", cx))
.on_click(cx.listener(|this, _, cx| { .on_click(cx.listener(|this, _, cx| {
if let Some(workspace) = this.workspace.upgrade() { if let Some(workspace) = this.workspace.upgrade() {
recent_projects::RemoteProjects::open(workspace, cx) recent_projects::DevServerProjects::open(workspace, cx)
} }
})) }))
.into_any_element(), .into_any_element(),

View File

@ -1,5 +1,5 @@
[package] [package]
name = "remote_projects" name = "dev_server_projects"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
publish = false publish = false
@ -9,7 +9,7 @@ license = "GPL-3.0-or-later"
workspace = true workspace = true
[lib] [lib]
path = "src/remote_projects.rs" path = "src/dev_server_projects.rs"
doctest = false doctest = false
[dependencies] [dependencies]

View File

@ -7,27 +7,27 @@ use rpc::{
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use client::{Client, ProjectId}; use client::{Client, ProjectId};
pub use client::{DevServerId, RemoteProjectId}; pub use client::{DevServerId, DevServerProjectId};
pub struct Store { pub struct Store {
remote_projects: HashMap<RemoteProjectId, RemoteProject>, dev_server_projects: HashMap<DevServerProjectId, DevServerProject>,
dev_servers: HashMap<DevServerId, DevServer>, dev_servers: HashMap<DevServerId, DevServer>,
_subscriptions: Vec<client::Subscription>, _subscriptions: Vec<client::Subscription>,
client: Arc<Client>, client: Arc<Client>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RemoteProject { pub struct DevServerProject {
pub id: RemoteProjectId, pub id: DevServerProjectId,
pub project_id: Option<ProjectId>, pub project_id: Option<ProjectId>,
pub path: SharedString, pub path: SharedString,
pub dev_server_id: DevServerId, pub dev_server_id: DevServerId,
} }
impl From<proto::RemoteProject> for RemoteProject { impl From<proto::DevServerProject> for DevServerProject {
fn from(project: proto::RemoteProject) -> Self { fn from(project: proto::DevServerProject) -> Self {
Self { Self {
id: RemoteProjectId(project.id), id: DevServerProjectId(project.id),
project_id: project.project_id.map(|id| ProjectId(id)), project_id: project.project_id.map(|id| ProjectId(id)),
path: project.path.into(), path: project.path.into(),
dev_server_id: DevServerId(project.dev_server_id), dev_server_id: DevServerId(project.dev_server_id),
@ -68,18 +68,17 @@ impl Store {
pub fn new(client: Arc<Client>, cx: &ModelContext<Self>) -> Self { pub fn new(client: Arc<Client>, cx: &ModelContext<Self>) -> Self {
Self { Self {
remote_projects: Default::default(), dev_server_projects: Default::default(),
dev_servers: Default::default(), dev_servers: Default::default(),
_subscriptions: vec![ _subscriptions: vec![client
client.add_message_handler(cx.weak_model(), Self::handle_remote_projects_update) .add_message_handler(cx.weak_model(), Self::handle_dev_server_projects_update)],
],
client, client,
} }
} }
pub fn remote_projects_for_server(&self, id: DevServerId) -> Vec<RemoteProject> { pub fn projects_for_server(&self, id: DevServerId) -> Vec<DevServerProject> {
let mut projects: Vec<RemoteProject> = self let mut projects: Vec<DevServerProject> = self
.remote_projects .dev_server_projects
.values() .values()
.filter(|project| project.dev_server_id == id) .filter(|project| project.dev_server_id == id)
.cloned() .cloned()
@ -104,24 +103,25 @@ impl Store {
.unwrap_or(DevServerStatus::Offline) .unwrap_or(DevServerStatus::Offline)
} }
pub fn remote_projects(&self) -> Vec<RemoteProject> { pub fn dev_server_projects(&self) -> Vec<DevServerProject> {
let mut projects: Vec<RemoteProject> = self.remote_projects.values().cloned().collect(); let mut projects: Vec<DevServerProject> =
self.dev_server_projects.values().cloned().collect();
projects.sort_by_key(|p| (p.path.clone(), p.id)); projects.sort_by_key(|p| (p.path.clone(), p.id));
projects projects
} }
pub fn remote_project(&self, id: RemoteProjectId) -> Option<&RemoteProject> { pub fn dev_server_project(&self, id: DevServerProjectId) -> Option<&DevServerProject> {
self.remote_projects.get(&id) self.dev_server_projects.get(&id)
} }
pub fn dev_server_for_project(&self, id: RemoteProjectId) -> Option<&DevServer> { pub fn dev_server_for_project(&self, id: DevServerProjectId) -> Option<&DevServer> {
self.remote_project(id) self.dev_server_project(id)
.and_then(|project| self.dev_server(project.dev_server_id)) .and_then(|project| self.dev_server(project.dev_server_id))
} }
async fn handle_remote_projects_update( async fn handle_dev_server_projects_update(
this: Model<Self>, this: Model<Self>,
envelope: TypedEnvelope<proto::RemoteProjectsUpdate>, envelope: TypedEnvelope<proto::DevServerProjectsUpdate>,
_: Arc<Client>, _: Arc<Client>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<()> { ) -> Result<()> {
@ -132,11 +132,11 @@ impl Store {
.into_iter() .into_iter()
.map(|dev_server| (DevServerId(dev_server.dev_server_id), dev_server.into())) .map(|dev_server| (DevServerId(dev_server.dev_server_id), dev_server.into()))
.collect(); .collect();
this.remote_projects = envelope this.dev_server_projects = envelope
.payload .payload
.remote_projects .dev_server_projects
.into_iter() .into_iter()
.map(|project| (RemoteProjectId(project.id), project.into())) .map(|project| (DevServerProjectId(project.id), project.into()))
.collect(); .collect();
cx.notify(); cx.notify();
@ -144,16 +144,16 @@ impl Store {
Ok(()) Ok(())
} }
pub fn create_remote_project( pub fn create_dev_server_project(
&mut self, &mut self,
dev_server_id: DevServerId, dev_server_id: DevServerId,
path: String, path: String,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Task<Result<proto::CreateRemoteProjectResponse>> { ) -> Task<Result<proto::CreateDevServerProjectResponse>> {
let client = self.client.clone(); let client = self.client.clone();
cx.background_executor().spawn(async move { cx.background_executor().spawn(async move {
client client
.request(proto::CreateRemoteProject { .request(proto::CreateDevServerProject {
dev_server_id: dev_server_id.0, dev_server_id: dev_server_id.0,
path, path,
}) })

View File

@ -1,5 +1,5 @@
use anyhow::Result; use anyhow::Result;
use client::RemoteProjectId; use client::DevServerProjectId;
use client::{user::UserStore, Client, ClientSettings}; use client::{user::UserStore, Client, ClientSettings};
use fs::Fs; use fs::Fs;
use futures::Future; use futures::Future;
@ -20,7 +20,7 @@ pub struct DevServer {
client: Arc<Client>, client: Arc<Client>,
app_state: AppState, app_state: AppState,
remote_shutdown: bool, remote_shutdown: bool,
projects: HashMap<RemoteProjectId, Model<Project>>, projects: HashMap<DevServerProjectId, Model<Project>>,
_subscriptions: Vec<client::Subscription>, _subscriptions: Vec<client::Subscription>,
_maintain_connection: Task<Option<()>>, _maintain_connection: Task<Option<()>>,
} }
@ -106,7 +106,7 @@ impl DevServer {
client.add_message_handler(cx.weak_model(), Self::handle_dev_server_instructions), client.add_message_handler(cx.weak_model(), Self::handle_dev_server_instructions),
client.add_request_handler( client.add_request_handler(
cx.weak_model(), cx.weak_model(),
Self::handle_validate_remote_project_request, Self::handle_validate_dev_server_project_request,
), ),
client.add_message_handler(cx.weak_model(), Self::handle_shutdown), client.add_message_handler(cx.weak_model(), Self::handle_shutdown),
], ],
@ -141,12 +141,12 @@ impl DevServer {
let removed_projects = this let removed_projects = this
.projects .projects
.keys() .keys()
.filter(|remote_project_id| { .filter(|dev_server_project_id| {
!envelope !envelope
.payload .payload
.projects .projects
.iter() .iter()
.any(|p| p.id == remote_project_id.0) .any(|p| p.id == dev_server_project_id.0)
}) })
.cloned() .cloned()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -155,14 +155,14 @@ impl DevServer {
.payload .payload
.projects .projects
.into_iter() .into_iter()
.filter(|project| !this.projects.contains_key(&RemoteProjectId(project.id))) .filter(|project| !this.projects.contains_key(&DevServerProjectId(project.id)))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
(added_projects, removed_projects) (added_projects, removed_projects)
})?; })?;
for remote_project in added_projects { for dev_server_project in added_projects {
DevServer::share_project(this.clone(), &remote_project, &mut cx).await?; DevServer::share_project(this.clone(), &dev_server_project, &mut cx).await?;
} }
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
@ -174,9 +174,9 @@ impl DevServer {
Ok(()) Ok(())
} }
async fn handle_validate_remote_project_request( async fn handle_validate_dev_server_project_request(
this: Model<Self>, this: Model<Self>,
envelope: TypedEnvelope<proto::ValidateRemoteProjectRequest>, envelope: TypedEnvelope<proto::ValidateDevServerProjectRequest>,
_: Arc<Client>, _: Arc<Client>,
cx: AsyncAppContext, cx: AsyncAppContext,
) -> Result<proto::Ack> { ) -> Result<proto::Ack> {
@ -186,7 +186,7 @@ impl DevServer {
let path_exists = fs.is_dir(path).await; let path_exists = fs.is_dir(path).await;
if !path_exists { if !path_exists {
return Err(anyhow::anyhow!(ErrorCode::RemoteProjectPathDoesNotExist))?; return Err(anyhow::anyhow!(ErrorCode::DevServerProjectPathDoesNotExist))?;
} }
Ok(proto::Ack {}) Ok(proto::Ack {})
@ -206,10 +206,10 @@ impl DevServer {
fn unshare_project( fn unshare_project(
&mut self, &mut self,
remote_project_id: &RemoteProjectId, dev_server_project_id: &DevServerProjectId,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Result<()> { ) -> Result<()> {
if let Some(project) = self.projects.remove(remote_project_id) { if let Some(project) = self.projects.remove(dev_server_project_id) {
project.update(cx, |project, cx| project.unshare(cx))?; project.update(cx, |project, cx| project.unshare(cx))?;
} }
Ok(()) Ok(())
@ -217,7 +217,7 @@ impl DevServer {
async fn share_project( async fn share_project(
this: Model<Self>, this: Model<Self>,
remote_project: &proto::RemoteProject, dev_server_project: &proto::DevServerProject,
cx: &mut AsyncAppContext, cx: &mut AsyncAppContext,
) -> Result<()> { ) -> Result<()> {
let (client, project) = this.update(cx, |this, cx| { let (client, project) = this.update(cx, |this, cx| {
@ -233,7 +233,7 @@ impl DevServer {
(this.client.clone(), project) (this.client.clone(), project)
})?; })?;
let path = shellexpand::tilde(&remote_project.path).to_string(); let path = shellexpand::tilde(&dev_server_project.path).to_string();
project project
.update(cx, |project, cx| { .update(cx, |project, cx| {
@ -245,8 +245,8 @@ impl DevServer {
project.read_with(cx, |project, cx| project.worktree_metadata_protos(cx))?; project.read_with(cx, |project, cx| project.worktree_metadata_protos(cx))?;
let response = client let response = client
.request(proto::ShareRemoteProject { .request(proto::ShareDevServerProject {
remote_project_id: remote_project.id, dev_server_project_id: dev_server_project.id,
worktrees, worktrees,
}) })
.await?; .await?;
@ -255,7 +255,7 @@ impl DevServer {
project.update(cx, |project, cx| project.shared(project_id, cx))??; project.update(cx, |project, cx| project.shared(project_id, cx))??;
this.update(cx, |this, _| { this.update(cx, |this, _| {
this.projects this.projects
.insert(RemoteProjectId(remote_project.id), project); .insert(DevServerProjectId(dev_server_project.id), project);
})?; })?;
Ok(()) Ok(())
} }

View File

@ -15,7 +15,7 @@ pub mod search_history;
use anyhow::{anyhow, bail, Context as _, Result}; use anyhow::{anyhow, bail, Context as _, Result};
use async_trait::async_trait; use async_trait::async_trait;
use client::{ use client::{
proto, Client, Collaborator, PendingEntitySubscription, ProjectId, RemoteProjectId, proto, Client, Collaborator, DevServerProjectId, PendingEntitySubscription, ProjectId,
TypedEnvelope, UserStore, TypedEnvelope, UserStore,
}; };
use clock::ReplicaId; use clock::ReplicaId;
@ -209,7 +209,7 @@ pub struct Project {
prettier_instances: HashMap<PathBuf, PrettierInstance>, prettier_instances: HashMap<PathBuf, PrettierInstance>,
tasks: Model<Inventory>, tasks: Model<Inventory>,
hosted_project_id: Option<ProjectId>, hosted_project_id: Option<ProjectId>,
remote_project_id: Option<client::RemoteProjectId>, dev_server_project_id: Option<client::DevServerProjectId>,
search_history: SearchHistory, search_history: SearchHistory,
} }
@ -744,7 +744,7 @@ impl Project {
prettier_instances: HashMap::default(), prettier_instances: HashMap::default(),
tasks, tasks,
hosted_project_id: None, hosted_project_id: None,
remote_project_id: None, dev_server_project_id: None,
search_history: Self::new_search_history(), search_history: Self::new_search_history(),
} }
}) })
@ -858,7 +858,7 @@ impl Project {
capability: Capability::ReadWrite, capability: Capability::ReadWrite,
remote_id, remote_id,
replica_id, replica_id,
in_room: response.payload.remote_project_id.is_none(), in_room: response.payload.dev_server_project_id.is_none(),
}, },
supplementary_language_servers: HashMap::default(), supplementary_language_servers: HashMap::default(),
language_servers: Default::default(), language_servers: Default::default(),
@ -900,10 +900,10 @@ impl Project {
prettier_instances: HashMap::default(), prettier_instances: HashMap::default(),
tasks, tasks,
hosted_project_id: None, hosted_project_id: None,
remote_project_id: response dev_server_project_id: response
.payload .payload
.remote_project_id .dev_server_project_id
.map(|remote_project_id| RemoteProjectId(remote_project_id)), .map(|dev_server_project_id| DevServerProjectId(dev_server_project_id)),
search_history: Self::new_search_history(), search_history: Self::new_search_history(),
}; };
this.set_role(role, cx); this.set_role(role, cx);
@ -1262,8 +1262,8 @@ impl Project {
self.hosted_project_id self.hosted_project_id
} }
pub fn remote_project_id(&self) -> Option<RemoteProjectId> { pub fn dev_server_project_id(&self) -> Option<DevServerProjectId> {
self.remote_project_id self.dev_server_project_id
} }
pub fn replica_id(&self) -> ReplicaId { pub fn replica_id(&self) -> ReplicaId {
@ -1589,7 +1589,7 @@ impl Project {
pub fn shared(&mut self, project_id: u64, cx: &mut ModelContext<Self>) -> Result<()> { pub fn shared(&mut self, project_id: u64, cx: &mut ModelContext<Self>) -> Result<()> {
if !matches!(self.client_state, ProjectClientState::Local) { if !matches!(self.client_state, ProjectClientState::Local) {
if let ProjectClientState::Remote { in_room, .. } = &mut self.client_state { if let ProjectClientState::Remote { in_room, .. } = &mut self.client_state {
if *in_room || self.remote_project_id.is_none() { if *in_room || self.dev_server_project_id.is_none() {
return Err(anyhow!("project was already shared")); return Err(anyhow!("project was already shared"));
} else { } else {
*in_room = true; *in_room = true;
@ -1808,7 +1808,7 @@ impl Project {
fn unshare_internal(&mut self, cx: &mut AppContext) -> Result<()> { fn unshare_internal(&mut self, cx: &mut AppContext) -> Result<()> {
if self.is_remote() { if self.is_remote() {
if self.remote_project_id().is_some() { if self.dev_server_project_id().is_some() {
if let ProjectClientState::Remote { in_room, .. } = &mut self.client_state { if let ProjectClientState::Remote { in_room, .. } = &mut self.client_state {
*in_room = false *in_room = false
} }

View File

@ -20,7 +20,7 @@ gpui.workspace = true
menu.workspace = true menu.workspace = true
ordered-float.workspace = true ordered-float.workspace = true
picker.workspace = true picker.workspace = true
remote_projects.workspace = true dev_server_projects.workspace = true
rpc.workspace = true rpc.workspace = true
serde.workspace = true serde.workspace = true
settings.workspace = true settings.workspace = true

View File

@ -1,12 +1,12 @@
use std::time::Duration; use std::time::Duration;
use dev_server_projects::{DevServer, DevServerId, DevServerProject, DevServerProjectId};
use feature_flags::FeatureFlagViewExt; use feature_flags::FeatureFlagViewExt;
use gpui::{ use gpui::{
percentage, Action, Animation, AnimationExt, AppContext, ClipboardItem, DismissEvent, percentage, Action, Animation, AnimationExt, AppContext, ClipboardItem, DismissEvent,
EventEmitter, FocusHandle, FocusableView, Model, ScrollHandle, Transformation, View, EventEmitter, FocusHandle, FocusableView, Model, ScrollHandle, Transformation, View,
ViewContext, ViewContext,
}; };
use remote_projects::{DevServer, DevServerId, RemoteProject, RemoteProjectId};
use rpc::{ use rpc::{
proto::{self, CreateDevServerResponse, DevServerStatus}, proto::{self, CreateDevServerResponse, DevServerStatus},
ErrorCode, ErrorExt, ErrorCode, ErrorExt,
@ -20,12 +20,12 @@ use workspace::{notifications::DetachAndPromptErr, AppState, ModalView, Workspac
use crate::OpenRemote; use crate::OpenRemote;
pub struct RemoteProjects { pub struct DevServerProjects {
mode: Mode, mode: Mode,
focus_handle: FocusHandle, focus_handle: FocusHandle,
scroll_handle: ScrollHandle, scroll_handle: ScrollHandle,
remote_project_store: Model<remote_projects::Store>, dev_server_store: Model<dev_server_projects::Store>,
remote_project_path_input: View<TextField>, project_path_input: View<TextField>,
dev_server_name_input: View<TextField>, dev_server_name_input: View<TextField>,
_subscription: gpui::Subscription, _subscription: gpui::Subscription,
} }
@ -36,19 +36,19 @@ struct CreateDevServer {
dev_server: Option<CreateDevServerResponse>, dev_server: Option<CreateDevServerResponse>,
} }
struct CreateRemoteProject { struct CreateDevServerProject {
dev_server_id: DevServerId, dev_server_id: DevServerId,
creating: bool, creating: bool,
remote_project: Option<proto::RemoteProject>, dev_server_project: Option<proto::DevServerProject>,
} }
enum Mode { enum Mode {
Default, Default,
CreateRemoteProject(CreateRemoteProject), CreateDevServerProject(CreateDevServerProject),
CreateDevServer(CreateDevServer), CreateDevServer(CreateDevServer),
} }
impl RemoteProjects { impl DevServerProjects {
pub fn register(_: &mut Workspace, cx: &mut ViewContext<Workspace>) { pub fn register(_: &mut Workspace, cx: &mut ViewContext<Workspace>) {
cx.observe_flag::<feature_flags::Remoting, _>(|enabled, workspace, _| { cx.observe_flag::<feature_flags::Remoting, _>(|enabled, workspace, _| {
if enabled { if enabled {
@ -67,14 +67,14 @@ impl RemoteProjects {
} }
pub fn new(cx: &mut ViewContext<Self>) -> Self { pub fn new(cx: &mut ViewContext<Self>) -> Self {
let remote_project_path_input = cx.new_view(|cx| TextField::new(cx, "", "Project path")); let project_path_input = cx.new_view(|cx| TextField::new(cx, "", "Project path"));
let dev_server_name_input = let dev_server_name_input =
cx.new_view(|cx| TextField::new(cx, "Name", "").with_label(FieldLabelLayout::Stacked)); cx.new_view(|cx| TextField::new(cx, "Name", "").with_label(FieldLabelLayout::Stacked));
let focus_handle = cx.focus_handle(); let focus_handle = cx.focus_handle();
let remote_project_store = remote_projects::Store::global(cx); let dev_server_store = dev_server_projects::Store::global(cx);
let subscription = cx.observe(&remote_project_store, |_, _, cx| { let subscription = cx.observe(&dev_server_store, |_, _, cx| {
cx.notify(); cx.notify();
}); });
@ -82,20 +82,20 @@ impl RemoteProjects {
mode: Mode::Default, mode: Mode::Default,
focus_handle, focus_handle,
scroll_handle: ScrollHandle::new(), scroll_handle: ScrollHandle::new(),
remote_project_store, dev_server_store,
remote_project_path_input, project_path_input,
dev_server_name_input, dev_server_name_input,
_subscription: subscription, _subscription: subscription,
} }
} }
pub fn create_remote_project( pub fn create_dev_server_project(
&mut self, &mut self,
dev_server_id: DevServerId, dev_server_id: DevServerId,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) { ) {
let path = self let path = self
.remote_project_path_input .project_path_input
.read(cx) .read(cx)
.editor() .editor()
.read(cx) .read(cx)
@ -108,9 +108,9 @@ impl RemoteProjects {
} }
if self if self
.remote_project_store .dev_server_store
.read(cx) .read(cx)
.remote_projects_for_server(dev_server_id) .projects_for_server(dev_server_id)
.iter() .iter()
.any(|p| p.path == path) .any(|p| p.path == path)
{ {
@ -132,19 +132,22 @@ impl RemoteProjects {
let create = { let create = {
let path = path.clone(); let path = path.clone();
self.remote_project_store.update(cx, |store, cx| { self.dev_server_store.update(cx, |store, cx| {
store.create_remote_project(dev_server_id, path, cx) store.create_dev_server_project(dev_server_id, path, cx)
}) })
}; };
cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
let result = create.await; let result = create.await;
let remote_project = result.as_ref().ok().and_then(|r| r.remote_project.clone()); let dev_server_project = result
.as_ref()
.ok()
.and_then(|r| r.dev_server_project.clone());
this.update(&mut cx, |this, _| { this.update(&mut cx, |this, _| {
this.mode = Mode::CreateRemoteProject(CreateRemoteProject { this.mode = Mode::CreateDevServerProject(CreateDevServerProject {
dev_server_id, dev_server_id,
creating: false, creating: false,
remote_project, dev_server_project,
}); });
}) })
.log_err(); .log_err();
@ -156,23 +159,23 @@ impl RemoteProjects {
"The dev server is offline. Please log in and check it is connected." "The dev server is offline. Please log in and check it is connected."
.to_string(), .to_string(),
), ),
ErrorCode::RemoteProjectPathDoesNotExist => { ErrorCode::DevServerProjectPathDoesNotExist => {
Some(format!("The path `{}` does not exist on the server.", path)) Some(format!("The path `{}` does not exist on the server.", path))
} }
_ => None, _ => None,
} }
}); });
self.remote_project_path_input.update(cx, |input, cx| { self.project_path_input.update(cx, |input, cx| {
input.editor().update(cx, |editor, cx| { input.editor().update(cx, |editor, cx| {
editor.set_text("", cx); editor.set_text("", cx);
}); });
}); });
self.mode = Mode::CreateRemoteProject(CreateRemoteProject { self.mode = Mode::CreateDevServerProject(CreateDevServerProject {
dev_server_id, dev_server_id,
creating: true, creating: true,
remote_project: None, dev_server_project: None,
}); });
} }
@ -191,7 +194,7 @@ impl RemoteProjects {
} }
let dev_server = self let dev_server = self
.remote_project_store .dev_server_store
.update(cx, |store, cx| store.create_dev_server(name.clone(), cx)); .update(cx, |store, cx| store.create_dev_server(name.clone(), cx));
cx.spawn(|this, mut cx| async move { cx.spawn(|this, mut cx| async move {
@ -236,7 +239,7 @@ impl RemoteProjects {
} }
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.remote_project_store this.dev_server_store
.update(cx, |store, cx| store.delete_dev_server(id, cx)) .update(cx, |store, cx| store.delete_dev_server(id, cx))
})? })?
.await .await
@ -247,8 +250,8 @@ impl RemoteProjects {
fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) { fn confirm(&mut self, _: &menu::Confirm, cx: &mut ViewContext<Self>) {
match self.mode { match self.mode {
Mode::Default => {} Mode::Default => {}
Mode::CreateRemoteProject(CreateRemoteProject { dev_server_id, .. }) => { Mode::CreateDevServerProject(CreateDevServerProject { dev_server_id, .. }) => {
self.create_remote_project(dev_server_id, cx); self.create_dev_server_project(dev_server_id, cx);
} }
Mode::CreateDevServer(_) => { Mode::CreateDevServer(_) => {
self.create_dev_server(cx); self.create_dev_server(cx);
@ -259,7 +262,7 @@ impl RemoteProjects {
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) { fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
match self.mode { match self.mode {
Mode::Default => cx.emit(DismissEvent), Mode::Default => cx.emit(DismissEvent),
Mode::CreateRemoteProject(_) | Mode::CreateDevServer(_) => { Mode::CreateDevServerProject(_) | Mode::CreateDevServer(_) => {
self.mode = Mode::Default; self.mode = Mode::Default;
self.focus_handle(cx).focus(cx); self.focus_handle(cx).focus(cx);
cx.notify(); cx.notify();
@ -338,15 +341,13 @@ impl RemoteProjects {
.tooltip(|cx| Tooltip::text("Add a remote project", cx)) .tooltip(|cx| Tooltip::text("Add a remote project", cx))
.on_click(cx.listener( .on_click(cx.listener(
move |this, _, cx| { move |this, _, cx| {
this.mode = Mode::CreateRemoteProject(CreateRemoteProject { this.mode =
dev_server_id, Mode::CreateDevServerProject(CreateDevServerProject {
creating: false, dev_server_id,
remote_project: None, creating: false,
}); dev_server_project: None,
this.remote_project_path_input });
.read(cx) this.project_path_input.read(cx).focus_handle(cx).focus(cx);
.focus_handle(cx)
.focus(cx);
cx.notify(); cx.notify();
}, },
)), )),
@ -365,26 +366,26 @@ impl RemoteProjects {
.px_3() .px_3()
.child( .child(
List::new().empty_message("No projects.").children( List::new().empty_message("No projects.").children(
self.remote_project_store self.dev_server_store
.read(cx) .read(cx)
.remote_projects_for_server(dev_server.id) .projects_for_server(dev_server.id)
.iter() .iter()
.map(|p| self.render_remote_project(p, cx)), .map(|p| self.render_dev_server_project(p, cx)),
), ),
), ),
) )
} }
fn render_remote_project( fn render_dev_server_project(
&mut self, &mut self,
project: &RemoteProject, project: &DevServerProject,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> impl IntoElement { ) -> impl IntoElement {
let remote_project_id = project.id; let dev_server_project_id = project.id;
let project_id = project.project_id; let project_id = project.project_id;
let is_online = project_id.is_some(); let is_online = project_id.is_some();
ListItem::new(("remote-project", remote_project_id.0)) ListItem::new(("remote-project", dev_server_project_id.0))
.start_slot(Icon::new(IconName::FileTree).when(!is_online, |icon| icon.color(Color::Muted))) .start_slot(Icon::new(IconName::FileTree).when(!is_online, |icon| icon.color(Color::Muted)))
.child( .child(
Label::new(project.path.clone()) Label::new(project.path.clone())
@ -392,7 +393,7 @@ impl RemoteProjects {
.on_click(cx.listener(move |_, _, cx| { .on_click(cx.listener(move |_, _, cx| {
if let Some(project_id) = project_id { if let Some(project_id) = project_id {
if let Some(app_state) = AppState::global(cx).upgrade() { if let Some(app_state) = AppState::global(cx).upgrade() {
workspace::join_remote_project(project_id, app_state, None, cx) workspace::join_dev_server_project(project_id, app_state, None, cx)
.detach_and_prompt_err("Could not join project", cx, |_, _| None) .detach_and_prompt_err("Could not join project", cx, |_, _| None)
} }
} else { } else {
@ -471,7 +472,7 @@ impl RemoteProjects {
}) })
.when_some(dev_server.clone(), |div, dev_server| { .when_some(dev_server.clone(), |div, dev_server| {
let status = self let status = self
.remote_project_store .dev_server_store
.read(cx) .read(cx)
.dev_server_status(DevServerId(dev_server.dev_server_id)); .dev_server_status(DevServerId(dev_server.dev_server_id));
@ -556,7 +557,7 @@ impl RemoteProjects {
} }
fn render_default(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render_default(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let dev_servers = self.remote_project_store.read(cx).dev_servers(); let dev_servers = self.dev_server_store.read(cx).dev_servers();
v_flex() v_flex()
.id("scroll-container") .id("scroll-container")
@ -602,18 +603,18 @@ impl RemoteProjects {
) )
} }
fn render_create_remote_project(&self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render_create_dev_server_project(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
let Mode::CreateRemoteProject(CreateRemoteProject { let Mode::CreateDevServerProject(CreateDevServerProject {
dev_server_id, dev_server_id,
creating, creating,
remote_project, dev_server_project,
}) = &self.mode }) = &self.mode
else { else {
unreachable!() unreachable!()
}; };
let dev_server = self let dev_server = self
.remote_project_store .dev_server_store
.read(cx) .read(cx)
.dev_server(*dev_server_id) .dev_server(*dev_server_id)
.cloned(); .cloned();
@ -672,12 +673,12 @@ impl RemoteProjects {
h_flex() h_flex()
.ml_5() .ml_5()
.gap_2() .gap_2()
.child(self.remote_project_path_input.clone()) .child(self.project_path_input.clone())
.when(!*creating && remote_project.is_none(), |div| { .when(!*creating && dev_server_project.is_none(), |div| {
div.child(Button::new("create-remote-server", "Create").on_click({ div.child(Button::new("create-remote-server", "Create").on_click({
let dev_server_id = *dev_server_id; let dev_server_id = *dev_server_id;
cx.listener(move |this, _, cx| { cx.listener(move |this, _, cx| {
this.create_remote_project(dev_server_id, cx) this.create_dev_server_project(dev_server_id, cx)
}) })
})) }))
}) })
@ -685,11 +686,11 @@ impl RemoteProjects {
div.child(Button::new("create-dev-server", "Creating...").disabled(true)) div.child(Button::new("create-dev-server", "Creating...").disabled(true))
}), }),
) )
.when_some(remote_project.clone(), |div, remote_project| { .when_some(dev_server_project.clone(), |div, dev_server_project| {
let status = self let status = self
.remote_project_store .dev_server_store
.read(cx) .read(cx)
.remote_project(RemoteProjectId(remote_project.id)) .dev_server_project(DevServerProjectId(dev_server_project.id))
.map(|project| { .map(|project| {
if project.project_id.is_some() { if project.project_id.is_some() {
DevServerStatus::Online DevServerStatus::Online
@ -717,17 +718,17 @@ impl RemoteProjects {
}) })
} }
} }
impl ModalView for RemoteProjects {} impl ModalView for DevServerProjects {}
impl FocusableView for RemoteProjects { impl FocusableView for DevServerProjects {
fn focus_handle(&self, _cx: &AppContext) -> FocusHandle { fn focus_handle(&self, _cx: &AppContext) -> FocusHandle {
self.focus_handle.clone() self.focus_handle.clone()
} }
} }
impl EventEmitter<DismissEvent> for RemoteProjects {} impl EventEmitter<DismissEvent> for DevServerProjects {}
impl Render for RemoteProjects { impl Render for DevServerProjects {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement { fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
div() div()
.track_focus(&self.focus_handle) .track_focus(&self.focus_handle)
@ -746,8 +747,8 @@ impl Render for RemoteProjects {
.max_h(rems(40.)) .max_h(rems(40.))
.child(match &self.mode { .child(match &self.mode {
Mode::Default => self.render_default(cx).into_any_element(), Mode::Default => self.render_default(cx).into_any_element(),
Mode::CreateRemoteProject(_) => { Mode::CreateDevServerProject(_) => {
self.render_create_remote_project(cx).into_any_element() self.render_create_dev_server_project(cx).into_any_element()
} }
Mode::CreateDevServer(_) => self.render_create_dev_server(cx).into_any_element(), Mode::CreateDevServer(_) => self.render_create_dev_server(cx).into_any_element(),
}) })

View File

@ -1,5 +1,6 @@
mod remote_projects; mod dev_servers;
pub use dev_servers::DevServerProjects;
use feature_flags::FeatureFlagAppExt; use feature_flags::FeatureFlagAppExt;
use fuzzy::{StringMatch, StringMatchCandidate}; use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{ use gpui::{
@ -11,7 +12,6 @@ use picker::{
highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText}, highlighted_match_with_paths::{HighlightedMatchWithPaths, HighlightedText},
Picker, PickerDelegate, Picker, PickerDelegate,
}; };
pub use remote_projects::RemoteProjects;
use rpc::proto::DevServerStatus; use rpc::proto::DevServerStatus;
use serde::Deserialize; use serde::Deserialize;
use std::{ use std::{
@ -42,8 +42,7 @@ gpui::actions!(projects, [OpenRemote]);
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
cx.observe_new_views(RecentProjects::register).detach(); cx.observe_new_views(RecentProjects::register).detach();
cx.observe_new_views(remote_projects::RemoteProjects::register) cx.observe_new_views(DevServerProjects::register).detach();
.detach();
} }
pub struct RecentProjects { pub struct RecentProjects {
@ -158,7 +157,7 @@ pub struct RecentProjectsDelegate {
create_new_window: bool, create_new_window: bool,
// Flag to reset index when there is a new query vs not reset index when user delete an item // Flag to reset index when there is a new query vs not reset index when user delete an item
reset_selected_match_index: bool, reset_selected_match_index: bool,
has_any_remote_projects: bool, has_any_dev_server_projects: bool,
} }
impl RecentProjectsDelegate { impl RecentProjectsDelegate {
@ -171,16 +170,16 @@ impl RecentProjectsDelegate {
create_new_window, create_new_window,
render_paths, render_paths,
reset_selected_match_index: true, reset_selected_match_index: true,
has_any_remote_projects: false, has_any_dev_server_projects: false,
} }
} }
pub fn set_workspaces(&mut self, workspaces: Vec<(WorkspaceId, SerializedWorkspaceLocation)>) { pub fn set_workspaces(&mut self, workspaces: Vec<(WorkspaceId, SerializedWorkspaceLocation)>) {
self.workspaces = workspaces; self.workspaces = workspaces;
self.has_any_remote_projects = self self.has_any_dev_server_projects = self
.workspaces .workspaces
.iter() .iter()
.any(|(_, location)| matches!(location, SerializedWorkspaceLocation::Remote(_))); .any(|(_, location)| matches!(location, SerializedWorkspaceLocation::DevServer(_)));
} }
} }
impl EventEmitter<DismissEvent> for RecentProjectsDelegate {} impl EventEmitter<DismissEvent> for RecentProjectsDelegate {}
@ -235,8 +234,11 @@ impl PickerDelegate for RecentProjectsDelegate {
.map(|path| path.compact().to_string_lossy().into_owned()) .map(|path| path.compact().to_string_lossy().into_owned())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(""), .join(""),
SerializedWorkspaceLocation::Remote(remote_project) => { SerializedWorkspaceLocation::DevServer(dev_server_project) => {
format!("{}{}", remote_project.dev_server_name, remote_project.path) format!(
"{}{}",
dev_server_project.dev_server_name, dev_server_project.path
)
} }
}; };
@ -310,13 +312,13 @@ impl PickerDelegate for RecentProjectsDelegate {
workspace.open_workspace_for_paths(false, paths, cx) workspace.open_workspace_for_paths(false, paths, cx)
} }
} }
SerializedWorkspaceLocation::Remote(remote_project) => { SerializedWorkspaceLocation::DevServer(dev_server_project) => {
let store = ::remote_projects::Store::global(cx).read(cx); let store = dev_server_projects::Store::global(cx).read(cx);
let Some(project_id) = store let Some(project_id) = store
.remote_project(remote_project.id) .dev_server_project(dev_server_project.id)
.and_then(|p| p.project_id) .and_then(|p| p.project_id)
else { else {
let dev_server_name = remote_project.dev_server_name.clone(); let dev_server_name = dev_server_project.dev_server_name.clone();
return cx.spawn(|workspace, mut cx| async move { return cx.spawn(|workspace, mut cx| async move {
let response = let response =
cx.prompt(gpui::PromptLevel::Warning, cx.prompt(gpui::PromptLevel::Warning,
@ -326,7 +328,7 @@ impl PickerDelegate for RecentProjectsDelegate {
).await?; ).await?;
if response == 1 { if response == 1 {
workspace.update(&mut cx, |workspace, cx| { workspace.update(&mut cx, |workspace, cx| {
workspace.toggle_modal(cx, |cx| RemoteProjects::new(cx)) workspace.toggle_modal(cx, |cx| DevServerProjects::new(cx))
})?; })?;
} else { } else {
workspace.update(&mut cx, |workspace, cx| { workspace.update(&mut cx, |workspace, cx| {
@ -354,7 +356,7 @@ impl PickerDelegate for RecentProjectsDelegate {
if continue_replacing { if continue_replacing {
workspace workspace
.update(&mut cx, |_workspace, cx| { .update(&mut cx, |_workspace, cx| {
workspace::join_remote_project(project_id, app_state, Some(handle), cx) workspace::join_dev_server_project(project_id, app_state, Some(handle), cx)
})? })?
.await?; .await?;
} }
@ -363,7 +365,7 @@ impl PickerDelegate for RecentProjectsDelegate {
} }
else { else {
let task = let task =
workspace::join_remote_project(project_id, app_state, None, cx); workspace::join_dev_server_project(project_id, app_state, None, cx);
cx.spawn(|_, _| async move { cx.spawn(|_, _| async move {
task.await?; task.await?;
Ok(()) Ok(())
@ -404,13 +406,13 @@ impl PickerDelegate for RecentProjectsDelegate {
let (workspace_id, location) = &self.workspaces[hit.candidate_id]; let (workspace_id, location) = &self.workspaces[hit.candidate_id];
let is_current_workspace = self.is_current_workspace(*workspace_id, cx); let is_current_workspace = self.is_current_workspace(*workspace_id, cx);
let is_remote = matches!(location, SerializedWorkspaceLocation::Remote(_)); let is_remote = matches!(location, SerializedWorkspaceLocation::DevServer(_));
let dev_server_status = let dev_server_status =
if let SerializedWorkspaceLocation::Remote(remote_project) = location { if let SerializedWorkspaceLocation::DevServer(dev_server_project) = location {
let store = ::remote_projects::Store::global(cx).read(cx); let store = dev_server_projects::Store::global(cx).read(cx);
Some( Some(
store store
.remote_project(remote_project.id) .dev_server_project(dev_server_project.id)
.and_then(|p| store.dev_server(p.dev_server_id)) .and_then(|p| store.dev_server(p.dev_server_id))
.map(|s| s.status) .map(|s| s.status)
.unwrap_or_default(), .unwrap_or_default(),
@ -422,9 +424,12 @@ impl PickerDelegate for RecentProjectsDelegate {
let mut path_start_offset = 0; let mut path_start_offset = 0;
let paths = match location { let paths = match location {
SerializedWorkspaceLocation::Local(paths) => paths.paths(), SerializedWorkspaceLocation::Local(paths) => paths.paths(),
SerializedWorkspaceLocation::Remote(remote_project) => Arc::new(vec![PathBuf::from( SerializedWorkspaceLocation::DevServer(dev_server_project) => {
format!("{}:{}", remote_project.dev_server_name, remote_project.path), Arc::new(vec![PathBuf::from(format!(
)]), "{}:{}",
dev_server_project.dev_server_name, dev_server_project.path
))])
}
}; };
let (match_labels, paths): (Vec<_>, Vec<_>) = paths let (match_labels, paths): (Vec<_>, Vec<_>) = paths
@ -459,7 +464,7 @@ impl PickerDelegate for RecentProjectsDelegate {
h_flex() h_flex()
.flex_grow() .flex_grow()
.gap_3() .gap_3()
.when(self.has_any_remote_projects, |this| { .when(self.has_any_dev_server_projects, |this| {
this.child(if is_remote { this.child(if is_remote {
// if disabled, Color::Disabled // if disabled, Color::Disabled
let indicator_color = match dev_server_status { let indicator_color = match dev_server_status {
@ -540,7 +545,7 @@ impl PickerDelegate for RecentProjectsDelegate {
.when_some(KeyBinding::for_action(&OpenRemote, cx), |button, key| { .when_some(KeyBinding::for_action(&OpenRemote, cx), |button, key| {
button.child(key) button.child(key)
}) })
.child(Label::new("Connect remote").color(Color::Muted)) .child(Label::new("Connect").color(Color::Muted))
.on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())), .on_click(|_, cx| cx.dispatch_action(OpenRemote.boxed_clone())),
) )
.child( .child(

View File

@ -220,8 +220,8 @@ message Envelope {
MultiLspQuery multi_lsp_query = 175; MultiLspQuery multi_lsp_query = 175;
MultiLspQueryResponse multi_lsp_query_response = 176; MultiLspQueryResponse multi_lsp_query_response = 176;
CreateRemoteProject create_remote_project = 177; CreateDevServerProject create_dev_server_project = 177;
CreateRemoteProjectResponse create_remote_project_response = 188; CreateDevServerProjectResponse create_dev_server_project_response = 188;
CreateDevServer create_dev_server = 178; CreateDevServer create_dev_server = 178;
CreateDevServerResponse create_dev_server_response = 179; CreateDevServerResponse create_dev_server_response = 179;
ShutdownDevServer shutdown_dev_server = 180; ShutdownDevServer shutdown_dev_server = 180;
@ -229,13 +229,13 @@ message Envelope {
ReconnectDevServer reconnect_dev_server = 182; ReconnectDevServer reconnect_dev_server = 182;
ReconnectDevServerResponse reconnect_dev_server_response = 183; ReconnectDevServerResponse reconnect_dev_server_response = 183;
ShareRemoteProject share_remote_project = 184; ShareDevServerProject share_dev_server_project = 184;
JoinRemoteProject join_remote_project = 185; JoinDevServerProject join_dev_server_project = 185;
RejoinRemoteProjects rejoin_remote_projects = 186; RejoinRemoteProjects rejoin_remote_projects = 186;
RejoinRemoteProjectsResponse rejoin_remote_projects_response = 187; RejoinRemoteProjectsResponse rejoin_remote_projects_response = 187;
RemoteProjectsUpdate remote_projects_update = 193; DevServerProjectsUpdate dev_server_projects_update = 193;
ValidateRemoteProjectRequest validate_remote_project_request = 194; ValidateDevServerProjectRequest validate_dev_server_project_request = 194;
DeleteDevServer delete_dev_server = 195; DeleteDevServer delete_dev_server = 195;
OpenNewBuffer open_new_buffer = 196; // Current max OpenNewBuffer open_new_buffer = 196; // Current max
} }
@ -275,7 +275,7 @@ enum ErrorCode {
NoSuchProject = 13; NoSuchProject = 13;
DevServerAlreadyOnline = 14; DevServerAlreadyOnline = 14;
DevServerOffline = 15; DevServerOffline = 15;
RemoteProjectPathDoesNotExist = 16; DevServerProjectPathDoesNotExist = 16;
RemoteUpgradeRequired = 17; RemoteUpgradeRequired = 17;
reserved 6; reserved 6;
} }
@ -441,7 +441,7 @@ message LiveKitConnectionInfo {
message ShareProject { message ShareProject {
uint64 room_id = 1; uint64 room_id = 1;
repeated WorktreeMetadata worktrees = 2; repeated WorktreeMetadata worktrees = 2;
optional uint64 remote_project_id = 3; optional uint64 dev_server_project_id = 3;
} }
message ShareProjectResponse { message ShareProjectResponse {
@ -465,17 +465,17 @@ message JoinHostedProject {
uint64 project_id = 1; uint64 project_id = 1;
} }
message CreateRemoteProject { message CreateDevServerProject {
reserved 1; reserved 1;
reserved 2; reserved 2;
uint64 dev_server_id = 3; uint64 dev_server_id = 3;
string path = 4; string path = 4;
} }
message CreateRemoteProjectResponse { message CreateDevServerProjectResponse {
RemoteProject remote_project = 1; DevServerProject dev_server_project = 1;
} }
message ValidateRemoteProjectRequest { message ValidateDevServerProjectRequest {
string path = 1; string path = 1;
} }
@ -507,21 +507,21 @@ message ReconnectDevServerResponse {
} }
message DevServerInstructions { message DevServerInstructions {
repeated RemoteProject projects = 1; repeated DevServerProject projects = 1;
} }
message RemoteProjectsUpdate { message DevServerProjectsUpdate {
repeated DevServer dev_servers = 1; repeated DevServer dev_servers = 1;
repeated RemoteProject remote_projects = 2; repeated DevServerProject dev_server_projects = 2;
} }
message ShareRemoteProject { message ShareDevServerProject {
uint64 remote_project_id = 1; uint64 dev_server_project_id = 1;
repeated WorktreeMetadata worktrees = 2; repeated WorktreeMetadata worktrees = 2;
} }
message JoinRemoteProject { message JoinDevServerProject {
uint64 remote_project_id = 1; uint64 dev_server_project_id = 1;
} }
message JoinProjectResponse { message JoinProjectResponse {
@ -531,7 +531,7 @@ message JoinProjectResponse {
repeated Collaborator collaborators = 3; repeated Collaborator collaborators = 3;
repeated LanguageServer language_servers = 4; repeated LanguageServer language_servers = 4;
ChannelRole role = 6; ChannelRole role = 6;
optional uint64 remote_project_id = 7; optional uint64 dev_server_project_id = 7;
} }
message LeaveProject { message LeaveProject {
@ -1211,7 +1211,7 @@ message HostedProject {
ChannelVisibility visibility = 4; ChannelVisibility visibility = 4;
} }
message RemoteProject { message DevServerProject {
uint64 id = 1; uint64 id = 1;
optional uint64 project_id = 2; optional uint64 project_id = 2;
reserved 3; reserved 3;

View File

@ -303,22 +303,22 @@ messages!(
(SetRoomParticipantRole, Foreground), (SetRoomParticipantRole, Foreground),
(BlameBuffer, Foreground), (BlameBuffer, Foreground),
(BlameBufferResponse, Foreground), (BlameBufferResponse, Foreground),
(CreateRemoteProject, Background), (CreateDevServerProject, Background),
(CreateRemoteProjectResponse, Foreground), (CreateDevServerProjectResponse, Foreground),
(CreateDevServer, Foreground), (CreateDevServer, Foreground),
(CreateDevServerResponse, Foreground), (CreateDevServerResponse, Foreground),
(DevServerInstructions, Foreground), (DevServerInstructions, Foreground),
(ShutdownDevServer, Foreground), (ShutdownDevServer, Foreground),
(ReconnectDevServer, Foreground), (ReconnectDevServer, Foreground),
(ReconnectDevServerResponse, Foreground), (ReconnectDevServerResponse, Foreground),
(ShareRemoteProject, Foreground), (ShareDevServerProject, Foreground),
(JoinRemoteProject, Foreground), (JoinDevServerProject, Foreground),
(RejoinRemoteProjects, Foreground), (RejoinRemoteProjects, Foreground),
(RejoinRemoteProjectsResponse, Foreground), (RejoinRemoteProjectsResponse, Foreground),
(MultiLspQuery, Background), (MultiLspQuery, Background),
(MultiLspQueryResponse, Background), (MultiLspQueryResponse, Background),
(RemoteProjectsUpdate, Foreground), (DevServerProjectsUpdate, Foreground),
(ValidateRemoteProjectRequest, Background), (ValidateDevServerProjectRequest, Background),
(DeleteDevServer, Foreground), (DeleteDevServer, Foreground),
(OpenNewBuffer, Foreground) (OpenNewBuffer, Foreground)
); );
@ -415,14 +415,14 @@ request_messages!(
(LspExtExpandMacro, LspExtExpandMacroResponse), (LspExtExpandMacro, LspExtExpandMacroResponse),
(SetRoomParticipantRole, Ack), (SetRoomParticipantRole, Ack),
(BlameBuffer, BlameBufferResponse), (BlameBuffer, BlameBufferResponse),
(CreateRemoteProject, CreateRemoteProjectResponse), (CreateDevServerProject, CreateDevServerProjectResponse),
(CreateDevServer, CreateDevServerResponse), (CreateDevServer, CreateDevServerResponse),
(ShutdownDevServer, Ack), (ShutdownDevServer, Ack),
(ShareRemoteProject, ShareProjectResponse), (ShareDevServerProject, ShareProjectResponse),
(JoinRemoteProject, JoinProjectResponse), (JoinDevServerProject, JoinProjectResponse),
(RejoinRemoteProjects, RejoinRemoteProjectsResponse), (RejoinRemoteProjects, RejoinRemoteProjectsResponse),
(ReconnectDevServer, ReconnectDevServerResponse), (ReconnectDevServer, ReconnectDevServerResponse),
(ValidateRemoteProjectRequest, Ack), (ValidateDevServerProjectRequest, Ack),
(MultiLspQuery, MultiLspQueryResponse), (MultiLspQuery, MultiLspQueryResponse),
(DeleteDevServer, Ack), (DeleteDevServer, Ack),
); );

View File

@ -223,6 +223,14 @@ fn parse_alter_table(remaining_sql_str: &str) -> Option<(String, String)> {
.skip_while(|c| c.is_whitespace()) .skip_while(|c| c.is_whitespace())
.take_while(|c| !c.is_whitespace()) .take_while(|c| !c.is_whitespace())
.collect::<String>() .collect::<String>()
} else if let Some(drop_offset) = remaining_sql_str.find("drop column") {
let after_drop_offset = drop_offset + "drop column".len();
remaining_sql_str
.chars()
.skip(after_drop_offset)
.skip_while(|c| c.is_whitespace())
.take_while(|c| !c.is_whitespace())
.collect::<String>()
} else { } else {
"__place_holder_column_for_syntax_checking".to_string() "__place_holder_column_for_syntax_checking".to_string()
}; };

View File

@ -45,7 +45,7 @@ node_runtime.workspace = true
parking_lot.workspace = true parking_lot.workspace = true
postage.workspace = true postage.workspace = true
project.workspace = true project.workspace = true
remote_projects.workspace = true dev_server_projects.workspace = true
task.workspace = true task.workspace = true
schemars.workspace = true schemars.workspace = true
serde.workspace = true serde.workspace = true

View File

@ -3,7 +3,7 @@ pub mod model;
use std::path::Path; use std::path::Path;
use anyhow::{anyhow, bail, Context, Result}; use anyhow::{anyhow, bail, Context, Result};
use client::RemoteProjectId; use client::DevServerProjectId;
use db::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql}; use db::{define_connection, query, sqlez::connection::Connection, sqlez_macros::sql};
use gpui::{point, size, Axis, Bounds}; use gpui::{point, size, Axis, Bounds};
@ -22,7 +22,7 @@ use model::{
SerializedWorkspace, SerializedWorkspace,
}; };
use self::model::{DockStructure, SerializedRemoteProject, SerializedWorkspaceLocation}; use self::model::{DockStructure, SerializedDevServerProject, SerializedWorkspaceLocation};
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
pub(crate) struct SerializedAxis(pub(crate) gpui::Axis); pub(crate) struct SerializedAxis(pub(crate) gpui::Axis);
@ -299,6 +299,16 @@ define_connection! {
ALTER TABLE workspaces ADD COLUMN remote_project_id INTEGER; ALTER TABLE workspaces ADD COLUMN remote_project_id INTEGER;
ALTER TABLE workspaces RENAME COLUMN workspace_location TO local_paths; ALTER TABLE workspaces RENAME COLUMN workspace_location TO local_paths;
), ),
sql!(
DROP TABLE remote_projects;
CREATE TABLE dev_server_projects (
id INTEGER NOT NULL UNIQUE,
path TEXT,
dev_server_name TEXT
);
ALTER TABLE workspaces DROP COLUMN remote_project_id;
ALTER TABLE workspaces ADD COLUMN dev_server_project_id INTEGER;
),
]; ];
} }
@ -317,7 +327,7 @@ impl WorkspaceDb {
let ( let (
workspace_id, workspace_id,
local_paths, local_paths,
remote_project_id, dev_server_project_id,
bounds, bounds,
display, display,
fullscreen, fullscreen,
@ -337,7 +347,7 @@ impl WorkspaceDb {
SELECT SELECT
workspace_id, workspace_id,
local_paths, local_paths,
remote_project_id, dev_server_project_id,
window_state, window_state,
window_x, window_x,
window_y, window_y,
@ -363,18 +373,18 @@ impl WorkspaceDb {
.warn_on_err() .warn_on_err()
.flatten()?; .flatten()?;
let location = if let Some(remote_project_id) = remote_project_id { let location = if let Some(dev_server_project_id) = dev_server_project_id {
let remote_project: SerializedRemoteProject = self let dev_server_project: SerializedDevServerProject = self
.select_row_bound(sql! { .select_row_bound(sql! {
SELECT remote_project_id, path, dev_server_name SELECT id, path, dev_server_name
FROM remote_projects FROM dev_server_projects
WHERE remote_project_id = ? WHERE id = ?
}) })
.and_then(|mut prepared_statement| (prepared_statement)(remote_project_id)) .and_then(|mut prepared_statement| (prepared_statement)(dev_server_project_id))
.context("No remote project found") .context("No remote project found")
.warn_on_err() .warn_on_err()
.flatten()?; .flatten()?;
SerializedWorkspaceLocation::Remote(remote_project) SerializedWorkspaceLocation::DevServer(dev_server_project)
} else if let Some(local_paths) = local_paths { } else if let Some(local_paths) = local_paths {
SerializedWorkspaceLocation::Local(local_paths) SerializedWorkspaceLocation::Local(local_paths)
} else { } else {
@ -447,15 +457,15 @@ impl WorkspaceDb {
))?((workspace.id, &local_paths, workspace.docks)) ))?((workspace.id, &local_paths, workspace.docks))
.context("Updating workspace")?; .context("Updating workspace")?;
} }
SerializedWorkspaceLocation::Remote(remote_project) => { SerializedWorkspaceLocation::DevServer(dev_server_project) => {
conn.exec_bound(sql!( conn.exec_bound(sql!(
DELETE FROM workspaces WHERE remote_project_id = ? AND workspace_id != ? DELETE FROM workspaces WHERE dev_server_project_id = ? AND workspace_id != ?
))?((remote_project.id.0, workspace.id)) ))?((dev_server_project.id.0, workspace.id))
.context("clearing out old locations")?; .context("clearing out old locations")?;
conn.exec_bound(sql!( conn.exec_bound(sql!(
INSERT INTO remote_projects( INSERT INTO dev_server_projects(
remote_project_id, id,
path, path,
dev_server_name dev_server_name
) VALUES (?1, ?2, ?3) ) VALUES (?1, ?2, ?3)
@ -463,13 +473,13 @@ impl WorkspaceDb {
UPDATE SET UPDATE SET
path = ?2, path = ?2,
dev_server_name = ?3 dev_server_name = ?3
))?(&remote_project)?; ))?(&dev_server_project)?;
// Upsert // Upsert
conn.exec_bound(sql!( conn.exec_bound(sql!(
INSERT INTO workspaces( INSERT INTO workspaces(
workspace_id, workspace_id,
remote_project_id, dev_server_project_id,
left_dock_visible, left_dock_visible,
left_dock_active_panel, left_dock_active_panel,
left_dock_zoom, left_dock_zoom,
@ -484,7 +494,7 @@ impl WorkspaceDb {
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, CURRENT_TIMESTAMP) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, CURRENT_TIMESTAMP)
ON CONFLICT DO ON CONFLICT DO
UPDATE SET UPDATE SET
remote_project_id = ?2, dev_server_project_id = ?2,
left_dock_visible = ?3, left_dock_visible = ?3,
left_dock_active_panel = ?4, left_dock_active_panel = ?4,
left_dock_zoom = ?5, left_dock_zoom = ?5,
@ -497,7 +507,7 @@ impl WorkspaceDb {
timestamp = CURRENT_TIMESTAMP timestamp = CURRENT_TIMESTAMP
))?(( ))?((
workspace.id, workspace.id,
remote_project.id.0, dev_server_project.id.0,
workspace.docks, workspace.docks,
)) ))
.context("Updating workspace")?; .context("Updating workspace")?;
@ -523,17 +533,17 @@ impl WorkspaceDb {
query! { query! {
fn recent_workspaces() -> Result<Vec<(WorkspaceId, LocalPaths, Option<u64>)>> { fn recent_workspaces() -> Result<Vec<(WorkspaceId, LocalPaths, Option<u64>)>> {
SELECT workspace_id, local_paths, remote_project_id SELECT workspace_id, local_paths, dev_server_project_id
FROM workspaces FROM workspaces
WHERE local_paths IS NOT NULL OR remote_project_id IS NOT NULL WHERE local_paths IS NOT NULL OR dev_server_project_id IS NOT NULL
ORDER BY timestamp DESC ORDER BY timestamp DESC
} }
} }
query! { query! {
fn remote_projects() -> Result<Vec<SerializedRemoteProject>> { fn dev_server_projects() -> Result<Vec<SerializedDevServerProject>> {
SELECT remote_project_id, path, dev_server_name SELECT id, path, dev_server_name
FROM remote_projects FROM dev_server_projects
} }
} }
@ -573,14 +583,15 @@ impl WorkspaceDb {
) -> Result<Vec<(WorkspaceId, SerializedWorkspaceLocation)>> { ) -> Result<Vec<(WorkspaceId, SerializedWorkspaceLocation)>> {
let mut result = Vec::new(); let mut result = Vec::new();
let mut delete_tasks = Vec::new(); let mut delete_tasks = Vec::new();
let remote_projects = self.remote_projects()?; let dev_server_projects = self.dev_server_projects()?;
for (id, location, remote_project_id) in self.recent_workspaces()? { for (id, location, dev_server_project_id) in self.recent_workspaces()? {
if let Some(remote_project_id) = remote_project_id.map(RemoteProjectId) { if let Some(dev_server_project_id) = dev_server_project_id.map(DevServerProjectId) {
if let Some(remote_project) = if let Some(dev_server_project) = dev_server_projects
remote_projects.iter().find(|rp| rp.id == remote_project_id) .iter()
.find(|rp| rp.id == dev_server_project_id)
{ {
result.push((id, remote_project.clone().into())); result.push((id, dev_server_project.clone().into()));
} else { } else {
delete_tasks.push(self.delete_workspace_by_id(id)); delete_tasks.push(self.delete_workspace_by_id(id));
} }
@ -607,7 +618,7 @@ impl WorkspaceDb {
.into_iter() .into_iter()
.filter_map(|(_, location)| match location { .filter_map(|(_, location)| match location {
SerializedWorkspaceLocation::Local(local_paths) => Some(local_paths), SerializedWorkspaceLocation::Local(local_paths) => Some(local_paths),
SerializedWorkspaceLocation::Remote(_) => None, SerializedWorkspaceLocation::DevServer(_) => None,
}) })
.next()) .next())
} }

View File

@ -2,7 +2,7 @@ use super::SerializedAxis;
use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId}; use crate::{item::ItemHandle, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use async_recursion::async_recursion; use async_recursion::async_recursion;
use client::RemoteProjectId; use client::DevServerProjectId;
use db::sqlez::{ use db::sqlez::{
bindable::{Bind, Column, StaticColumnCount}, bindable::{Bind, Column, StaticColumnCount},
statement::Statement, statement::Statement,
@ -18,8 +18,8 @@ use util::ResultExt;
use uuid::Uuid; use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct SerializedRemoteProject { pub struct SerializedDevServerProject {
pub id: RemoteProjectId, pub id: DevServerProjectId,
pub dev_server_name: String, pub dev_server_name: String,
pub path: String, pub path: String,
} }
@ -68,14 +68,14 @@ impl Column for LocalPaths {
} }
} }
impl From<SerializedRemoteProject> for SerializedWorkspaceLocation { impl From<SerializedDevServerProject> for SerializedWorkspaceLocation {
fn from(remote_project: SerializedRemoteProject) -> Self { fn from(dev_server_project: SerializedDevServerProject) -> Self {
Self::Remote(remote_project) Self::DevServer(dev_server_project)
} }
} }
impl StaticColumnCount for SerializedRemoteProject {} impl StaticColumnCount for SerializedDevServerProject {}
impl Bind for &SerializedRemoteProject { impl Bind for &SerializedDevServerProject {
fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> { fn bind(&self, statement: &Statement, start_index: i32) -> Result<i32> {
let next_index = statement.bind(&self.id.0, start_index)?; let next_index = statement.bind(&self.id.0, start_index)?;
let next_index = statement.bind(&self.dev_server_name, next_index)?; let next_index = statement.bind(&self.dev_server_name, next_index)?;
@ -83,14 +83,14 @@ impl Bind for &SerializedRemoteProject {
} }
} }
impl Column for SerializedRemoteProject { impl Column for SerializedDevServerProject {
fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> { fn column(statement: &mut Statement, start_index: i32) -> Result<(Self, i32)> {
let id = statement.column_int64(start_index)?; let id = statement.column_int64(start_index)?;
let dev_server_name = statement.column_text(start_index + 1)?.to_string(); let dev_server_name = statement.column_text(start_index + 1)?.to_string();
let path = statement.column_text(start_index + 2)?.to_string(); let path = statement.column_text(start_index + 2)?.to_string();
Ok(( Ok((
Self { Self {
id: RemoteProjectId(id as u64), id: DevServerProjectId(id as u64),
dev_server_name, dev_server_name,
path, path,
}, },
@ -102,7 +102,7 @@ impl Column for SerializedRemoteProject {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum SerializedWorkspaceLocation { pub enum SerializedWorkspaceLocation {
Local(LocalPaths), Local(LocalPaths),
Remote(SerializedRemoteProject), DevServer(SerializedDevServerProject),
} }
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]

View File

@ -47,7 +47,7 @@ pub use pane::*;
pub use pane_group::*; pub use pane_group::*;
use persistence::{model::SerializedWorkspace, SerializedWindowsBounds, DB}; use persistence::{model::SerializedWorkspace, SerializedWindowsBounds, DB};
pub use persistence::{ pub use persistence::{
model::{ItemId, LocalPaths, SerializedRemoteProject, SerializedWorkspaceLocation}, model::{ItemId, LocalPaths, SerializedDevServerProject, SerializedWorkspaceLocation},
WorkspaceDb, DB as WORKSPACE_DB, WorkspaceDb, DB as WORKSPACE_DB,
}; };
use postage::stream::Stream; use postage::stream::Stream;
@ -3644,18 +3644,19 @@ impl Workspace {
} else { } else {
None None
} }
} else if let Some(remote_project_id) = self.project().read(cx).remote_project_id() { } else if let Some(dev_server_project_id) = self.project().read(cx).dev_server_project_id()
let store = remote_projects::Store::global(cx).read(cx); {
let store = dev_server_projects::Store::global(cx).read(cx);
maybe!({ maybe!({
let project = store.remote_project(remote_project_id)?; let project = store.dev_server_project(dev_server_project_id)?;
let dev_server = store.dev_server(project.dev_server_id)?; let dev_server = store.dev_server(project.dev_server_id)?;
let remote_project = SerializedRemoteProject { let dev_server_project = SerializedDevServerProject {
id: remote_project_id, id: dev_server_project_id,
dev_server_name: dev_server.name.to_string(), dev_server_name: dev_server.name.to_string(),
path: project.path.to_string(), path: project.path.to_string(),
}; };
Some(SerializedWorkspaceLocation::Remote(remote_project)) Some(SerializedWorkspaceLocation::DevServer(dev_server_project))
}) })
} else { } else {
None None
@ -4537,7 +4538,7 @@ async fn join_channel_internal(
return None; return None;
} }
let project = workspace.project.read(cx); let project = workspace.project.read(cx);
if (project.is_local() || project.remote_project_id().is_some()) if (project.is_local() || project.dev_server_project_id().is_some())
&& project.visible_worktrees(cx).any(|tree| { && project.visible_worktrees(cx).any(|tree| {
tree.read(cx) tree.read(cx)
.root_entry() .root_entry()
@ -4883,7 +4884,7 @@ pub fn join_hosted_project(
}) })
} }
pub fn join_remote_project( pub fn join_dev_server_project(
project_id: ProjectId, project_id: ProjectId,
app_state: Arc<AppState>, app_state: Arc<AppState>,
window_to_replace: Option<WindowHandle<Workspace>>, window_to_replace: Option<WindowHandle<Workspace>>,

View File

@ -73,7 +73,7 @@ project_panel.workspace = true
project_symbols.workspace = true project_symbols.workspace = true
quick_action_bar.workspace = true quick_action_bar.workspace = true
recent_projects.workspace = true recent_projects.workspace = true
remote_projects.workspace = true dev_server_projects.workspace = true
release_channel.workspace = true release_channel.workspace = true
rope.workspace = true rope.workspace = true
search.workspace = true search.workspace = true

View File

@ -290,7 +290,7 @@ fn init_ui(args: Args) {
ThemeRegistry::global(cx), ThemeRegistry::global(cx),
cx, cx,
); );
remote_projects::init(client.clone(), cx); dev_server_projects::init(client.clone(), cx);
load_user_themes_in_background(fs.clone(), cx); load_user_themes_in_background(fs.clone(), cx);
watch_themes(fs.clone(), cx); watch_themes(fs.clone(), cx);