Skip to content

Commit d5b5bb0

Browse files
authored
Add detection for in-project Poetry environments and support for poetry.toml (#283)
Implement detection for in-project Poetry environments by checking for the presence of poetry.toml and pyproject.toml files. Update tests to ensure proper functionality. fixes #282
1 parent a6747a8 commit d5b5bb0

File tree

4 files changed

+278
-23
lines changed

4 files changed

+278
-23
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/pet-poetry/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,8 @@ sha2 = "0.10.6"
2222
base64 = "0.22.0"
2323
toml = "0.8.14"
2424

25+
[dev-dependencies]
26+
tempfile = "3.12"
27+
2528
[features]
2629
ci = []

crates/pet-poetry/src/lib.rs

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ lazy_static! {
3535
.expect("Error generating RegEx for poetry environment name pattern");
3636
}
3737

38-
/// Check if a path looks like a Poetry environment by examining the directory structure
39-
/// Poetry environments typically have names like: {name}-{hash}-py{version}
40-
/// and are located in cache directories or as .venv in project directories
41-
fn is_poetry_environment(path: &Path) -> bool {
38+
/// Check if a path looks like a Poetry environment in the cache directory
39+
/// Poetry cache environments have names like: {name}-{hash}-py{version}
40+
/// and are located in cache directories containing "pypoetry/virtualenvs"
41+
fn is_poetry_cache_environment(path: &Path) -> bool {
4242
// Check if the environment is in a directory that looks like Poetry's virtualenvs cache
4343
// Common patterns:
4444
// - Linux: ~/.cache/pypoetry/virtualenvs/
@@ -62,6 +62,56 @@ fn is_poetry_environment(path: &Path) -> bool {
6262
false
6363
}
6464

65+
/// Check if a .venv directory is an in-project Poetry environment
66+
/// This is for the case when virtualenvs.in-project = true is set.
67+
/// We check if the parent directory has Poetry configuration files.
68+
fn is_in_project_poetry_environment(path: &Path) -> bool {
69+
// Check if this is a .venv directory
70+
let dir_name = path
71+
.file_name()
72+
.and_then(|n| n.to_str())
73+
.unwrap_or_default();
74+
if dir_name != ".venv" {
75+
return false;
76+
}
77+
78+
// Check if the parent directory has Poetry configuration
79+
if let Some(parent) = path.parent() {
80+
// Check for poetry.toml - a local Poetry configuration file
81+
// Its presence indicates this project uses Poetry
82+
let poetry_toml = parent.join("poetry.toml");
83+
if poetry_toml.is_file() {
84+
trace!(
85+
"Found in-project Poetry environment: {:?} with poetry.toml at {:?}",
86+
path,
87+
poetry_toml
88+
);
89+
return true;
90+
}
91+
92+
// Check if pyproject.toml contains Poetry configuration
93+
let pyproject_toml = parent.join("pyproject.toml");
94+
if pyproject_toml.is_file() {
95+
if let Ok(contents) = std::fs::read_to_string(&pyproject_toml) {
96+
// Look for [tool.poetry] or poetry as build backend
97+
if contents.contains("[tool.poetry]")
98+
|| contents.contains("poetry.core.masonry.api")
99+
|| contents.contains("poetry-core")
100+
{
101+
trace!(
102+
"Found in-project Poetry environment: {:?} with pyproject.toml at {:?}",
103+
path,
104+
pyproject_toml
105+
);
106+
return true;
107+
}
108+
}
109+
}
110+
}
111+
112+
false
113+
}
114+
65115
pub trait PoetryLocator: Send + Sync {
66116
fn find_and_report_missing_envs(
67117
&self,
@@ -203,9 +253,9 @@ impl Locator for Poetry {
203253
// This handles cases where the environment wasn't discovered during find()
204254
// (e.g., workspace directories not configured, or pyproject.toml not found)
205255
if let Some(prefix) = &env.prefix {
206-
if is_poetry_environment(prefix) {
256+
if is_poetry_cache_environment(prefix) {
207257
trace!(
208-
"Identified Poetry environment by path pattern: {:?}",
258+
"Identified Poetry environment by cache path pattern: {:?}",
209259
prefix
210260
);
211261
return environment::create_poetry_env(
@@ -214,6 +264,18 @@ impl Locator for Poetry {
214264
None, // No manager available in this fallback case
215265
);
216266
}
267+
268+
// Check for in-project .venv Poetry environment
269+
if is_in_project_poetry_environment(prefix) {
270+
trace!("Identified in-project Poetry environment: {:?}", prefix);
271+
// For in-project .venv, the project directory is the parent
272+
let project_dir = prefix.parent().unwrap_or(prefix).to_path_buf();
273+
return environment::create_poetry_env(
274+
prefix,
275+
project_dir,
276+
None, // No manager available in this fallback case
277+
);
278+
}
217279
}
218280

219281
None

0 commit comments

Comments
 (0)