Skip to content

Commit 3b7ffe0

Browse files
Add configurable venv path and improve Python detection (#116)
1 parent 36c57cf commit 3b7ffe0

File tree

5 files changed

+562
-31
lines changed

5 files changed

+562
-31
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ and this project attempts to adhere to [Semantic Versioning](https://semver.org/
2222

2323
- Added support for loading server settings from user files (`~/.config/djls/djls.toml`) and project files (`djls.toml`, `.djls.toml`, and `pyproject.toml` via `[tool.djls]` table).
2424
- Implemented dynamic settings reloading via `workspace/didChangeConfiguration`.
25+
- Added `venv_path` setting to allow explicit configuration of Python virtual environment.
2526

2627
### Changed
2728

2829
- **Internal**: Moved task queueing functionality to `djls-server` crate, renamed from `Worker` to `Queue`, and simplified API.
30+
- Improved Python environment detection.
2931

3032
## [5.2.0a0]
3133

crates/djls-conf/src/lib.rs

Lines changed: 109 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ pub enum ConfigError {
1717
}
1818

1919
#[derive(Debug, Deserialize, Default, PartialEq)]
20-
#[serde(default)]
2120
pub struct Settings {
21+
#[serde(default)]
2222
debug: bool,
23+
venv_path: Option<String>,
2324
}
2425

2526
impl Settings {
@@ -76,6 +77,10 @@ impl Settings {
7677
pub fn debug(&self) -> bool {
7778
self.debug
7879
}
80+
81+
pub fn venv_path(&self) -> Option<&str> {
82+
self.venv_path.as_deref()
83+
}
7984
}
8085

8186
#[cfg(test)]
@@ -91,9 +96,14 @@ mod tests {
9196
fn test_load_no_files() {
9297
let dir = tempdir().unwrap();
9398
let settings = Settings::new(dir.path()).unwrap();
94-
// Should load defaults
95-
assert_eq!(settings, Settings { debug: false });
9699
// Add assertions for future default fields here
100+
assert_eq!(
101+
settings,
102+
Settings {
103+
debug: false,
104+
venv_path: None
105+
}
106+
);
97107
}
98108
}
99109

@@ -105,15 +115,41 @@ mod tests {
105115
let dir = tempdir().unwrap();
106116
fs::write(dir.path().join("djls.toml"), "debug = true").unwrap();
107117
let settings = Settings::new(dir.path()).unwrap();
108-
assert_eq!(settings, Settings { debug: true });
118+
assert_eq!(
119+
settings,
120+
Settings {
121+
debug: true,
122+
..Default::default()
123+
}
124+
);
125+
}
126+
127+
#[test]
128+
fn test_load_venv_path_config() {
129+
let dir = tempdir().unwrap();
130+
fs::write(dir.path().join("djls.toml"), "venv_path = '/path/to/venv'").unwrap();
131+
let settings = Settings::new(dir.path()).unwrap();
132+
assert_eq!(
133+
settings,
134+
Settings {
135+
venv_path: Some("/path/to/venv".to_string()),
136+
..Default::default()
137+
}
138+
);
109139
}
110140

111141
#[test]
112142
fn test_load_dot_djls_toml_only() {
113143
let dir = tempdir().unwrap();
114144
fs::write(dir.path().join(".djls.toml"), "debug = true").unwrap();
115145
let settings = Settings::new(dir.path()).unwrap();
116-
assert_eq!(settings, Settings { debug: true });
146+
assert_eq!(
147+
settings,
148+
Settings {
149+
debug: true,
150+
..Default::default()
151+
}
152+
);
117153
}
118154

119155
#[test]
@@ -123,7 +159,13 @@ mod tests {
123159
let content = "[tool.djls]\ndebug = true\n";
124160
fs::write(dir.path().join("pyproject.toml"), content).unwrap();
125161
let settings = Settings::new(dir.path()).unwrap();
126-
assert_eq!(settings, Settings { debug: true });
162+
assert_eq!(
163+
settings,
164+
Settings {
165+
debug: true,
166+
..Default::default()
167+
}
168+
);
127169
}
128170
}
129171

@@ -136,7 +178,14 @@ mod tests {
136178
fs::write(dir.path().join(".djls.toml"), "debug = false").unwrap();
137179
fs::write(dir.path().join("djls.toml"), "debug = true").unwrap();
138180
let settings = Settings::new(dir.path()).unwrap();
139-
assert_eq!(settings, Settings { debug: true }); // djls.toml wins
181+
// djls.toml wins
182+
assert_eq!(
183+
settings,
184+
Settings {
185+
debug: true,
186+
..Default::default()
187+
}
188+
);
140189
}
141190

142191
#[test]
@@ -146,7 +195,14 @@ mod tests {
146195
fs::write(dir.path().join("pyproject.toml"), pyproject_content).unwrap();
147196
fs::write(dir.path().join(".djls.toml"), "debug = true").unwrap();
148197
let settings = Settings::new(dir.path()).unwrap();
149-
assert_eq!(settings, Settings { debug: true }); // .djls.toml wins
198+
// .djls.toml wins
199+
assert_eq!(
200+
settings,
201+
Settings {
202+
debug: true,
203+
..Default::default()
204+
}
205+
);
150206
}
151207

152208
#[test]
@@ -157,7 +213,14 @@ mod tests {
157213
fs::write(dir.path().join(".djls.toml"), "debug = false").unwrap();
158214
fs::write(dir.path().join("djls.toml"), "debug = true").unwrap();
159215
let settings = Settings::new(dir.path()).unwrap();
160-
assert_eq!(settings, Settings { debug: true }); // djls.toml wins
216+
// djls.toml wins
217+
assert_eq!(
218+
settings,
219+
Settings {
220+
debug: true,
221+
..Default::default()
222+
}
223+
);
161224
}
162225

163226
#[test]
@@ -171,7 +234,14 @@ mod tests {
171234

172235
let settings =
173236
Settings::load_from_paths(project_dir.path(), Some(&user_conf_path)).unwrap();
174-
assert_eq!(settings, Settings { debug: false }); // pyproject.toml overrides user
237+
// pyproject.toml overrides user
238+
assert_eq!(
239+
settings,
240+
Settings {
241+
debug: false,
242+
..Default::default()
243+
}
244+
);
175245
}
176246

177247
#[test]
@@ -184,7 +254,14 @@ mod tests {
184254

185255
let settings =
186256
Settings::load_from_paths(project_dir.path(), Some(&user_conf_path)).unwrap();
187-
assert_eq!(settings, Settings { debug: false }); // djls.toml overrides user
257+
// djls.toml overrides user
258+
assert_eq!(
259+
settings,
260+
Settings {
261+
debug: false,
262+
..Default::default()
263+
}
264+
);
188265
}
189266
}
190267

@@ -200,7 +277,13 @@ mod tests {
200277

201278
let settings =
202279
Settings::load_from_paths(project_dir.path(), Some(&user_conf_path)).unwrap();
203-
assert_eq!(settings, Settings { debug: true });
280+
assert_eq!(
281+
settings,
282+
Settings {
283+
debug: true,
284+
..Default::default()
285+
}
286+
);
204287
}
205288

206289
#[test]
@@ -214,7 +297,13 @@ mod tests {
214297
// Should load project settings fine, ignoring non-existent user config
215298
let settings =
216299
Settings::load_from_paths(project_dir.path(), Some(&user_conf_path)).unwrap();
217-
assert_eq!(settings, Settings { debug: true });
300+
assert_eq!(
301+
settings,
302+
Settings {
303+
debug: true,
304+
..Default::default()
305+
}
306+
);
218307
}
219308

220309
#[test]
@@ -225,7 +314,13 @@ mod tests {
225314

226315
// Call helper with None for user path
227316
let settings = Settings::load_from_paths(project_dir.path(), None).unwrap();
228-
assert_eq!(settings, Settings { debug: true });
317+
assert_eq!(
318+
settings,
319+
Settings {
320+
debug: true,
321+
..Default::default()
322+
}
323+
);
229324
}
230325
}
231326

crates/djls-project/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ pyo3 = { workspace = true }
88
tower-lsp-server = { workspace = true, features = ["proposed"] }
99

1010
which = "7.0.1"
11+
12+
[dev-dependencies]
13+
tempfile = "3.19"

0 commit comments

Comments
 (0)