Skip to content
Merged
33 changes: 31 additions & 2 deletions components/polylith/commands/sync.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,42 @@
from pathlib import Path
from typing import Union

from polylith import sync
from polylith import info, project, sync


def is_project_without_bricks(project_data: dict) -> bool:
bases = project_data["bases"]
components = project_data["components"]

return not bases and not components


def choose_base(root: Path, ns: str, project_data: dict) -> Union[str, None]:
possible_bases = info.find_unused_bases(root, ns)

if not possible_bases:
return None

return project.interactive.choose_base_for_project(
root, ns, project_data["name"], possible_bases
)


def calculate_brick_diff(root: Path, ns: str, project_data: dict) -> dict:
if info.is_project(project_data) and is_project_without_bricks(project_data):
base = choose_base(root, ns, project_data)

if base:
return sync.calculate_needed_bricks(root, ns, project_data, base)

return sync.calculate_diff(root, ns, project_data)


def run(root: Path, ns: str, project_data: dict, options: dict):
is_quiet = options["quiet"]
is_verbose = options["verbose"]

diff = sync.calculate_diff(root, ns, project_data)
diff = calculate_brick_diff(root, ns, project_data)

sync.update_project(root, ns, diff)

Expand Down
14 changes: 4 additions & 10 deletions components/polylith/info/collect.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import difflib
from pathlib import Path
from typing import List, Set

from polylith.bricks import base, component
from polylith.info.report import is_project
from polylith.project import get_packages_for_projects, parse_package_paths


Expand Down Expand Up @@ -60,14 +60,8 @@ def find_unused_bases(root: Path, ns: str) -> Set[str]:
projects_data = get_projects_data(root, ns)

bases = get_bases(root, ns)
bases_in_projects = set().union(*[p["bases"] for p in projects_data])

return set(bases).difference(bases_in_projects)


def sort_bases_by_closest_match(bases: Set[str], name: str) -> List[str]:
closest = difflib.get_close_matches(name, bases, cutoff=0.3)
bases_per_project = [p["bases"] for p in projects_data if is_project(p)]
bases_in_projects = set().union(*bases_per_project)

rest = sorted([b for b in bases if b not in closest])

return closest + rest
return set(bases).difference(bases_in_projects)
56 changes: 38 additions & 18 deletions components/polylith/project/interactive.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import difflib
from pathlib import Path
from typing import List, Set
from typing import List, Set, Union

from polylith import configuration, info, repo, sync
from polylith.reporting import theme
Expand Down Expand Up @@ -44,28 +45,27 @@ def confirmation(diff: dict, project_name: str) -> None:
console.print(components_message)


def add_bricks_to_project(
root: Path,
ns: str,
project_name: str,
possible_bases: List[str],
) -> None:
projects_data = info.get_projects_data(root, ns)
project_data = next((p for p in projects_data if p["name"] == project_name), None)
def sort_bases_by_closest_match(bases: Set[str], name: str) -> List[str]:
closest = difflib.get_close_matches(name, bases, cutoff=0.3)

if not project_data:
return
rest = sorted([b for b in bases if b not in closest])

return closest + rest

message = f"[data]Project [proj]{project_name}[/] created.[/]"
console.print(Padding(message, (0, 0, 1, 0)))

first, *_ = possible_bases
def choose_base_for_project(
root: Path,
ns: str,
project_name: str,
possible_bases: Set[str],
) -> Union[str, None]:
first, *_ = sort_bases_by_closest_match(possible_bases, project_name)

if not Confirm.ask(
prompt=f"[data]Do you want to add bricks to the [proj]{project_name}[/] project?[/]",
console=console,
):
return
return None

question = "[data]What's the name of the Polylith [base]base[/] to add?[/]"

Expand All @@ -78,7 +78,18 @@ def add_bricks_to_project(
)

all_bases = info.get_bases(root, ns)
found_base = next((b for b in all_bases if str.lower(b) == str.lower(base)), None)

return next((b for b in all_bases if str.lower(b) == str.lower(base)), None)


def add_bricks_to_project(
root: Path,
ns: str,
project_data: dict,
possible_bases: Set[str],
) -> None:
project_name = project_data["name"]
found_base = choose_base_for_project(root, ns, project_name, possible_bases)

if not found_base:
confirmation({}, project_name)
Expand All @@ -95,9 +106,18 @@ def run(project_name: str) -> None:
root = repo.get_workspace_root(Path.cwd())
ns = configuration.get_namespace_from_config(root)

possible_bases = sorted(info.find_unused_bases(root, ns))
possible_bases = info.find_unused_bases(root, ns)

if not possible_bases:
return

add_bricks_to_project(root, ns, project_name, possible_bases)
projects_data = info.get_projects_data(root, ns)
project_data = next((p for p in projects_data if p["name"] == project_name), None)

if not project_data:
return

message = f"[data]Project [proj]{project_name}[/] created.[/]"
console.print(Padding(message, (0, 0, 1, 0)))

add_bricks_to_project(root, ns, project_data, possible_bases)
2 changes: 1 addition & 1 deletion projects/poetry_polylith_plugin/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "poetry-polylith-plugin"
version = "1.40.1"
version = "1.41.0"
description = "A Poetry plugin that adds tooling support for the Polylith Architecture"
authors = ["David Vujic"]
homepage = "https://davidvujic.github.io/python-polylith-docs/"
Expand Down
2 changes: 1 addition & 1 deletion projects/polylith_cli/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "polylith-cli"
version = "1.33.1"
version = "1.34.0"
description = "Python tooling support for the Polylith Architecture"
authors = ['David Vujic']
homepage = "https://davidvujic.github.io/python-polylith-docs/"
Expand Down