Skip to content

Commit 704f5e5

Browse files
committed
refactor: move env var config to ServerFactory/Session lifecycle
Env config is computed once at ServerFactory creation and threaded through to Session, which merges it as the highest-priority layer during config loading. Tests use ServerFactory::default() which provides None, avoiding DATABASE_URL interference from sqlx::test.
1 parent 0012818 commit 704f5e5

2 files changed

Lines changed: 24 additions & 9 deletions

File tree

crates/pgls_lsp/src/server.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::session::{
66
use crate::utils::{into_lsp_error, panic_to_lsp_error};
77
use futures::FutureExt;
88
use futures::future::ready;
9+
use pgls_configuration::database::PartialDatabaseConfiguration;
910
use pgls_fs::{ConfigName, FileSystem, OsFileSystem};
1011
use pgls_workspace::workspace::{RegisterProjectFolderParams, UnregisterProjectFolderParams};
1112
use pgls_workspace::{DynRef, Workspace, workspace};
@@ -162,9 +163,9 @@ impl LanguageServer for LSPServer {
162163

163164
#[tracing::instrument(level = "info", skip_all)]
164165
async fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
165-
self.session
166-
.load_workspace_settings(serde_json::from_value(params.settings).ok())
167-
.await;
166+
let extra_config: Option<pgls_configuration::PartialConfiguration> =
167+
serde_json::from_value(params.settings).ok();
168+
self.session.load_workspace_settings(extra_config).await;
168169
self.setup_capabilities().await;
169170
self.session.update_all_diagnostics().await;
170171
}
@@ -410,17 +411,27 @@ pub struct ServerFactory {
410411
/// This shared flag is set to true once at least one sessions has been
411412
/// initialized on this server instance
412413
is_initialized: Arc<AtomicBool>,
414+
/// Configuration from environment variables (DATABASE_URL, PGHOST, etc.).
415+
/// Computed once at factory creation and passed to each session.
416+
env_config: Option<pgls_configuration::PartialConfiguration>,
413417
}
414418

415419
impl ServerFactory {
416420
pub fn new(stop_on_disconnect: bool) -> Self {
421+
let env_config = PartialDatabaseConfiguration::from_env().map(|db| {
422+
pgls_configuration::PartialConfiguration {
423+
db: Some(db),
424+
..Default::default()
425+
}
426+
});
417427
Self {
418428
cancellation: Arc::default(),
419429
workspace: None,
420430
sessions: Sessions::default(),
421431
next_session_key: AtomicU64::new(0),
422432
stop_on_disconnect,
423433
is_initialized: Arc::default(),
434+
env_config,
424435
}
425436
}
426437

@@ -441,13 +452,15 @@ impl ServerFactory {
441452

442453
let session_key = SessionKey(self.next_session_key.fetch_add(1, Ordering::Relaxed));
443454

455+
let env_config = self.env_config.clone();
444456
let mut builder = LspService::build(move |client| {
445457
let mut session = Session::new(
446458
session_key,
447459
client,
448460
workspace,
449461
self.cancellation.clone(),
450462
fs,
463+
env_config,
451464
);
452465
if let Some(path) = config_path {
453466
session.set_config_path(path);

crates/pgls_lsp/src/session.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use biome_deserialize::Merge;
77
use futures::StreamExt;
88
use futures::stream::FuturesUnordered;
99
use pgls_analyse::RuleCategoriesBuilder;
10-
use pgls_configuration::database::PartialDatabaseConfiguration;
1110
use pgls_configuration::{ConfigurationPathHint, PartialConfiguration};
1211
use pgls_diagnostics::{DiagnosticExt, Error};
1312
use pgls_fs::{ConfigName, FileSystem, PgLSPath};
@@ -76,6 +75,9 @@ pub(crate) struct Session {
7675
pub(crate) cancellation: Arc<Notify>,
7776

7877
pub(crate) config_path: Option<PathBuf>,
78+
79+
/// Extra configuration from environment variables, applied on every config load.
80+
env_config: Option<PartialConfiguration>,
7981
}
8082

8183
/// The parameters provided by the client in the "initialize" request
@@ -156,6 +158,7 @@ impl Session {
156158
workspace: Arc<dyn Workspace>,
157159
cancellation: Arc<Notify>,
158160
fs: DynRef<'static, dyn FileSystem>,
161+
env_config: Option<PartialConfiguration>,
159162
) -> Self {
160163
let documents = Default::default();
161164
Self {
@@ -170,6 +173,7 @@ impl Session {
170173
config_path: None,
171174
notified_broken_configuration: AtomicBool::new(false),
172175
notified_deprecated_config: AtomicBool::new(false),
176+
env_config,
173177
}
174178
}
175179

@@ -500,11 +504,9 @@ impl Session {
500504
fs_configuration.merge_with(ws_configuration);
501505
}
502506

503-
if let Some(env_db) = PartialDatabaseConfiguration::from_env() {
504-
match &mut fs_configuration.db {
505-
Some(db) => db.merge_with(env_db),
506-
None => fs_configuration.db = Some(env_db),
507-
}
507+
// Env vars take highest priority — merge last so they override everything.
508+
if let Some(env_config) = &self.env_config {
509+
fs_configuration.merge_with(env_config.clone());
508510
}
509511

510512
let result = fs_configuration

0 commit comments

Comments
 (0)