Skip to content

Commit 588ac7e

Browse files
Refactor to use heuristic to decide on source layout (#323)
1 parent efaf6c1 commit 588ac7e

7 files changed

Lines changed: 73 additions & 15 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ version-file = "src/usethis/_version.py"
8484
[tool.ruff]
8585
line-length = 88
8686

87-
src = [ "src" ]
8887
lint.select = [
8988
"A",
9089
"C4",
@@ -178,7 +177,7 @@ type = "layers"
178177
layers = [
179178
"bitbucket | github | pre_commit | pytest | ruff",
180179
"uv | pydantic | sonarqube",
181-
"pyproject | yaml | python",
180+
"project | pyproject | yaml | python",
182181
]
183182
containers = [ "usethis._integrations" ]
184183
exhaustive = true

src/usethis/_integrations/project/__init__.py

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pathlib import Path
2+
from typing import Literal
3+
4+
5+
def get_source_dir_str() -> Literal["src", "."]:
6+
src_dir = Path.cwd() / "src"
7+
8+
if src_dir.exists() and src_dir.is_dir():
9+
return "src"
10+
return "."

src/usethis/_integrations/sonarqube/config.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from pydantic import TypeAdapter
55

6+
from usethis._integrations.project.layout import get_source_dir_str
67
from usethis._integrations.pyproject.core import get_config_value
78
from usethis._integrations.python.version import get_python_version
89
from usethis._integrations.sonarqube.errors import (
@@ -61,11 +62,17 @@ def get_sonar_project_properties() -> str:
6162
raise CoverageReportConfigNotFoundError(msg)
6263

6364
# No file, so construct the contents
65+
source_dir_str = get_source_dir_str()
66+
if source_dir_str == ".":
67+
sources = "./"
68+
else:
69+
sources = f"./{source_dir_str}"
70+
6471
text = f"""\
6572
sonar.projectKey={project_key}
6673
sonar.language=py
6774
sonar.python.version={python_version}
68-
sonar.sources=./src
75+
sonar.sources={sources}
6976
sonar.tests=./tests
7077
sonar.python.coverage.reportPaths={coverage_output}
7178
sonar.verbose={"true" if verbose else "false"}

src/usethis/_tool.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
LocalRepo,
2222
UriRepo,
2323
)
24+
from usethis._integrations.project.layout import get_source_dir_str
2425
from usethis._integrations.pyproject.config import PyProjectConfig
2526
from usethis._integrations.pyproject.core import (
2627
PyProjectTOMLValueAlreadySetError,
@@ -280,7 +281,7 @@ def get_pyproject_configs(self) -> list[PyProjectConfig]:
280281
PyProjectConfig(
281282
id_keys=["tool", "coverage", "run"],
282283
value={
283-
"source": ["src"],
284+
"source": [get_source_dir_str()],
284285
"omit": ["*/pytest-of-*/*"],
285286
},
286287
),
@@ -316,17 +317,19 @@ def dev_deps(self) -> list[Dependency]:
316317
return [Dependency(name="deptry")]
317318

318319
def print_how_to_use(self) -> None:
319-
box_print("Run 'deptry src' to run deptry.")
320+
_dir = get_source_dir_str()
321+
box_print(f"Run 'deptry {_dir}' to run deptry.")
320322

321323
def get_pre_commit_repos(self) -> list[LocalRepo | UriRepo]:
324+
_dir = get_source_dir_str()
322325
return [
323326
LocalRepo(
324327
repo="local",
325328
hooks=[
326329
HookDefinition(
327330
id="deptry",
328331
name="deptry",
329-
entry="uv run --frozen deptry src",
332+
entry=f"uv run --frozen deptry {_dir}",
330333
language=Language("system"),
331334
always_run=True,
332335
pass_filenames=False,
@@ -339,14 +342,15 @@ def get_pyproject_id_keys(self) -> list[list[str]]:
339342
return [["tool", "deptry"]]
340343

341344
def get_bitbucket_steps(self) -> list[BitbucketStep]:
345+
_dir = get_source_dir_str()
342346
return [
343347
BitbucketStep(
344348
name="Run Deptry",
345349
caches=["uv"],
346350
script=BitbucketScript(
347351
[
348352
BitbucketScriptItemAnchor(name="install-uv"),
349-
"uv run deptry src",
353+
f"uv run deptry {_dir}",
350354
]
351355
),
352356
)
@@ -573,7 +577,6 @@ def get_pyproject_configs(self) -> list[PyProjectConfig]:
573577
PyProjectConfig(
574578
id_keys=["tool", "ruff"],
575579
value={
576-
"src": ["src"],
577580
"line-length": 88,
578581
"lint": {"select": []},
579582
},
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from pathlib import Path
2+
3+
from usethis._integrations.project.layout import get_source_dir_str
4+
from usethis._test import change_cwd
5+
6+
7+
class TestGetSourceDirStr:
8+
def test_has_src(self, tmp_path: Path):
9+
# Arrange
10+
(tmp_path / "src").mkdir()
11+
12+
# Act
13+
with change_cwd(tmp_path):
14+
result = get_source_dir_str()
15+
16+
# Assert
17+
assert result == "src"
18+
19+
def test_no_src(self, tmp_path: Path):
20+
# Arrange
21+
(tmp_path / "foo").mkdir()
22+
23+
# Act
24+
with change_cwd(tmp_path):
25+
result = get_source_dir_str()
26+
27+
# Assert
28+
assert result == "."
29+
30+
def test_src_file_not_dir(self, tmp_path: Path):
31+
# Arrange
32+
(tmp_path / "src").touch()
33+
34+
# Act
35+
with change_cwd(tmp_path):
36+
result = get_source_dir_str()
37+
38+
# Assert
39+
assert result == "."

tests/usethis/_integrations/sonarqube/test_sonarqube_config.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def test_different_python_version(self, tmp_path: Path):
9595
sonar.projectKey=foobar
9696
sonar.language=py
9797
sonar.python.version=3.10
98-
sonar.sources=./src
98+
sonar.sources=./
9999
sonar.tests=./tests
100100
sonar.python.coverage.reportPaths=coverage.xml
101101
sonar.verbose=false
@@ -125,7 +125,7 @@ def test_no_pin_python(self, tmp_path: Path):
125125
sonar.projectKey=foobar
126126
sonar.language=py
127127
sonar.python.version={get_python_version()}
128-
sonar.sources=./src
128+
sonar.sources=./
129129
sonar.tests=./tests
130130
sonar.python.coverage.reportPaths=coverage.xml
131131
sonar.verbose=false
@@ -156,7 +156,7 @@ def test_different_project_key(self, tmp_path: Path):
156156
sonar.projectKey=different
157157
sonar.language=py
158158
sonar.python.version=3.12
159-
sonar.sources=./src
159+
sonar.sources=./
160160
sonar.tests=./tests
161161
sonar.python.coverage.reportPaths=coverage.xml
162162
sonar.verbose=false
@@ -191,7 +191,7 @@ def test_set_verbose_true(self, tmp_path: Path):
191191
sonar.projectKey=foobar
192192
sonar.language=py
193193
sonar.python.version=3.12
194-
sonar.sources=./src
194+
sonar.sources=./
195195
sonar.tests=./tests
196196
sonar.python.coverage.reportPaths=coverage.xml
197197
sonar.verbose=true
@@ -239,7 +239,7 @@ def test_patch_version_ignored(self, tmp_path: Path):
239239
sonar.projectKey=foobar
240240
sonar.language=py
241241
sonar.python.version=3.12
242-
sonar.sources=./src
242+
sonar.sources=./
243243
sonar.tests=./tests
244244
sonar.python.coverage.reportPaths=coverage.xml
245245
sonar.verbose=false
@@ -277,7 +277,7 @@ def test_exclusions(self, tmp_path: Path):
277277
sonar.projectKey=foobar
278278
sonar.language=py
279279
sonar.python.version=3.12
280-
sonar.sources=./src
280+
sonar.sources=./
281281
sonar.tests=./tests
282282
sonar.python.coverage.reportPaths=coverage.xml
283283
sonar.verbose=false
@@ -309,7 +309,7 @@ def test_different_coverage_file_location(self, tmp_path: Path):
309309
sonar.projectKey=foobar
310310
sonar.language=py
311311
sonar.python.version=3.12
312-
sonar.sources=./src
312+
sonar.sources=./
313313
sonar.tests=./tests
314314
sonar.python.coverage.reportPaths=./test-reports/cov.xml
315315
sonar.verbose=false

0 commit comments

Comments
 (0)