未验证 提交 45eb9361 编写于 作者: F Frost Ming 提交者: GitHub

Merge pull request #81 from frostming/tests/build

add tests for build
......@@ -125,7 +125,7 @@ which are not covered in the above example:
- `core.repository_class`: change the class of repository object, which controls how to look for candidates and metadata of a package
- `core.resolver_class`: change the resolver class, to control the resolution process
- `core.synchronizer_class`: change the synchronizer_class, to control the installation process
- `core.parser = None`: add arguments to the **root** argument parser
- `core.parser`: add arguments to the **root** argument parser
## Publish your plugin
......
Fix wheel builds when `package_dir` is mapped.
Add test cases for `pdm build`.
......@@ -72,9 +72,9 @@ def _merge_globs(include_globs, excludes_globs):
return includes, excludes
def _find_top_packages() -> List[str]:
def _find_top_packages(root) -> List[str]:
result = []
for path in os.listdir("."):
for path in os.listdir(root):
if (
os.path.isdir(path)
and os.path.exists(os.path.join(path, "__init__.py"))
......@@ -111,6 +111,7 @@ class Builder:
self.ireq = ireq
self.project = Project(ireq.unpacked_source_directory)
self._old_cwd = None
self.package_dir = None
def __enter__(self) -> "Builder":
self._old_cwd = os.getcwd()
......@@ -134,11 +135,17 @@ class Builder:
dont_find_froms = []
if not self.meta.includes:
find_froms = ["src"] if os.path.isdir("src") else _find_top_packages()
if os.path.isdir("src"):
find_froms = ["src"]
self.package_dir = "src"
else:
find_froms = _find_top_packages(".")
if not find_froms:
includes = ["*.py"]
else:
for pat in self.meta.includes:
if os.path.basename(pat) == "*":
pat = pat[:-2]
if "*" in pat or os.path.isfile(pat):
includes.append(pat)
else:
......@@ -157,6 +164,12 @@ class Builder:
includes, excludes = _merge_globs(include_globs, excludes_globs)
for path in find_froms:
if (
not os.path.isfile(os.path.join(path, "__init__.py"))
and _find_top_packages(path)
and not self.package_dir
):
self.package_dir = path
for root, dirs, filenames in os.walk(path):
if root == "__pycache__" or any(
......@@ -189,7 +202,7 @@ class Builder:
if self.project.pyproject_file.exists():
yield "pyproject.toml"
def find_files_to_add(self, include_build: bool = False) -> List[str]:
def find_files_to_add(self, include_build: bool = False) -> List[Path]:
"""Traverse the project path and return a list of file names
that should be included in a sdist distribution.
If include_build is True, will include files like LICENSE, README and pyproject
......
......@@ -182,7 +182,13 @@ class WheelBuilder(Builder):
def _copy_module(self, wheel):
for path in self.find_files_to_add():
self._add_file(wheel, str(path))
rel_path = None
if self.package_dir:
try:
rel_path = path.relative_to(self.package_dir).as_posix()
except ValueError:
pass
self._add_file(wheel, str(path), rel_path)
def _add_file(self, wheel, full_path, rel_path=None):
if not rel_path:
......
......@@ -378,7 +378,7 @@ def do_build(
stream.echo("All artifacts are disabled, nothing to do.", err=True)
return
ireq = project.make_self_candidate(False).ireq
ireq.source_dir = "."
ireq.source_dir = project.root.as_posix()
if clean:
shutil.rmtree(dest, ignore_errors=True)
if sdist:
......
......@@ -48,7 +48,7 @@ class PackageMeta:
if isinstance(value, str):
return value
version_source = value.get("from")
with open(version_source, encoding="utf-8") as fp:
with self.project.root.joinpath(version_source).open(encoding="utf-8") as fp:
version = re.findall(
r"^__version__\s*=\s*[\"'](.+?)[\"']\s*$", fp.read(), re.M
)[0]
......
import tarfile
import zipfile
from distlib.wheel import Wheel
from pdm.cli import actions
def get_tarball_names(path):
with tarfile.open(path, "r:gz") as tar:
return tar.getnames()
def get_wheel_names(path):
with zipfile.ZipFile(path) as zf:
return zf.namelist()
def test_build_single_module(fixture_project):
project = fixture_project("demo-module")
assert project.meta.version == "0.1.0"
actions.do_build(project)
tar_names = get_tarball_names(project.root / "dist/demo-module-0.1.0.tar.gz")
for name in [
"foo_module.py",
"bar_module.py",
"LICENSE",
"pyproject.toml",
"PKG-INFO",
]:
assert f"demo-module-0.1.0/{name}" in tar_names
zip_names = get_wheel_names(
project.root / "dist/demo_module-0.1.0-py3-none-any.whl"
)
for name in ["foo_module.py", "bar_module.py"]:
assert name in zip_names
for name in ("pyproject.toml", "LICENSE"):
assert name not in zip_names
assert Wheel(
(project.root / "dist/demo_module-0.1.0-py3-none-any.whl").as_posix()
).metadata
def test_build_single_module_with_readme(fixture_project):
project = fixture_project("demo-module")
project.tool_settings["readme"] = "README.md"
project.write_pyproject()
actions.do_build(project)
assert "demo-module-0.1.0/README.md" in get_tarball_names(
project.root / "dist/demo-module-0.1.0.tar.gz"
)
def test_build_package(fixture_project):
project = fixture_project("demo-package")
actions.do_build(project)
tar_names = get_tarball_names(project.root / "dist/demo-package-0.1.0.tar.gz")
assert "demo-package-0.1.0/my_package/__init__.py" in tar_names
assert "demo-package-0.1.0/my_package/data.json" in tar_names
assert "demo-package-0.1.0/single_module.py" not in tar_names
assert "demo-package-0.1.0/data_out.json" not in tar_names
zip_names = get_wheel_names(
project.root / "dist/demo_package-0.1.0-py3-none-any.whl"
)
assert "my_package/__init__.py" in zip_names
assert "my_package/data.json" in zip_names
assert "single_module.py" not in zip_names
assert "data_out.json" not in zip_names
def test_build_src_package(fixture_project):
project = fixture_project("demo-src-package")
actions.do_build(project)
tar_names = get_tarball_names(project.root / "dist/demo-package-0.1.0.tar.gz")
assert "demo-package-0.1.0/src/my_package/__init__.py" in tar_names
assert "demo-package-0.1.0/src/my_package/data.json" in tar_names
zip_names = get_wheel_names(
project.root / "dist/demo_package-0.1.0-py3-none-any.whl"
)
assert "my_package/__init__.py" in zip_names
assert "my_package/data.json" in zip_names
def test_build_package_include(fixture_project):
project = fixture_project("demo-package")
project.tool_settings["includes"] = [
"my_package/",
"single_module.py",
"data_out.json",
]
project.tool_settings["excludes"] = ["my_package/*.json"]
project.write_pyproject()
actions.do_build(project)
tar_names = get_tarball_names(project.root / "dist/demo-package-0.1.0.tar.gz")
assert "demo-package-0.1.0/my_package/__init__.py" in tar_names
assert "demo-package-0.1.0/my_package/data.json" not in tar_names
assert "demo-package-0.1.0/single_module.py" in tar_names
assert "demo-package-0.1.0/data_out.json" in tar_names
zip_names = get_wheel_names(
project.root / "dist/demo_package-0.1.0-py3-none-any.whl"
)
assert "my_package/__init__.py" in zip_names
assert "my_package/data.json" not in zip_names
assert "single_module.py" in zip_names
assert "data_out.json" in zip_names
......@@ -4,6 +4,7 @@ import json
import os
import shutil
import sys
from distutils.dir_util import copy_tree
from io import BytesIO
from pathlib import Path
from typing import Callable, Iterable, List, Optional, Tuple
......@@ -259,6 +260,18 @@ def project(project_no_init):
return project_no_init
@pytest.fixture()
def fixture_project(project_no_init):
"""Initailize a project from a fixture project"""
def func(project_name):
source = FIXTURES / "projects" / project_name
copy_tree(source.as_posix(), project_no_init.root.as_posix())
return project_no_init
return func
@pytest.fixture()
def repository(project, mocker):
rv = TestRepository([], project.environment)
......
[build-system]
build-backend = "pdm.builders.api"
requires = ["pdm"]
[tool]
[tool.pdm]
author = "frostming <mianghong@gmail.com>"
description = ""
homepage = ""
license = "MIT"
name = "demo-module"
python_requires = ">=3.5"
version = { from = "foo_module.py" }
[tool.pdm.dependencies]
[tool.pdm.dev-dependencies]
[build-system]
build-backend = "pdm.builders.api"
requires = ["pdm"]
[tool]
[tool.pdm]
author = "frostming <mianghong@gmail.com>"
description = ""
homepage = ""
license = "MIT"
name = "demo-package"
python_requires = ">=3.5"
version = { from = "my_package/__init__.py" }
readme = "README.md"
[tool.pdm.dependencies]
[tool.pdm.dev-dependencies]
[build-system]
build-backend = "pdm.builders.api"
requires = ["pdm"]
[tool]
[tool.pdm]
author = "frostming <mianghong@gmail.com>"
description = ""
homepage = ""
license = "MIT"
name = "demo-package"
python_requires = ">=3.5"
version = { from = "src/my_package/__init__.py" }
[tool.pdm.dependencies]
[tool.pdm.dev-dependencies]
from setuptools import setup
setup(
name="test-plugin",
version="0.0.1",
py_modules=["hello"],
entry_points={"pdm.plugin": ["hello = hello:main"]},
)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册