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