Skip to content

Commit 1efb553

Browse files
committed
add poetry.toml support for detection
1 parent 9aa6886 commit 1efb553

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

crates/pet-poetry/src/lib.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn is_poetry_cache_environment(path: &Path) -> bool {
6464

6565
/// Check if a .venv directory is an in-project Poetry environment
6666
/// This is for the case when virtualenvs.in-project = true is set.
67-
/// We check if the parent directory has a pyproject.toml with Poetry configuration.
67+
/// We check if the parent directory has Poetry configuration files.
6868
fn is_in_project_poetry_environment(path: &Path) -> bool {
6969
// Check if this is a .venv directory
7070
let dir_name = path
@@ -75,16 +75,28 @@ fn is_in_project_poetry_environment(path: &Path) -> bool {
7575
return false;
7676
}
7777

78-
// Check if the parent directory has a pyproject.toml with Poetry configuration
78+
// Check if the parent directory has Poetry configuration
7979
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
8093
let pyproject_toml = parent.join("pyproject.toml");
8194
if pyproject_toml.is_file() {
82-
// Check if pyproject.toml contains Poetry configuration
8395
if let Ok(contents) = std::fs::read_to_string(&pyproject_toml) {
84-
// Look for [tool.poetry] or [project] with poetry as build backend
96+
// Look for [tool.poetry] or poetry as build backend
8597
if contents.contains("[tool.poetry]")
86-
|| (contents.contains("poetry.core.masonry.api")
87-
|| contents.contains("poetry-core"))
98+
|| contents.contains("poetry.core.masonry.api")
99+
|| contents.contains("poetry-core")
88100
{
89101
trace!(
90102
"Found in-project Poetry environment: {:?} with pyproject.toml at {:?}",

crates/pet-poetry/tests/path_identification_test.rs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
//! The fix adds fallback path-based detection that checks:
1313
//! 1. If the environment path matches Poetry's cache naming pattern
1414
//! ({name}-{8-char-hash}-py{version}) in "pypoetry/virtualenvs"
15-
//! 2. If the environment is an in-project .venv with a pyproject.toml
16-
//! containing Poetry configuration
15+
//! 2. If the environment is an in-project .venv with Poetry configuration:
16+
//! - poetry.toml exists in the parent directory, OR
17+
//! - pyproject.toml contains [tool.poetry] or poetry-core build backend
1718
1819
use std::fs;
1920
use std::path::PathBuf;
@@ -50,8 +51,15 @@ mod tests {
5051
return false;
5152
}
5253

53-
// Check if the parent directory has a pyproject.toml with Poetry configuration
54+
// Check if the parent directory has Poetry configuration
5455
if let Some(parent) = path.parent() {
56+
// Check for poetry.toml - a local Poetry configuration file
57+
let poetry_toml = parent.join("poetry.toml");
58+
if poetry_toml.is_file() {
59+
return true;
60+
}
61+
62+
// Check if pyproject.toml contains Poetry configuration
5563
let pyproject_toml = parent.join("pyproject.toml");
5664
if pyproject_toml.is_file() {
5765
if let Ok(contents) = std::fs::read_to_string(&pyproject_toml) {
@@ -217,18 +225,50 @@ build-backend = "setuptools.build_meta"
217225
}
218226

219227
#[test]
220-
fn test_in_project_env_no_pyproject_rejected() {
228+
fn test_in_project_env_no_poetry_config_rejected() {
221229
let temp_dir = tempfile::tempdir().unwrap();
222230
let project_dir = temp_dir.path();
223231
let venv_dir = project_dir.join(".venv");
224232

225-
// Create .venv directory without pyproject.toml
233+
// Create .venv directory without any Poetry configuration files
226234
fs::create_dir(&venv_dir).unwrap();
227235

228236
// Test that the .venv is NOT recognized as a Poetry environment
229237
assert!(!test_in_project_poetry_env(&venv_dir));
230238
}
231239

240+
#[test]
241+
fn test_in_project_poetry_env_with_poetry_toml() {
242+
let temp_dir = tempfile::tempdir().unwrap();
243+
let project_dir = temp_dir.path();
244+
let venv_dir = project_dir.join(".venv");
245+
246+
// Create .venv directory
247+
fs::create_dir(&venv_dir).unwrap();
248+
249+
// Create poetry.toml with in-project setting (no pyproject.toml with Poetry config)
250+
let poetry_toml_content = r#"
251+
[virtualenvs]
252+
in-project = true
253+
"#;
254+
fs::write(project_dir.join("poetry.toml"), poetry_toml_content).unwrap();
255+
256+
// Create minimal pyproject.toml without Poetry-specific config
257+
let pyproject_content = r#"
258+
[project]
259+
name = "my-project"
260+
version = "0.1.0"
261+
262+
[build-system]
263+
requires = ["setuptools>=45"]
264+
build-backend = "setuptools.build_meta"
265+
"#;
266+
fs::write(project_dir.join("pyproject.toml"), pyproject_content).unwrap();
267+
268+
// Test that the .venv is recognized as a Poetry environment due to poetry.toml
269+
assert!(test_in_project_poetry_env(&venv_dir));
270+
}
271+
232272
#[test]
233273
fn test_non_venv_directory_rejected() {
234274
let temp_dir = tempfile::tempdir().unwrap();

0 commit comments

Comments
 (0)