summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonny Pfannschmidt <opensource@ronnypfannschmidt.de>2022-06-26 23:06:53 +0200
committerRonny Pfannschmidt <opensource@ronnypfannschmidt.de>2022-06-26 23:06:53 +0200
commit1d920c7dd3d21000570c68c4cb3af24a9cdfac5e (patch)
tree10e30b8cb9728d4a6a0d0be149d42ba00be3a972
parent1c00405a0e5075a2330c60a69f72d4c7aad88203 (diff)
downloadsetuptools-scm-1d920c7dd3d21000570c68c4cb3af24a9cdfac5e.tar.gz
fix #691 - support root in pyproject.toml even for cli
superseeds #702 which served as inspiration adds integration tests
-rw-r--r--src/setuptools_scm/_cli.py21
-rw-r--r--src/setuptools_scm/config.py35
-rw-r--r--testing/conftest.py26
-rw-r--r--testing/test_cli.py50
-rw-r--r--testing/test_git.py7
5 files changed, 115 insertions, 24 deletions
diff --git a/src/setuptools_scm/_cli.py b/src/setuptools_scm/_cli.py
index 88dd6d0..4883c4f 100644
--- a/src/setuptools_scm/_cli.py
+++ b/src/setuptools_scm/_cli.py
@@ -10,15 +10,15 @@ from setuptools_scm.discover import walk_potential_roots
from setuptools_scm.integration import find_files
-def main() -> None:
- opts = _get_cli_opts()
- root = opts.root or "."
+def main(args: list[str] | None = None) -> None:
+ opts = _get_cli_opts(args)
+ inferred_root: str = opts.root or "."
- pyproject = opts.config or _find_pyproject(root)
+ pyproject = opts.config or _find_pyproject(inferred_root)
try:
- root = opts.root or os.path.relpath(os.path.dirname(pyproject))
- config = Configuration.from_file(pyproject, root=root)
+
+ config = Configuration.from_file(pyproject, root=opts.root)
except (LookupError, FileNotFoundError) as ex:
# no pyproject.toml OR no [tool.setuptools_scm]
print(
@@ -27,10 +27,11 @@ def main() -> None:
f" Reason: {ex}.",
file=sys.stderr,
)
- config = Configuration(root=root)
+ config = Configuration(inferred_root)
version = _get_version(config)
- assert version is not None
+ if version is None:
+ raise SystemExit("ERROR: no version found for", opts)
if opts.strip_dev:
version = version.partition(".dev")[0]
print(version)
@@ -40,7 +41,7 @@ def main() -> None:
print(fname)
-def _get_cli_opts() -> argparse.Namespace:
+def _get_cli_opts(args: list[str] | None) -> argparse.Namespace:
prog = "python -m setuptools_scm"
desc = "Print project version according to SCM metadata"
parser = argparse.ArgumentParser(prog, description=desc)
@@ -68,7 +69,7 @@ def _get_cli_opts() -> argparse.Namespace:
# We avoid `metavar` to prevent printing repetitive information
desc = "List files managed by the SCM"
sub.add_parser("ls", help=desc[0].lower() + desc[1:], description=desc)
- return parser.parse_args()
+ return parser.parse_args(args)
def _find_pyproject(parent: str) -> str:
diff --git a/src/setuptools_scm/config.py b/src/setuptools_scm/config.py
index f73b905..fee652c 100644
--- a/src/setuptools_scm/config.py
+++ b/src/setuptools_scm/config.py
@@ -24,6 +24,7 @@ if TYPE_CHECKING:
DEFAULT_TAG_REGEX = r"^(?:[\w-]+-)?(?P<version>[vV]?\d+(?:\.\d+){0,2}[^\+]*)(?:\+.*)?$"
DEFAULT_VERSION_SCHEME = "guess-next-dev"
DEFAULT_LOCAL_SCHEME = "node-and-date"
+_ROOT = "root"
def _check_tag_regex(value: str | Pattern[str] | None) -> Pattern[str]:
@@ -213,6 +214,7 @@ class Configuration:
with open(name, encoding="UTF-8") as strm:
data = strm.read()
+
defn = _load_toml(data)
try:
section = defn.get("tool", {})["setuptools_scm"]
@@ -220,6 +222,21 @@ class Configuration:
raise LookupError(
f"{name} does not contain a tool.setuptools_scm section"
) from e
+
+ project = defn.get("project", {})
+ dist_name = cls._cleanup_from_file_args_data(
+ project, dist_name, kwargs, section
+ )
+ return cls(dist_name=dist_name, relative_to=name, **section, **kwargs)
+
+ @staticmethod
+ def _cleanup_from_file_args_data(
+ project: dict[str, Any],
+ dist_name: str | None,
+ kwargs: dict[str, Any],
+ section: dict[str, Any],
+ ) -> str | None:
+ """drops problematic details and figures the distribution name"""
if "dist_name" in section:
if dist_name is None:
dist_name = section.pop("dist_name")
@@ -227,13 +244,21 @@ class Configuration:
assert dist_name == section["dist_name"]
del section["dist_name"]
if dist_name is None:
- if "project" in defn:
- # minimal pep 621 support for figuring the pretend keys
- dist_name = defn["project"].get("name")
+ # minimal pep 621 support for figuring the pretend keys
+ dist_name = project.get("name")
if dist_name is None:
dist_name = _read_dist_name_from_setup_cfg()
-
- return cls(dist_name=dist_name, **section, **kwargs)
+ if _ROOT in kwargs:
+ if kwargs[_ROOT] is None:
+ kwargs.pop(_ROOT, None)
+ elif _ROOT in section:
+ if section[_ROOT] != kwargs[_ROOT]:
+ warnings.warn(
+ f"root {section[_ROOT]} is overridden"
+ f" by the cli arg {kwargs[_ROOT]}"
+ )
+ section.pop("root", None)
+ return dist_name
def _read_dist_name_from_setup_cfg() -> str | None:
diff --git a/testing/conftest.py b/testing/conftest.py
index c881042..d29b5dd 100644
--- a/testing/conftest.py
+++ b/testing/conftest.py
@@ -3,10 +3,10 @@ from __future__ import annotations
import os
from pathlib import Path
from typing import Any
-from typing import Generator
import pytest
+import setuptools_scm.utils
from .wd_wrapper import WorkDir
@@ -39,13 +39,25 @@ def pytest_addoption(parser: Any) -> None:
)
-@pytest.fixture(autouse=True)
-def debug_mode() -> Generator[None, None, None]:
- from setuptools_scm import utils
+class DebugMode:
+ def __init__(self, monkeypatch: pytest.MonkeyPatch):
+ self.__monkeypatch = monkeypatch
+ self.__module = setuptools_scm.utils
+
+ __monkeypatch: pytest.MonkeyPatch
+
+ def enable(self) -> None:
+ self.__monkeypatch.setattr(self.__module, "DEBUG", True)
- utils.DEBUG = True
- yield
- utils.DEBUG = False
+ def disable(self) -> None:
+ self.__monkeypatch.setattr(self.__module, "DEBUG", False)
+
+
+@pytest.fixture(autouse=True)
+def debug_mode(monkeypatch: pytest.MonkeyPatch) -> DebugMode:
+ debug_mode = DebugMode(monkeypatch)
+ debug_mode.enable()
+ return debug_mode
@pytest.fixture
diff --git a/testing/test_cli.py b/testing/test_cli.py
new file mode 100644
index 0000000..0198111
--- /dev/null
+++ b/testing/test_cli.py
@@ -0,0 +1,50 @@
+from __future__ import annotations
+
+import io
+from contextlib import redirect_stdout
+
+import pytest
+
+from .conftest import DebugMode
+from .test_git import wd as wd_fixture # NOQA evil fixture reuse
+from .wd_wrapper import WorkDir
+from setuptools_scm._cli import main
+
+
+PYPROJECT_TOML = "pyproject.toml"
+PYPROJECT_SIMPLE = "[tool.setuptools_scm]"
+PYPROJECT_ROOT = '[tool.setuptools_scm]\nroot=".."'
+
+
+def get_output(args: list[str]) -> str:
+
+ with redirect_stdout(io.StringIO()) as out:
+ main(args)
+ return out.getvalue()
+
+
+def test_cli_find_pyproject(
+ wd: WorkDir, monkeypatch: pytest.MonkeyPatch, debug_mode: DebugMode
+) -> None:
+ debug_mode.disable()
+ wd.commit_testfile()
+ wd.write(PYPROJECT_TOML, PYPROJECT_SIMPLE)
+ monkeypatch.chdir(wd.cwd)
+
+ out = get_output([])
+ assert out.startswith("0.1.dev1+")
+
+ with pytest.raises(SystemExit, match="no version found for"):
+ get_output(["--root=.."])
+
+ wd.write(PYPROJECT_TOML, PYPROJECT_ROOT)
+ with pytest.raises(SystemExit, match="no version found for"):
+ print(get_output(["-c", PYPROJECT_TOML]))
+
+ with pytest.raises(SystemExit, match="no version found for"):
+
+ get_output(["-c", PYPROJECT_TOML, "--root=.."])
+
+ with pytest.warns(UserWarning, match="root .. is overridden by the cli arg ."):
+ out = get_output(["-c", PYPROJECT_TOML, "--root=."])
+ assert out.startswith("0.1.dev1+")
diff --git a/testing/test_git.py b/testing/test_git.py
index 661a5ee..105a9e0 100644
--- a/testing/test_git.py
+++ b/testing/test_git.py
@@ -15,6 +15,7 @@ from unittest.mock import patch
import pytest
+from .conftest import DebugMode
from .wd_wrapper import WorkDir
from setuptools_scm import Configuration
from setuptools_scm import format_version
@@ -31,14 +32,16 @@ pytestmark = pytest.mark.skipif(
)
-@pytest.fixture
-def wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch) -> WorkDir:
+@pytest.fixture(name="wd")
+def wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch, debug_mode: DebugMode) -> WorkDir:
+ debug_mode.disable()
monkeypatch.delenv("HOME", raising=False)
wd("git init")
wd("git config user.email test@example.com")
wd('git config user.name "a test"')
wd.add_command = "git add ."
wd.commit_command = "git commit -m test-{reason}"
+ debug_mode.enable()
return wd