Skip to content

Commit b8f25a1

Browse files
authored
fix: correct project root detection for src modules (#64)
1 parent 6a0a0f0 commit b8f25a1

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

lua/pymple/utils.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ local function find_project_root(starting_dir, root_markers)
8181
while dir ~= "/" and jumps <= MAX_UPWARD_JUMPS do
8282
for _, marker in ipairs(root_markers) do
8383
if vim.fn.glob(dir .. "/" .. marker) ~= "" then
84-
if vim.fn.glob(dir .. "/src") ~= "" then
84+
local src_path = Path:new(dir):joinpath("src")
85+
if src_path:is_dir() and not src_path:joinpath("__init__.py"):exists() then
8586
dir = dir .. "/src"
8687
end
8788
log.debug("Found project root: " .. dir)

lua/tests/utils_spec.lua

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,21 @@ local cwd = vim.fn.getcwd()
44
local mock = require("luassert.mock")
55

66
describe("find_project_root", function()
7+
local function with_temp_fixture(test_name, setup_func, test_func)
8+
local temp_dir = vim.fn.stdpath("data") .. "/pymple_test_tmp/" .. test_name
9+
local Path = require("plenary.path")
10+
Path:new(temp_dir):mkdir({ parents = true })
11+
setup_func(temp_dir)
12+
test_func(temp_dir)
13+
Path:new(temp_dir):rm({ recursive = true })
14+
end
15+
716
it("src present", function()
817
local result = utils.find_project_root(
918
FIXTURES_PATH .. "/project_with_src/src",
1019
{ "pyproject.toml" }
1120
)
12-
assert.equals(FIXTURES_PATH .. "/project_with_src/src", result)
21+
assert.equals(FIXTURES_PATH .. "/project_with_src", result)
1322
end)
1423

1524
it("no src", function()
@@ -27,6 +36,39 @@ describe("find_project_root", function()
2736
)
2837
assert.equals(nil, result)
2938
end)
39+
40+
it("src is a module (with __init__.py)", function()
41+
with_temp_fixture("src_as_module", function(temp_dir)
42+
local Path = require("plenary.path")
43+
local project_root = Path:new(temp_dir)
44+
local src_dir = project_root:joinpath("src")
45+
src_dir:mkdir({ parents = true })
46+
src_dir:joinpath("__init__.py"):touch()
47+
project_root:joinpath("pyproject.toml"):touch()
48+
end, function(temp_dir)
49+
local result = utils.find_project_root(
50+
temp_dir .. "/src/module.py",
51+
{ "pyproject.toml" }
52+
)
53+
assert.equals(temp_dir, result)
54+
end)
55+
end)
56+
57+
it("src is a source layout (without __init__.py)", function()
58+
with_temp_fixture("src_as_layout", function(temp_dir)
59+
local Path = require("plenary.path")
60+
local project_root = Path:new(temp_dir)
61+
local src_dir = project_root:joinpath("src")
62+
src_dir:mkdir({ parents = true })
63+
project_root:joinpath("pyproject.toml"):touch()
64+
end, function(temp_dir)
65+
local result = utils.find_project_root(
66+
temp_dir .. "/src/module.py",
67+
{ "pyproject.toml" }
68+
)
69+
assert.equals(temp_dir .. "/src", result)
70+
end)
71+
end)
3072
end)
3173

3274
describe("to_python_reference_path", function()

0 commit comments

Comments
 (0)