Skip to content

Commit

Permalink
Include document specific debug info
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvmanila committed Feb 18, 2025
1 parent 8abfba3 commit 62ff785
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 44 deletions.
82 changes: 68 additions & 14 deletions crates/ruff_server/src/server/api/requests/execute_command.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::fmt::Write;
use std::str::FromStr;

use crate::edit::WorkspaceEditTracker;
use crate::server::api::LSPResult;
use crate::server::schedule::Task;
use crate::server::{client, SupportedCommand};
use crate::session::Session;
use crate::DIAGNOSTIC_NAME;
use crate::{edit::DocumentVersion, server};
use crate::{DocumentKey, DIAGNOSTIC_NAME};
use lsp_server::ErrorCode;
use lsp_types::{self as types, request as req};
use serde::Deserialize;
Expand All @@ -19,6 +20,11 @@ struct Argument {
version: DocumentVersion,
}

#[derive(Default, Deserialize)]
struct DebugCommandArgument {
uri: Option<types::Url>,
}

impl super::RequestHandler for ExecuteCommand {
type RequestType = req::ExecuteCommand;
}
Expand All @@ -34,7 +40,12 @@ impl super::SyncRequestHandler for ExecuteCommand {
.with_failure_code(ErrorCode::InvalidParams)?;

if command == SupportedCommand::Debug {
let output = debug_information(session);
let argument: DebugCommandArgument = params.arguments.into_iter().next().map_or_else(
|| Ok(DebugCommandArgument::default()),
|value| serde_json::from_value(value).with_failure_code(ErrorCode::InvalidParams),
)?;
let output = debug_information(session, argument.uri)
.with_failure_code(ErrorCode::InternalError)?;
notifier
.notify::<types::notification::LogMessage>(types::LogMessageParams {
message: output.clone(),
Expand Down Expand Up @@ -134,23 +145,66 @@ fn apply_edit(
)
}

fn debug_information(session: &Session) -> String {
fn debug_information(session: &Session, uri: Option<types::Url>) -> crate::Result<String> {
let executable = std::env::current_exe()
.map(|path| format!("{}", path.display()))
.unwrap_or_else(|_| "<unavailable>".to_string());
format!(
"executable = {executable}

let mut buffer = String::new();

writeln!(
buffer,
"Global:
executable = {executable}
version = {version}
encoding = {encoding:?}
open_document_count = {doc_count}
active_workspace_count = {workspace_count}
configuration_files = {config_files:?}
{client_capabilities}",
position_encoding = {encoding:?}
workspace_root_folders = {workspace_folders:#?}
indexed_configuration_files = {config_files:#?}
open_documents = {open_documents}
client_capabilities = {client_capabilities:#?}
",
version = crate::version(),
encoding = session.encoding(),
workspace_folders = session.workspace_root_folders().collect::<Vec<_>>(),
config_files = session.config_file_paths().collect::<Vec<_>>(),
open_documents = session.open_documents(),
client_capabilities = session.resolved_client_capabilities(),
doc_count = session.num_documents(),
workspace_count = session.num_workspaces(),
config_files = session.list_config_files()
)
)?;

if let Some(uri) = uri {
let Some(snapshot) = session.take_snapshot(uri.clone()) else {
writeln!(buffer, "Unable to take a snapshot of the document at {uri}")?;
return Ok(buffer);
};

writeln!(
buffer,
"Document:
uri = {uri}
kind = {kind}
version = {version}
client_settings = {client_settings:#?}
config_path = {config_path:?}
{settings}
",
uri = uri.clone(),
kind = match session.key_from_url(uri) {
DocumentKey::Notebook(_) => "Notebook",
DocumentKey::NotebookCell(_) => "NotebookCell",
DocumentKey::Text(_) => "Text",
},
version = snapshot.query().version(),
client_settings = snapshot.client_settings(),
config_path = snapshot.query().settings().path(),
settings = snapshot.query().settings(),
)?;
} else {
writeln!(
buffer,
"global_client_settings = {:#?}",
session.global_client_settings()
)?;
}

Ok(buffer)
}
30 changes: 20 additions & 10 deletions crates/ruff_server/src/session.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Data model, state management, and configuration resolution.
use std::path::Path;
use std::sync::Arc;

use lsp_types::{ClientCapabilities, FileEvent, NotebookDocumentCellChange, Url};
use settings::ResolvedClientSettings;

use crate::edit::{DocumentKey, DocumentVersion, NotebookDocument};
use crate::server::Workspaces;
Expand Down Expand Up @@ -147,24 +149,32 @@ impl Session {
Ok(())
}

pub(crate) fn num_documents(&self) -> usize {
self.index.num_documents()
pub(crate) fn resolved_client_capabilities(&self) -> &ResolvedClientCapabilities {
&self.resolved_client_capabilities
}

pub(crate) fn num_workspaces(&self) -> usize {
self.index.num_workspaces()
pub(crate) fn encoding(&self) -> PositionEncoding {
self.position_encoding
}

pub(crate) fn list_config_files(&self) -> Vec<&std::path::Path> {
self.index.list_config_files()
/// Returns an iterator over the paths to the configuration files in the index.
pub(crate) fn config_file_paths(&self) -> impl Iterator<Item = &Path> {
self.index.config_file_paths()
}

pub(crate) fn resolved_client_capabilities(&self) -> &ResolvedClientCapabilities {
&self.resolved_client_capabilities
/// Returns the resolved global client settings.
pub(crate) fn global_client_settings(&self) -> ResolvedClientSettings {
ResolvedClientSettings::global(&self.global_settings)
}

pub(crate) fn encoding(&self) -> PositionEncoding {
self.position_encoding
/// Returns the number of open documents in the session.
pub(crate) fn open_documents(&self) -> usize {
self.index.open_documents()
}

/// Returns an iterator over the workspace root folders in the session.
pub(crate) fn workspace_root_folders(&self) -> impl Iterator<Item = &Path> {
self.index.workspace_root_folders()
}
}

Expand Down
32 changes: 17 additions & 15 deletions crates/ruff_server/src/session/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,6 @@ impl Index {
.register_workspace(&Workspace::new(url), global_settings)
}

pub(super) fn num_documents(&self) -> usize {
self.documents.len()
}

pub(super) fn num_workspaces(&self) -> usize {
self.settings.len()
}

pub(super) fn list_config_files(&self) -> Vec<&Path> {
self.settings
.values()
.flat_map(|WorkspaceSettings { ruff_settings, .. }| ruff_settings.list_files())
.collect()
}

pub(super) fn close_workspace_folder(&mut self, workspace_url: &Url) -> crate::Result<()> {
let workspace_path = workspace_url.to_file_path().map_err(|()| {
anyhow!("Failed to convert workspace URL to file path: {workspace_url}")
Expand Down Expand Up @@ -404,6 +389,23 @@ impl Index {
.next_back()
.map(|(_, settings)| settings)
}

/// Returns an iterator over the workspace root folders contained in this index.
pub(super) fn workspace_root_folders(&self) -> impl Iterator<Item = &Path> {
self.settings.keys().map(PathBuf::as_path)
}

/// Returns the number of open documents.
pub(super) fn open_documents(&self) -> usize {
self.documents.len()
}

/// Returns an iterator over the paths to the configuration files in the index.
pub(super) fn config_file_paths(&self) -> impl Iterator<Item = &Path> {
self.settings
.values()
.flat_map(|WorkspaceSettings { ruff_settings, .. }| ruff_settings.config_file_paths())
}
}

/// Maps a workspace folder root to its settings.
Expand Down
18 changes: 13 additions & 5 deletions crates/ruff_server/src/session/index/ruff_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use ruff_workspace::{

use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};

#[derive(Debug)]
pub struct RuffSettings {
/// The path to this configuration file, used for debugging.
/// The default fallback configuration does not have a file path.
Expand All @@ -28,6 +29,12 @@ pub struct RuffSettings {
settings: Settings,
}

impl RuffSettings {
pub(crate) fn path(&self) -> Option<&Path> {
self.path.as_deref()
}
}

impl Deref for RuffSettings {
type Target = Settings;

Expand Down Expand Up @@ -298,15 +305,16 @@ impl RuffSettingsIndex {
.clone()
}

pub(crate) fn list_files(&self) -> impl Iterator<Item = &Path> {
pub(super) fn fallback(&self) -> Arc<RuffSettings> {
self.fallback.clone()
}

/// Returns an iterator over the paths to the configuration files in the index.
pub(crate) fn config_file_paths(&self) -> impl Iterator<Item = &Path> {
self.index
.values()
.filter_map(|settings| settings.path.as_deref())
}

pub(super) fn fallback(&self) -> Arc<RuffSettings> {
self.fallback.clone()
}
}

struct EditorConfigurationTransformer<'a>(&'a ResolvedEditorSettings, &'a Path);
Expand Down

0 comments on commit 62ff785

Please sign in to comment.