diff --git a/crates/ty_server/src/logging.rs b/crates/ty_server/src/logging.rs index 9868dac107..97870753c2 100644 --- a/crates/ty_server/src/logging.rs +++ b/crates/ty_server/src/logging.rs @@ -4,10 +4,9 @@ //! are written to `stderr` by default, which should appear in the logs for most LSP clients. A //! `logFile` path can also be specified in the settings, and output will be directed there //! instead. -use std::path::{Path, PathBuf}; -use std::str::FromStr; use std::sync::Arc; +use ruff_db::system::{SystemPath, SystemPathBuf}; use serde::Deserialize; use tracing::level_filters::LevelFilter; use tracing_subscriber::Layer; @@ -15,14 +14,14 @@ use tracing_subscriber::fmt::time::ChronoLocal; use tracing_subscriber::fmt::writer::BoxMakeWriter; use tracing_subscriber::layer::SubscriberExt; -pub(crate) fn init_logging(log_level: LogLevel, log_file: Option<&Path>) { +pub(crate) fn init_logging(log_level: LogLevel, log_file: Option<&SystemPath>) { let log_file = log_file .map(|path| { // this expands `logFile` so that tildes and environment variables // are replaced with their values, if possible. - if let Some(expanded) = shellexpand::full(&path.to_string_lossy()) + if let Some(expanded) = shellexpand::full(&path.to_string()) .ok() - .and_then(|path| PathBuf::from_str(&path).ok()) + .map(|path| SystemPathBuf::from(&*path)) { expanded } else { @@ -33,14 +32,11 @@ pub(crate) fn init_logging(log_level: LogLevel, log_file: Option<&Path>) { std::fs::OpenOptions::new() .create(true) .append(true) - .open(&path) + .open(path.as_std_path()) .map_err(|err| { #[expect(clippy::print_stderr)] { - eprintln!( - "Failed to open file at {} for logging: {err}", - path.display() - ); + eprintln!("Failed to open file at {path} for logging: {err}"); } }) .ok() diff --git a/crates/ty_server/src/session.rs b/crates/ty_server/src/session.rs index b7c365240d..f7ba6983fd 100644 --- a/crates/ty_server/src/session.rs +++ b/crates/ty_server/src/session.rs @@ -2,7 +2,6 @@ use std::collections::{BTreeMap, VecDeque}; use std::ops::{Deref, DerefMut}; -use std::path::{Path, PathBuf}; use std::sync::Arc; use anyhow::{Context, anyhow}; @@ -235,14 +234,7 @@ impl Session { // In the future, index the workspace directories to find all projects // and create a project database for each. let system = LSPSystem::new(self.index.as_ref().unwrap().clone()); - - let Some(system_path) = SystemPath::from_std_path(workspace.root()) else { - tracing::warn!( - "Ignore workspace `{}` because it's root contains non UTF8 characters", - workspace.root().display() - ); - continue; - }; + let system_path = workspace.root(); let root = system_path.to_path_buf(); let project = ProjectMetadata::discover(&root, &system) @@ -473,11 +465,15 @@ impl Workspaces { .to_file_path() .map_err(|()| anyhow!("Workspace URL is not a file or directory: {url:?}"))?; + // Realistically I don't think this can fail because we got the path from a Url + let system_path = SystemPathBuf::from_path_buf(path) + .map_err(|_| anyhow!("Workspace URL is not valid UTF8"))?; + self.workspaces.insert( url, Workspace { options, - root: path, + root: system_path, }, ); @@ -520,12 +516,12 @@ impl<'a> IntoIterator for &'a Workspaces { #[derive(Debug)] pub(crate) struct Workspace { - root: PathBuf, + root: SystemPathBuf, options: ClientOptions, } impl Workspace { - pub(crate) fn root(&self) -> &Path { + pub(crate) fn root(&self) -> &SystemPath { &self.root } } diff --git a/crates/ty_server/src/session/options.rs b/crates/ty_server/src/session/options.rs index 531fe583df..a984b4e34e 100644 --- a/crates/ty_server/src/session/options.rs +++ b/crates/ty_server/src/session/options.rs @@ -1,6 +1,5 @@ -use std::path::PathBuf; - use lsp_types::Url; +use ruff_db::system::SystemPathBuf; use rustc_hash::FxHashMap; use serde::Deserialize; @@ -89,7 +88,7 @@ pub(crate) struct TracingOptions { pub(crate) log_level: Option, /// Path to the log file - tildes and environment variables are supported. - pub(crate) log_file: Option, + pub(crate) log_file: Option, } /// This is the exact schema for initialization options sent in by the client during