diff --git a/ide/src/js/lib/client/tasks/signArchives.js b/ide/src/js/lib/client/tasks/signArchives.js index 52a022c1bd25..c9ce600ccc3c 100644 --- a/ide/src/js/lib/client/tasks/signArchives.js +++ b/ide/src/js/lib/client/tasks/signArchives.js @@ -22,11 +22,13 @@ const resRoot = path.join(contentRoot, 'Resources') // TODO: Refactor this once we have a better wau to get the used engine version. // See the tracking issue for more information https://github.com/enso-org/ide/issues/1359 -const ENGINE = '0.2.11' +const ENGINE = '0.2.12' const ID = '"Developer ID Application: New Byte Order Sp. z o. o. (NM77WTZJFQ)"' // Placeholder name for temporary archives. const tmpArchive = 'temporary_archive.zip' +const GRAALVM = 'graalvm-ce-java11-21.1.0'; + // Helper to execute a command in a given directory and return the output. const run = (cmd, cwd) => child_process.execSync(cmd, { shell: true, cwd }).toString() @@ -126,115 +128,115 @@ const toSign = [ }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jartool.jmod', jarContent: ['bin/jarsigner', 'bin/jar'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jdeps.jmod', jarContent: ['bin/javap', 'bin/jdeprscan', 'bin/jdeps'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jstatd.jmod', jarContent: ['bin/jstatd'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.pack.jmod', jarContent: ['bin/unpack200', 'bin/pack200'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.hotspot.agent.jmod', jarContent: ['bin/jhsdb'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jfr.jmod', jarContent: ['bin/jfr'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.rmic.jmod', jarContent: ['bin/rmic'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'java.rmi.jmod', jarContent: ['bin/rmid', 'bin/rmiregistry'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'java.base.jmod', jarContent: ['bin/java', 'bin/keytool', 'lib/jspawnhelper'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jlink.jmod', jarContent: ['bin/jmod', 'bin/jlink', 'bin/jimage'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.scripting.nashorn.shell.jmod', jarContent: ['bin/jjs'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jcmd.jmod', jarContent: ['bin/jstack', 'bin/jcmd', 'bin/jps', 'bin/jmap', 'bin/jstat', 'bin/jinfo'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jshell.jmod', jarContent: ['bin/jshell'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.compiler.jmod', jarContent: ['bin/javac', 'bin/serialver'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'java.scripting.jmod', jarContent: ['bin/jrunscript'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jdi.jmod', jarContent: ['bin/jdb'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.javadoc.jmod', jarContent: ['bin/javadoc'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.jconsole.jmod', jarContent: ['bin/jconsole'], }, { jarDir: - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/jmods', + `enso/runtime/${GRAALVM}/Contents/Home/jmods`, jarName: 'jdk.javadoc.jmod', jarContent: ['bin/javadoc'], }, @@ -242,8 +244,20 @@ const toSign = [ // Extra files that need to be signed. const extra = [ - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/MacOS/libjli.dylib', - 'enso/runtime/graalvm-ce-java11-21.0.0.2/Contents/Home/languages/llvm/native/bin/ld.lld', + `enso/runtime/${GRAALVM}/Contents/MacOS/libjli.dylib`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/llvm/native/bin/ld.lld`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/MASS/libs/MASS.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/cluster/libs/cluster.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/nnet/libs/nnet.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/rpart/libs/rpart.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/lattice/libs/lattice.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/nlme/libs/nlme.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/class/libs/class.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/spatial/libs/spatial.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/foreign/libs/foreign.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/Matrix/libs/Matrix.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/KernSmooth/libs/KernSmooth.so`, + `enso/runtime/${GRAALVM}/Contents/Home/languages/R/library/survival/libs/survival.so`, ] exports.default = async function () { diff --git a/ide/src/js/lib/project-manager/src/build.ts b/ide/src/js/lib/project-manager/src/build.ts index 02cd4e23eeb4..351ec42b2174 100644 --- a/ide/src/js/lib/project-manager/src/build.ts +++ b/ide/src/js/lib/project-manager/src/build.ts @@ -41,9 +41,10 @@ async function get_project_manager_url(): Promise { const config = await get_build_config() const target_platform = config.target console.log('webpack target ' + target_platform) - // Usually it is a good idea to synchronize this constant with `ENGINE_VERSION_FOR_NEW_PROJECTS` in - // src/rust/ide/src/ide/initializer.rs. See also https://github.com/enso-org/ide/issues/1359 - const version = '0.2.11' + // This constant MUST be synchronized with `ENGINE` constant in src/js/lib/client/tasks/signArchives.js. + // Also it is usually a good idea to synchronize it with `ENGINE_VERSION_FOR_NEW_PROJECTS` in + // src/rust/ide/src/controller/project.rs. See also https://github.com/enso-org/ide/issues/1359 + const version = '0.2.12' let base_url: string = 'https://github.com/enso-org/' base_url += 'enso/releases/download/' base_url += `enso-${version}/enso-project-manager-${version}` diff --git a/ide/src/rust/ide/lib/enso-protocol/src/language_server/connection.rs b/ide/src/rust/ide/lib/enso-protocol/src/language_server/connection.rs index affd9fd354fd..251d51de3b7b 100644 --- a/ide/src/rust/ide/lib/enso-protocol/src/language_server/connection.rs +++ b/ide/src/rust/ide/lib/enso-protocol/src/language_server/connection.rs @@ -2,8 +2,10 @@ use crate::prelude::*; -use crate::language_server::MockClient; use crate::language_server::API; +use crate::language_server::MockClient; +use crate::language_server::types::ContentRoot; +use crate::language_server::types::ContentRootType; use uuid::Uuid; use utils::fail::FallibleResult; @@ -39,30 +41,41 @@ pub struct Connection { /// LS client that has already initialized protocol. #[derivative(Debug="ignore")] pub client:Box, - /// Content roots obtained during initialization. Guaranteed to be non-empty. - content_roots:Vec, + /// The Project content root, being an only obligatory content root received. + project_root:ContentRoot, + /// Content roots obtained during initialization other than the `project_root`]. + content_roots:Vec, } impl Connection { /// Takes a client, generates ID for it and initializes the protocol. pub async fn new(client:impl API + 'static, client_id:Uuid) -> FallibleResult { - let client = Box::new(client); - let init_response = client.init_protocol_connection(&client_id).await; - let init_response = init_response.map_err(|e| FailedToInitializeProtocol(e.into()))?; - let content_roots = init_response.content_roots; - if content_roots.is_empty() { - Err(MissingContentRoots.into()) - } else { - Ok(Connection {client_id,client,content_roots}) - } + let client = Box::new(client); + let init_response = client.init_protocol_connection(&client_id).await; + let init_response = init_response.map_err(|e| FailedToInitializeProtocol(e.into()))?; + let mut content_roots = init_response.content_roots; + let project_root = Self::extract_project_root(&mut content_roots)?; + Ok(Connection {client_id,client,project_root,content_roots}) + } + + fn extract_project_root(content_roots:&mut Vec) -> FallibleResult { + use ContentRootType::*; + let opt_index = content_roots.iter().position(|cr| cr.content_root_type == Project); + let index = opt_index.ok_or(MissingContentRoots)?; + Ok(content_roots.drain(index..=index).next().unwrap()) } /// Creates a connection which wraps a mock client. pub fn new_mock(client:MockClient) -> Connection { Connection { - client : Box::new(client), - client_id : default(), - content_roots : vec![default()], + client : Box::new(client), + client_id : default(), + project_root : ContentRoot { + id : default(), + content_root_type : ContentRootType::Project, + name : "Project".to_owned() + }, + content_roots : default(), } } @@ -72,14 +85,11 @@ impl Connection { } /// Returns the first content root. - pub fn content_root(&self) -> Uuid { - // Guaranteed to be non-empty thanks to check in `new` and implementation of `new_mock`. - self.content_roots[0] - } + pub fn project_root(&self) -> &ContentRoot { &self.project_root } /// Lists all content roots for this LS connection. - pub fn content_roots(&self) -> &Vec { - &self.content_roots + pub fn content_roots(&self) -> impl Iterator { + std::iter::once(&self.project_root).chain(self.content_roots.iter()) } } diff --git a/ide/src/rust/ide/lib/enso-protocol/src/language_server/response.rs b/ide/src/rust/ide/lib/enso-protocol/src/language_server/response.rs index 86b883b04eff..be6dbf4e76d3 100644 --- a/ide/src/rust/ide/lib/enso-protocol/src/language_server/response.rs +++ b/ide/src/rust/ide/lib/enso-protocol/src/language_server/response.rs @@ -7,7 +7,7 @@ use crate::language_server::SuggestionsDatabaseEntry; #[serde(rename_all="camelCase")] pub struct InitProtocolConnection { /// List of Root IDs. - pub content_roots:Vec, + pub content_roots:Vec, } /// Response of `file_read` method. diff --git a/ide/src/rust/ide/lib/enso-protocol/src/language_server/tests.rs b/ide/src/rust/ide/lib/enso-protocol/src/language_server/tests.rs index 42c15497f05b..a4a21e15cad8 100644 --- a/ide/src/rust/ide/lib/enso-protocol/src/language_server/tests.rs +++ b/ide/src/rust/ide/lib/enso-protocol/src/language_server/tests.rs @@ -261,7 +261,11 @@ fn test_file_requests() { #[test] fn test_protocol_connection() { let init_protocol_connection_response = response::InitProtocolConnection { - content_roots: vec![uuid::Uuid::default()] + content_roots: vec![ContentRoot { + id : default(), + content_root_type : ContentRootType::Project, + name : "Project".to_owned() + }] }; test_request( |client| client.init_protocol_connection(&uuid::Uuid::default()), @@ -270,7 +274,11 @@ fn test_protocol_connection() { "clientId" : "00000000-0000-0000-0000-000000000000" }), json!({ - "contentRoots" : ["00000000-0000-0000-0000-000000000000"] + "contentRoots" : [{ + "id" : "00000000-0000-0000-0000-000000000000", + "type" : "Project", + "name" : "Project", + }] }), init_protocol_connection_response ); diff --git a/ide/src/rust/ide/lib/enso-protocol/src/language_server/types.rs b/ide/src/rust/ide/lib/enso-protocol/src/language_server/types.rs index 7efdb8b23547..8d60030a7be9 100644 --- a/ide/src/rust/ide/lib/enso-protocol/src/language_server/types.rs +++ b/ide/src/rust/ide/lib/enso-protocol/src/language_server/types.rs @@ -386,6 +386,39 @@ impl FileSystemObject { +// ===================== +// === Content Roots === +// ===================== + +/// The type of the annotated content root. +#[derive(Clone,Copy,Debug,Deserialize,Eq,Hash,PartialEq,Serialize)] +pub enum ContentRootType { + /// The project home. + Project, + /// System root `/` on unix systems, or drive root on Windows. In Windows’ case, there may be + /// multiple [`Root`] entries corresponding to the various drives. + Root, + /// The user’s home directory. + Home, + /// An Enso library location. + Library, + /// A content root that has been added by the IDE (unused for now). + Custom +} + +/// A content root represents a location on a real file-system that has been virtualized for use in +/// the Cloud. +#[allow(missing_docs)] +#[derive(Clone,Debug,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[serde(rename_all="camelCase")] +pub struct ContentRoot { + pub id:Uuid, + #[serde(rename="type")] + pub content_root_type : ContentRootType, + pub name : String, +} + + // ================ // === Position === diff --git a/ide/src/rust/ide/src/controller/project.rs b/ide/src/rust/ide/src/controller/project.rs index f065dba9aaaf..66cd1add76be 100644 --- a/ide/src/rust/ide/src/controller/project.rs +++ b/ide/src/rust/ide/src/controller/project.rs @@ -22,12 +22,12 @@ pub const COMPILING_STDLIB_LABEL:&str = "Compiling standard library. It can take /// The requirements for Engine's version, in format understandable by /// [`semver::VersionReq::parse`]. -pub const ENGINE_VERSION_SUPPORTED : &str = "^0.2.11"; +pub const ENGINE_VERSION_SUPPORTED : &str = "^0.2.12"; /// The Engine version used in projects created in IDE. // Usually it is a good idea to synchronize this version with the bundled Engine version in // src/js/lib/project-manager/src/build.ts. See also https://github.com/enso-org/ide/issues/1359 -pub const ENGINE_VERSION_FOR_NEW_PROJECTS : &str = "0.2.11"; +pub const ENGINE_VERSION_FOR_NEW_PROJECTS : &str = "0.2.12"; /// The name of the module initially opened in the project view. /// @@ -57,6 +57,23 @@ pub fn main_method_ptr(project_name:impl Str, module_path:&model::module::Path) } + +// ================= +// === Utilities === +// ================= + +/// Returns the path to package.yaml file for given project. +pub fn package_yaml_path(project_name:&str) -> String { + match platform::current() { + Some(Platform::Linux) | + Some(Platform::MacOS) => format!("~/enso/projects/{}/package.yaml",project_name), + Some(Platform::Windows) => + format!("%userprofile%\\enso\\projects\\{}\\package.yaml",project_name), + _ => format!("/{}/package.yaml",project_name) + } +} + + // ============== // === Handle === // ============== @@ -177,22 +194,11 @@ impl Project { let version = self.model.engine_version(); if !requirements.matches(version) { let message = format!("Unsupported Engine version. Please update engine_version in {} \ - to {}.",self.package_yaml_path(),ENGINE_VERSION_FOR_NEW_PROJECTS); + to {}.",package_yaml_path(&self.model.name()),ENGINE_VERSION_FOR_NEW_PROJECTS); self.status_notifications.publish_event(message); } Ok(()) } - - fn package_yaml_path(&self) -> String { - let project_name = self.model.name(); - match platform::current() { - Some(Platform::Linux) | - Some(Platform::MacOS) => format!("~/enso/projects/{}/package.yaml",project_name), - Some(Platform::Windows) => - format!("%userprofile%\\enso\\projects\\{}\\package.yaml",project_name), - _ => format!("/{}/package.yaml",project_name) - } - } } diff --git a/ide/src/rust/ide/src/controller/visualization.rs b/ide/src/rust/ide/src/controller/visualization.rs index b4c97a4a02ad..57550acbc852 100644 --- a/ide/src/rust/ide/src/controller/visualization.rs +++ b/ide/src/rust/ide/src/controller/visualization.rs @@ -105,7 +105,7 @@ impl Handle { async fn list_project_specific_visualizations (&self) -> FallibleResult> { - let root_id = self.language_server_rpc.content_root(); + let root_id = self.language_server_rpc.project_root().id; let path = language_server::Path::new(root_id,&[VISUALIZATION_DIRECTORY]); let folder = self.language_server_rpc.file_exists(&path).await?; let file_list = if folder.exists { diff --git a/ide/src/rust/ide/src/model/project.rs b/ide/src/rust/ide/src/model/project.rs index cd9179c5dd10..ced5e5023129 100644 --- a/ide/src/rust/ide/src/model/project.rs +++ b/ide/src/rust/ide/src/model/project.rs @@ -65,7 +65,7 @@ pub trait API:Debug { /// Returns the primary content root id for this project. fn content_root_id(&self) -> Uuid { - self.json_rpc().content_root() + self.json_rpc().project_root().id } /// Generates full module's qualified name that includes the leading project name segment. diff --git a/ide/src/rust/ide/src/model/project/synchronized.rs b/ide/src/rust/ide/src/model/project/synchronized.rs index 7a582fdbad85..289295a588a8 100644 --- a/ide/src/rust/ide/src/model/project/synchronized.rs +++ b/ide/src/rust/ide/src/model/project/synchronized.rs @@ -99,6 +99,41 @@ impl ExecutionContextsRegistry { #[fail(display="Project Manager is unavailable.")] pub struct ProjectManagerUnavailable; +/// A wrapper for an error with information that user tried to open project with unsupported +/// engine's version (which is likely the cause of the problems). +#[derive(Debug,Fail)] +pub struct UnsupportedEngineVersion { + project_name : String, + root_cause : failure::Error, +} + +impl UnsupportedEngineVersion { + fn error_wrapper + (project_name:String, engine_version:semver::Version) + -> impl Fn(failure::Error) -> failure::Error { + move |root_cause| { + let requirements = semver::VersionReq::parse(controller::project::ENGINE_VERSION_SUPPORTED); + match requirements { + Ok(requirements) if !requirements.matches(&engine_version) => { + let project_name = project_name.clone(); + UnsupportedEngineVersion {project_name,root_cause}.into() + } + _ => root_cause, + } + } + } +} + +impl Display for UnsupportedEngineVersion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let package_yaml_path = controller::project::package_yaml_path(&self.project_name); + let version_supported = controller::project::ENGINE_VERSION_FOR_NEW_PROJECTS; + write!(f, "Failed to open project: unsupported engine version. Please update \ + engine_version in {} to {}.",package_yaml_path,version_supported) + } +} + + // === Data === @@ -146,6 +181,7 @@ impl Project { , id : Uuid , name : impl Str ) -> FallibleResult { + let wrap = UnsupportedEngineVersion::error_wrapper(name.as_ref().to_owned(),engine_version.clone()); let logger = Logger::sub(parent,"Project Controller"); info!(logger,"Creating a model of project {name.as_ref()}"); let binary_protocol_events = language_server_bin.event_stream(); @@ -159,10 +195,10 @@ impl Project { let parser = Parser::new_or_panic(); let language_server = &*language_server_rpc; let suggestion_db = SuggestionDatabase::create_synchronized(language_server); - let suggestion_db = Rc::new(suggestion_db.await?); + let suggestion_db = Rc::new(suggestion_db.await.map_err(&wrap)?); let notifications = notification::Publisher::default(); let urm = Rc::new(model::undo_redo::Manager::new(&logger)); - + let engine_version = engine_version.clone(); let properties = Rc::new(Properties {id,name,engine_version}); let ret = Project @@ -175,7 +211,7 @@ impl Project { let json_rpc_handler = ret.json_event_handler(); crate::executor::global::spawn(json_rpc_events.for_each(json_rpc_handler)); - ret.acquire_suggestion_db_updates_capability().await?; + ret.acquire_suggestion_db_updates_capability().await.map_err(|err| wrap(err.into()))?; Ok(ret) } @@ -189,15 +225,18 @@ impl Project { , id : Uuid , name : impl Str ) -> FallibleResult { - let client_id = Uuid::new_v4(); - let json_ws = WebSocket::new_opened(&parent,&language_server_rpc).await?; - let binary_ws = WebSocket::new_opened(&parent,&language_server_bin).await?; + let wrap = UnsupportedEngineVersion::error_wrapper(name.as_ref().to_owned(),engine_version.clone()); + let client_id = Uuid::new_v4(); + let json_ws = WebSocket::new_opened(&parent,&language_server_rpc).await?; + let binary_ws = WebSocket::new_opened(&parent,&language_server_bin).await?; let client_json = language_server::Client::new(json_ws); let client_binary = binary::Client::new(&parent,binary_ws); crate::executor::global::spawn(client_json.runner()); crate::executor::global::spawn(client_binary.runner()); - let connection_json = language_server::Connection::new(client_json,client_id).await?; - let connection_binary = binary::Connection::new(client_binary,client_id).await?; + let connection_json = language_server::Connection::new(client_json,client_id) + .await.map_err(&wrap)?; + let connection_binary = binary::Connection::new(client_binary,client_id) + .await.map_err(&wrap)?; let language_server_rpc = Rc::new(connection_json); let language_server_bin = Rc::new(connection_binary); let model = Self::new(parent,project_manager,language_server_rpc @@ -213,12 +252,12 @@ impl Project { , id : Uuid , name : impl Str ) -> FallibleResult { - let action = MissingComponentAction::Install; - let opened = project_manager.open_project(&id,&action).await?; + let action = MissingComponentAction::Install; + let opened = project_manager.open_project(&id,&action).await?; + let version = semver::Version::parse(&opened.engine_version)?; let project_manager = Some(project_manager); let json_endpoint = opened.language_server_json_address.to_string(); let binary_endpoint = opened.language_server_binary_address.to_string(); - let version = semver::Version::parse(&opened.engine_version)?; Self::new_connected(parent,project_manager,json_endpoint,binary_endpoint,version,id,name).await } @@ -404,7 +443,7 @@ impl model::project::API for Project { } fn content_root_id(&self) -> Uuid { - self.language_server_rpc.content_root() + self.language_server_rpc.project_root().id } fn subscribe(&self) -> Subscriber { diff --git a/ide/src/rust/ide/tests/language_server.rs b/ide/src/rust/ide/tests/language_server.rs index bc70e7945ac9..eb513c746e2a 100644 --- a/ide/src/rust/ide/tests/language_server.rs +++ b/ide/src/rust/ide/tests/language_server.rs @@ -240,7 +240,7 @@ async fn file_events() { let client_id = uuid::Uuid::default(); let session = client.init_protocol_connection(&client_id).await; let session = session.expect("Couldn't initialize session."); - let root_id = session.content_roots[0]; + let root_id = session.content_roots[0].id; let path = Path{root_id,segments:vec!["test.txt".into()]}; let file = client.file_exists(&path).await; @@ -298,7 +298,7 @@ async fn file_operations_test() { let project = ide.current_project(); info!(logger,"Got project: {project:?}"); // Edit file using the text protocol - let path = Path::new(project.json_rpc().content_root(), &["test_file.txt"]); + let path = Path::new(project.json_rpc().project_root().id, &["test_file.txt"]); let contents = "Hello, 世界!".to_string(); let written = project.json_rpc().write_file(&path,&contents).await.unwrap(); info!(logger,"Written: {written:?}");