Redact secrets from environment in LSP Server Info (#34971)

In "Server Info" view of LSP logs:
- Redacts sensitive values from environment
- Sorts environment by name

| Before | After | 
| - | - | 
| <img width="797" height="327" alt="Screenshot 2025-07-23 at 14 10 14"
src="https://github.com/user-attachments/assets/75781f30-9099-4994-9824-94d9c46f63e1"
/> | <img width="972" height="571" alt="image"
src="https://github.com/user-attachments/assets/c5bef744-a1b7-415f-9eb7-8314275c59b9"
/> |


Release Notes:

- Improved display of environment variables in LSP Logs: Server Info
view
This commit is contained in:
Peter Tripp 2025-07-23 16:55:13 -04:00 committed by GitHub
parent 50985b7d23
commit edceb7284f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -4,7 +4,7 @@ pub use lsp_types::request::*;
pub use lsp_types::*;
use anyhow::{Context as _, Result, anyhow};
use collections::HashMap;
use collections::{BTreeMap, HashMap};
use futures::{
AsyncRead, AsyncWrite, Future, FutureExt,
channel::oneshot::{self, Canceled},
@ -40,7 +40,7 @@ use std::{
time::{Duration, Instant},
};
use std::{path::Path, process::Stdio};
use util::{ConnectionResult, ResultExt, TryFutureExt};
use util::{ConnectionResult, ResultExt, TryFutureExt, redact};
const JSON_RPC_VERSION: &str = "2.0";
const CONTENT_LEN_HEADER: &str = "Content-Length: ";
@ -62,7 +62,7 @@ pub enum IoKind {
/// Represents a launchable language server. This can either be a standalone binary or the path
/// to a runtime with arguments to instruct it to launch the actual language server file.
#[derive(Debug, Clone, Deserialize)]
#[derive(Clone, Deserialize)]
pub struct LanguageServerBinary {
pub path: PathBuf,
pub arguments: Vec<OsString>,
@ -1448,6 +1448,33 @@ impl fmt::Debug for LanguageServer {
}
}
impl fmt::Debug for LanguageServerBinary {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug = f.debug_struct("LanguageServerBinary");
debug.field("path", &self.path);
debug.field("arguments", &self.arguments);
if let Some(env) = &self.env {
let redacted_env: BTreeMap<String, String> = env
.iter()
.map(|(key, value)| {
let redacted_value = if redact::should_redact(key) {
"REDACTED".to_string()
} else {
value.clone()
};
(key.clone(), redacted_value)
})
.collect();
debug.field("env", &Some(redacted_env));
} else {
debug.field("env", &self.env);
}
debug.finish()
}
}
impl Drop for Subscription {
fn drop(&mut self) {
match self {