Skip to content

Commit

Permalink
feat: use configured exclude patterns (#63)
Browse files Browse the repository at this point in the history
* feat: read exclude patterns

* fix: rename existing unit test

* feat: add exclude patterns when copying project

* bump version to 1.6.0

* refactor: use same exclude patterns for copying project and packages
  • Loading branch information
DavidVujic authored Jul 20, 2024
1 parent 1804fcc commit da1bab7
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 28 deletions.
23 changes: 23 additions & 0 deletions poetry_multiproject_plugin/components/project/copying.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import shutil
from pathlib import Path
from typing import Set

defaults_to_ignore = {
"*.pyc",
"__pycache__",
".venv",
".mypy_cache",
"node_modules",
".git",
}


def copy_tree(source: Path, destination: Path, exclude_patterns: Set[str]) -> str:
to_ignore = defaults_to_ignore.union(exclude_patterns)

return shutil.copytree(
source.as_posix(),
destination.as_posix(),
ignore=shutil.ignore_patterns(*to_ignore),
dirs_exist_ok=True,
)
12 changes: 3 additions & 9 deletions poetry_multiproject_plugin/components/project/packages.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import shutil
from pathlib import Path
from typing import Union

from poetry_multiproject_plugin.components.toml import read
from poetry_multiproject_plugin.components.toml.packages import packages_to_paths
from poetry_multiproject_plugin.components.project import copying


def is_relative_path(path: str) -> bool:
Expand All @@ -15,6 +15,7 @@ def copy_packages(
) -> None:
content = read.toml(project_file)
package_paths = packages_to_paths(content)
exclude_patterns = read.parse_exclude_patterns(content)

relative_package_paths = [p for p in package_paths if is_relative_path(p["from"])]

Expand All @@ -27,11 +28,4 @@ def copy_packages(

to_path = Path(destination / to)

shutil.copytree(
source,
to_path,
ignore=shutil.ignore_patterns(
"__pycache__", ".venv", ".mypy_cache", ".git"
),
dirs_exist_ok=True,
)
copying.copy_tree(source, to_path, exclude_patterns)
22 changes: 6 additions & 16 deletions poetry_multiproject_plugin/components/project/prepare.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import re
import shutil
from pathlib import Path
from typing import Union

from poetry_multiproject_plugin.components.project import copying
from poetry_multiproject_plugin.components.toml import read


Expand All @@ -19,21 +19,11 @@ def get_destination(project_file: Path, prefix: str) -> Path:


def copy_project(project_file: Path, destination: Path) -> Path:
source = project_file.parent.as_posix()

res = shutil.copytree(
source,
destination,
ignore=shutil.ignore_patterns(
"*.pyc",
"__pycache__",
".venv",
".mypy_cache",
"node_modules",
".git",
),
dirs_exist_ok=True,
)
source = project_file.parent

exclude_patterns = read.get_exclude_patterns(project_file)

res = copying.copy_tree(source, destination, exclude_patterns)

return Path(res)

Expand Down
25 changes: 24 additions & 1 deletion poetry_multiproject_plugin/components/toml/read.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import List
from typing import List, Set, Union, cast

from tomlkit.toml_document import TOMLDocument
from tomlkit.toml_file import TOMLFile
Expand All @@ -26,3 +26,26 @@ def project_name(path: Path) -> str:
data: dict = toml(path)

return data["tool"]["poetry"]["name"]


def parse_exclude_path(data: dict) -> Union[str, None]:
return None if data.get("format") else data.get("path")


def parse_exclude_pattern(data: Union[str, dict]) -> Union[str, None]:
return parse_exclude_path(data) if isinstance(data, dict) else data


def parse_exclude_patterns(toml: TOMLDocument) -> Set[str]:
data = cast(dict, toml)
config: list = data["tool"]["poetry"].get("exclude", [])

res = {parse_exclude_pattern(c) for c in config}

return {r for r in res if r}


def get_exclude_patterns(path: Path) -> Set[str]:
data = toml(path)

return parse_exclude_patterns(data)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "poetry-multiproject-plugin"
version = "1.5.1"
version = "1.6.0"
description = "A Poetry plugin that makes it possible to use relative package includes."
authors = ["David Vujic"]
license = "MIT"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@ def test_generate_project_file_with_unchanged_script_entry_point_when_ns_is_in_p
def test_generate_project_file_with_unchanged_script_entry_point_using_local_module():
data = generate_toml(pyproject_cli_with_local_modules, "xyz")

assert data["tool"]["poetry"]["scripts"] == {"my_cli": "my_local_module.console.app:run"}
assert data["tool"]["poetry"]["scripts"] == {
"my_cli": "my_local_module.console.app:run"
}
54 changes: 54 additions & 0 deletions test/components/toml/test_read.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import tomlkit

from poetry_multiproject_plugin.components.toml import read

pyproject = """\
[tool.poetry]
"""

pyproject_with_exclude_pattern = """\
[tool.poetry]
exclude = ["testing.json"]
"""

pyproject_with_complex_exclude_pattern = """\
[tool.poetry]
exclude = [{"path" = "testing.json"}]
"""

pyproject_with_complex_exclude_pattern_containing_format = """\
[tool.poetry]
exclude = [{"path" = "testing.json", "format" = "wheel"}]
"""


def test_read_exclude_pattern_should_return_empty_result():
data = tomlkit.loads(pyproject)

res = read.parse_exclude_patterns(data)

assert res == set()


def test_read_exclude_pattern_should_return_patterns_to_exclude():
data = tomlkit.loads(pyproject_with_exclude_pattern)

res = read.parse_exclude_patterns(data)

assert res == {"testing.json"}


def test_read_complex_exclude_pattern_should_return_patterns_to_exclude():
data = tomlkit.loads(pyproject_with_complex_exclude_pattern_containing_format)

res = read.parse_exclude_patterns(data)

assert res == set()


def test_read_complex_exclude_pattern_with_format_should_return_empty_result():
data = tomlkit.loads(pyproject_with_complex_exclude_pattern)

res = read.parse_exclude_patterns(data)

assert res == {"testing.json"}

0 comments on commit da1bab7

Please sign in to comment.