Commit 0bff3b14 by Sébastien Eustace

Add support for src/ layout in packages

parent d774c58f
......@@ -7,6 +7,7 @@
- Added the `cache:clear` command.
- Added support for `git` dependencies in the `add` command.
- Added support for `file` dependencies in the `add` command.
- Added support for `src/` layout for packages.
### Changed
......
......@@ -72,26 +72,32 @@ class Builder(object):
src = self._module.path
to_add = []
for root, dirs, files in os.walk(src.as_posix()):
root = Path(root)
if root.name == '__pycache__':
continue
if not self._module.is_package():
if self._module.is_in_src():
to_add.append(src.relative_to(src.parent.parent))
else:
to_add.append(src.relative_to(src.parent))
else:
for root, dirs, files in os.walk(src.as_posix()):
root = Path(root)
if root.name == '__pycache__':
continue
for file in files:
file = root / file
file = file.relative_to(self._path)
for file in files:
file = root / file
file = file.relative_to(self._path)
if file in excluded:
continue
if file in excluded:
continue
if file.suffix == '.pyc':
continue
if file.suffix == '.pyc':
continue
self._io.writeln(
' - Adding: <comment>{}</comment>'.format(str(file)),
verbosity=self._io.VERBOSITY_VERY_VERBOSE
)
to_add.append(file)
self._io.writeln(
' - Adding: <comment>{}</comment>'.format(str(file)),
verbosity=self._io.VERBOSITY_VERY_VERBOSE
)
to_add.append(file)
# Include project files
self._io.writeln(
......
......@@ -119,6 +119,10 @@ class SdistBuilder(Builder):
'build(setup_kwargs)'
]
if self._module.is_in_src():
before.append("package_dir = \\\n{}\n".format(pformat({'': 'src'})))
extra.append("'package_dir': package_dir,")
if self._module.is_package():
packages, package_data = self.find_packages(
self._module.path.as_posix()
......
......@@ -133,6 +133,14 @@ class WheelBuilder(Builder):
for file in sorted(files):
full_path = self._path / file
if self._module.is_in_src():
try:
file = file.relative_to(
self._module.path.parent.relative_to(self._path)
)
except ValueError:
pass
# Do not include topmost files
if full_path.relative_to(self._path) == Path(file.name):
continue
......
......@@ -6,6 +6,7 @@ class Module:
def __init__(self, name, directory='.'):
self._name = module_name(name)
self._in_src = False
# It must exist either as a .py file or a directory, but not both
pkg_dir = Path(directory, self._name)
......@@ -19,7 +20,23 @@ class Module:
self._path = py_file
self._is_package = False
else:
raise ValueError("No file/folder found for package {}".format(name))
# Searching for a src module
src_pkg_dir = Path(directory, 'src', self._name)
src_py_file = Path(directory, 'src', self._name + '.py')
if src_pkg_dir.is_dir() and src_py_file.is_file():
raise ValueError(
"Both {} and {} exist".format(pkg_dir, py_file))
elif src_pkg_dir.is_dir():
self._in_src = True
self._path = src_pkg_dir
self._is_package = True
elif src_py_file.is_file():
self._in_src = True
self._path = src_py_file
self._is_package = False
else:
raise ValueError("No file/folder found for package {}".format(name))
@property
def name(self): # type: () -> str
......@@ -38,3 +55,6 @@ class Module:
def is_package(self): # type: () -> bool
return self._is_package
def is_in_src(self): # type: () -> bool
return self._in_src
[tool.poetry]
name = "module-src"
version = "0.1"
description = "Some description."
authors = [
"Sébastien Eustace <sebastien@eustace.io>"
]
license = "MIT"
readme = "README.rst"
homepage = "https://poetry.eustace.io/"
[tool.poetry.dependencies]
python = "*"
[tool.poetry]
name = "package-src"
version = "0.1"
description = "Some description."
authors = [
"Sébastien Eustace <sebastien@eustace.io>"
]
license = "MIT"
readme = "README.rst"
homepage = "https://poetry.eustace.io/"
[tool.poetry.dependencies]
python = "*"
......@@ -81,7 +81,7 @@ def test_complete():
whl = module_path / 'dist' / 'my_package-1.2.3-py3-none-any.whl'
assert whl.exists
assert whl.exists()
zip = zipfile.ZipFile(str(whl))
......@@ -133,3 +133,50 @@ My Package
"""
finally:
zip.close()
def test_module_src():
module_path = fixtures_dir / 'source_file'
builder = CompleteBuilder(Poetry.create(module_path), NullVenv(True),
NullIO())
builder.build()
sdist = module_path / 'dist' / 'module-src-0.1.tar.gz'
assert sdist.exists()
tar = tarfile.open(str(sdist), 'r')
assert 'module-src-0.1/src/module_src.py' in tar.getnames()
whl = module_path / 'dist' / 'module_src-0.1-py2.py3-none-any.whl'
assert whl.exists()
zip = zipfile.ZipFile(str(whl))
assert 'module_src.py' in zip.namelist()
def test_package_src():
module_path = fixtures_dir / 'source_package'
builder = CompleteBuilder(Poetry.create(module_path), NullVenv(True),
NullIO())
builder.build()
sdist = module_path / 'dist' / 'package-src-0.1.tar.gz'
assert sdist.exists()
tar = tarfile.open(str(sdist), 'r')
assert 'package-src-0.1/src/package_src/module.py' in tar.getnames()
whl = module_path / 'dist' / 'package_src-0.1-py2.py3-none-any.whl'
assert whl.exists()
zip = zipfile.ZipFile(str(whl))
assert 'package_src/__init__.py' in zip.namelist()
assert 'package_src/module.py' in zip.namelist()
import ast
import pytest
import re
import shutil
import tarfile
......@@ -8,6 +9,7 @@ from poetry.masonry.builders.sdist import SdistBuilder
from poetry.packages import Package
from poetry.poetry import Poetry
from poetry.utils._compat import Path
from poetry.utils._compat import to_str
from poetry.utils.venv import NullVenv
from tests.helpers import get_dependency
......@@ -175,6 +177,21 @@ def test_package():
assert sdist.exists()
def test_module():
poetry = Poetry.create(project('module1'))
builder = SdistBuilder(poetry, NullVenv(), NullIO())
builder.build()
sdist = fixtures_dir / 'module1' / 'dist' / 'module1-0.1.tar.gz'
assert sdist.exists()
tar = tarfile.open(str(sdist), 'r')
assert 'module1-0.1/module1.py' in tar.getnames()
def test_prelease():
poetry = Poetry.create(project('prerelease'))
......@@ -201,3 +218,58 @@ def test_with_c_extensions():
assert 'extended-0.1/build.py' in tar.getnames()
assert 'extended-0.1/extended/extended.c' in tar.getnames()
def test_with_src_module_file():
poetry = Poetry.create(project('source_file'))
builder = SdistBuilder(poetry, NullVenv(), NullIO())
# Check setup.py
setup = builder.build_setup()
setup_ast = ast.parse(setup)
setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)]
ns = {}
exec(compile(setup_ast, filename="setup.py", mode="exec"), ns)
assert ns['package_dir'] == {'': 'src'}
assert re.search('\'py_modules\': \'module_src\'', to_str(setup)) is not None
builder.build()
sdist = fixtures_dir / 'source_file' / 'dist' / 'module-src-0.1.tar.gz'
assert sdist.exists()
tar = tarfile.open(str(sdist), 'r')
assert 'module-src-0.1/src/module_src.py' in tar.getnames()
def test_with_src_module_dir():
poetry = Poetry.create(project('source_package'))
builder = SdistBuilder(poetry, NullVenv(), NullIO())
# Check setup.py
setup = builder.build_setup()
setup_ast = ast.parse(setup)
setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)]
ns = {}
exec(compile(setup_ast, filename="setup.py", mode="exec"), ns)
assert ns['package_dir'] == {'': 'src'}
assert ns['packages'] == [
'package_src',
]
builder.build()
sdist = fixtures_dir / 'source_package' / 'dist' / 'package-src-0.1.tar.gz'
assert sdist.exists()
tar = tarfile.open(str(sdist), 'r')
assert 'package-src-0.1/src/package_src/__init__.py' in tar.getnames()
assert 'package-src-0.1/src/package_src/module.py' in tar.getnames()
import pytest
import shutil
import zipfile
from poetry.io import NullIO
from poetry.masonry.builders import WheelBuilder
......@@ -34,6 +35,10 @@ def test_wheel_module():
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert 'module1.py' in z.namelist()
def test_wheel_package():
module_path = fixtures_dir / 'complete'
......@@ -43,6 +48,10 @@ def test_wheel_package():
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert 'my_package/sub_pkg1/__init__.py' in z.namelist()
def test_wheel_prerelease():
module_path = fixtures_dir / 'prerelease'
......@@ -51,3 +60,30 @@ def test_wheel_prerelease():
whl = module_path / 'dist' / 'prerelease-0.1b1-py2.py3-none-any.whl'
assert whl.exists()
def test_wheel_package_src():
module_path = fixtures_dir / 'source_package'
WheelBuilder.make(Poetry.create(str(module_path)), NullVenv(), NullIO())
whl = module_path / 'dist' / 'package_src-0.1-py2.py3-none-any.whl'
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert 'package_src/__init__.py' in z.namelist()
assert 'package_src/module.py' in z.namelist()
def test_wheel_module_src():
module_path = fixtures_dir / 'source_file'
WheelBuilder.make(Poetry.create(str(module_path)), NullVenv(), NullIO())
whl = module_path / 'dist' / 'module_src-0.1-py2.py3-none-any.whl'
assert whl.exists()
z = zipfile.ZipFile(str(whl))
assert 'module_src.py' in z.namelist()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment