Commit 85f922df by Arun Babu Neelicattu

layouts: improve supported layout creation

- remove unnecessary template duplication
- stop generating default test case (this is out of scope for poetry)
- stop generating content for package `__init__.py`
- simplify inheritance to only require base directory overrides
- remove "StandardLayout" (replaced with `Layout`)
- support handling namespace package names given in the form "a.b.c"
- specify include packages by default (be explicit)
parent ecec2fc5
......@@ -2,10 +2,9 @@ from typing import Type
from .layout import Layout
from .src import SrcLayout
from .standard import StandardLayout
_LAYOUTS = {"src": SrcLayout, "standard": StandardLayout}
_LAYOUTS = {"src": SrcLayout, "standard": Layout}
def layout(name: str) -> Type[Layout]:
......
from pathlib import Path
from typing import TYPE_CHECKING
from typing import Dict
from typing import Optional
from tomlkit import dumps
from tomlkit import inline_table
from tomlkit import loads
from tomlkit import table
from poetry.utils.helpers import canonicalize_name
from poetry.utils.helpers import module_name
if TYPE_CHECKING:
from pathlib import Path
from tomlkit.items import InlineTable
from poetry.core.pyproject.toml import PyProjectTOML
TESTS_DEFAULT = """from {package_name} import __version__
def test_version():
assert __version__ == '{version}'
"""
POETRY_DEFAULT = """\
[tool.poetry]
......@@ -28,26 +24,15 @@ name = ""
version = ""
description = ""
authors = []
[tool.poetry.dependencies]
[tool.poetry.dev-dependencies]
"""
POETRY_WITH_LICENSE = """\
[tool.poetry]
name = ""
version = ""
description = ""
authors = []
license = ""
packages = []
[tool.poetry.dependencies]
[tool.poetry.dev-dependencies]
"""
BUILD_SYSTEM_MIN_VERSION = "1.0.0"
BUILD_SYSTEM_MIN_VERSION: Optional[str] = None
BUILD_SYSTEM_MAX_VERSION: Optional[str] = None
......@@ -59,13 +44,16 @@ class Layout:
description: str = "",
readme_format: str = "md",
author: Optional[str] = None,
license: Optional[str] = None,
license: Optional[str] = None, # noqa
python: str = "*",
dependencies: Optional[Dict[str, str]] = None,
dev_dependencies: Optional[Dict[str, str]] = None,
):
self._project = project
self._package_name = module_name(project)
self._project = canonicalize_name(project).replace(".", "-")
self._package_path_relative = Path(
*(module_name(part) for part in canonicalize_name(project).split("."))
)
self._package_name = ".".join(self._package_path_relative.parts)
self._version = version
self._description = description
self._readme_format = readme_format
......@@ -79,6 +67,30 @@ class Layout:
self._author = author
@property
def basedir(self) -> Path:
return Path()
@property
def package_path(self) -> Path:
return self.basedir / self._package_path_relative
def get_package_include(self) -> Optional["InlineTable"]:
package = inline_table()
include = self._package_path_relative.parts[0]
package.append("include", include)
if self.basedir != Path():
package.append("from", self.basedir.as_posix())
else:
if include == self._project:
# package include and package name are the same,
# packages table is redundant here.
return None
return package
def create(self, path: "Path", with_tests: bool = True) -> None:
path.mkdir(parents=True, exist_ok=True)
......@@ -94,17 +106,25 @@ class Layout:
self, original: Optional["PyProjectTOML"] = None
) -> str:
template = POETRY_DEFAULT
if self._license:
template = POETRY_WITH_LICENSE
content = loads(template)
poetry_content = content["tool"]["poetry"]
poetry_content["name"] = self._project
poetry_content["version"] = self._version
poetry_content["description"] = self._description
poetry_content["authors"].append(self._author)
if self._license:
poetry_content["license"] = self._license
else:
poetry_content.remove("license")
packages = self.get_package_include()
if packages:
poetry_content["packages"].append(packages)
else:
poetry_content.remove("packages")
poetry_content["dependencies"]["python"] = self._python
......@@ -116,9 +136,14 @@ class Layout:
# Add build system
build_system = table()
build_system_version = ">=" + BUILD_SYSTEM_MIN_VERSION
build_system_version = ""
if BUILD_SYSTEM_MIN_VERSION is not None:
build_system_version = ">=" + BUILD_SYSTEM_MIN_VERSION
if BUILD_SYSTEM_MAX_VERSION is not None:
build_system_version += ",<" + BUILD_SYSTEM_MAX_VERSION
if build_system_version:
build_system_version += ","
build_system_version += "<" + BUILD_SYSTEM_MAX_VERSION
build_system.add("requires", ["poetry-core" + build_system_version])
build_system.add("build-backend", "poetry.core.masonry.api")
......@@ -133,7 +158,11 @@ class Layout:
return content
def _create_default(self, path: "Path", src: bool = True) -> None:
raise NotImplementedError()
package_path = path / self.package_path
package_path.mkdir(parents=True)
package_init = package_path / "__init__.py"
package_init.touch()
def _create_readme(self, path: "Path") -> None:
if self._readme_format == "rst":
......@@ -143,20 +172,13 @@ class Layout:
readme_file.touch()
def _create_tests(self, path: "Path") -> None:
@staticmethod
def _create_tests(path: "Path") -> None:
tests = path / "tests"
tests_init = tests / "__init__.py"
tests_default = tests / f"test_{self._package_name}.py"
tests.mkdir()
tests_init.touch(exist_ok=False)
with tests_default.open("w", encoding="utf-8") as f:
f.write(
TESTS_DEFAULT.format(
package_name=self._package_name, version=self._version
)
)
tests_init = tests / "__init__.py"
tests_init.touch(exist_ok=False)
def _write_poetry(self, path: "Path") -> None:
content = self.generate_poetry_content()
......
from typing import TYPE_CHECKING
from pathlib import Path
from .layout import Layout
if TYPE_CHECKING:
from pathlib import Path
DEFAULT = """__version__ = '{version}'
"""
class SrcLayout(Layout):
def _create_default(self, path: "Path") -> None:
package_path = path / "src" / self._package_name
package_init = package_path / "__init__.py"
package_path.mkdir(parents=True)
with package_init.open("w", encoding="utf-8") as f:
f.write(DEFAULT.format(version=self._version))
@property
def basedir(self) -> "Path":
return Path("src")
from typing import TYPE_CHECKING
from .layout import Layout
if TYPE_CHECKING:
from pathlib import Path
DEFAULT = """__version__ = '{version}'
"""
class StandardLayout(Layout):
def _create_default(self, path: "Path") -> None:
package_path = path / self._package_name
package_init = package_path / "__init__.py"
package_path.mkdir()
with package_init.open("w", encoding="utf-8") as f:
f.write(DEFAULT.format(version=self._version))
......@@ -66,6 +66,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -112,6 +113,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -144,6 +146,7 @@ name = "my-package"
version = "1.2.3"
description = ""
authors = ["Your Name <you@example.com>"]
packages = [{{include = "my_package"}}]
[tool.poetry.dependencies]
python = "^{python}"
......@@ -152,7 +155,6 @@ python = "^{python}"
""".format(
python=".".join(str(c) for c in sys.version_info[:2])
)
assert expected in tester.io.fetch_output()
......@@ -186,6 +188,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -228,6 +231,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -270,6 +274,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -315,6 +320,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -361,6 +367,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -406,6 +413,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......@@ -471,6 +479,7 @@ version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
packages = [{include = "my_package"}]
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
......
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