From 7cb54bf606c3322b6d3474de04674a7ea60ff7c8 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Sun, 18 Aug 2024 11:07:30 +0100 Subject: [PATCH] fix sync then check command --- README.md | 6 ++---- docs/index.md | 7 +++++-- docs/quickstart.md | 4 ++++ docs/style-modules.md | 4 ++++ docs/style-packages.md | 4 ++++ una/check.py | 13 +++++++++++++ una/cli.py | 37 ++++++++++++------------------------- una/config.py | 4 ++++ una/files.py | 2 +- una/internal_deps.py | 4 ++++ una/sync.py | 6 ------ 11 files changed, 53 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 9df41ae..4a086fa 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ # una -**Warning: this is pre-alpha and probably doesn't work at all. You'll probably just get frustrated if you even try to use it.** - una is a tool to make Python monorepos with Rye easier. It is a CLI tool and a Hatch plugin that does the following things: 1. Enable builds of individual apps or projects within a monorepo. 2. Ensure that internal and external dependencies are correctly specified. @@ -20,8 +18,8 @@ Within this context, we use the following words frequently: ## Examples You can see examples for each of the two styles here: -- [carderne/una-example-packages](https://github.com/carderne/una-example-packages) -- [carderne/una-example-modules](https://github.com/carderne/una-example-modules) +- [una-example-packages](https://github.com/carderne/una-example-packages) +- [una-example-modules](https://github.com/carderne/una-example-modules) ## Quickstart This will give you a quick view of how this all works. diff --git a/docs/index.md b/docs/index.md index 5f4f7f9..4061498 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,5 @@ # una -**Warning: this is pre-alpha and probably doesn't work at all. You'll probably just get frustrated if you even try to use it.** - una is a tool to make Python monorepos with Rye easier. It is a CLI tool and a Hatch plugin that does the following things: 1. Enable builds of individual apps or projects within a monorepo. @@ -21,3 +19,8 @@ Within this context, we use the following words frequently: - `lib`: a module or package that will be imported but not run. - `app`: a module or package that will be run but never imported. - `project`: a package with no code but only dependencies (only used in the `modules` style) + +## Examples +You can see examples for each of the two styles here: +- [una-example-packages](https://github.com/carderne/una-example-packages) +- [una-example-modules](https://github.com/carderne/una-example-modules) diff --git a/docs/quickstart.md b/docs/quickstart.md index 49be654..ae0c6db 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -66,3 +66,7 @@ And run it: docker build --tag unarepo-printer . docker run --rm -it unarepo-printer python -c 'from unarepo.printer import run; run()' ``` + +## Example +After running through the steps above, the result will be similar to the Projects style example repo: +- [una-example-packages](https://github.com/carderne/una-example-packages) diff --git a/docs/style-modules.md b/docs/style-modules.md index fc13947..4e51fb7 100644 --- a/docs/style-modules.md +++ b/docs/style-modules.md @@ -1,4 +1,8 @@ # Style: Modules + +You can see an example of the Modules style here: +- [una-example-modules](https://github.com/carderne/una-example-modules) + This approach is inspired by [Polylith](https://davidvujic.github.io/python-polylith-docs/). You don't use a Rye workspace (and indeed this approach will work with just Hatch), and there's only a single `pyproject.toml`. diff --git a/docs/style-packages.md b/docs/style-packages.md index 727a822..7a55094 100644 --- a/docs/style-packages.md +++ b/docs/style-packages.md @@ -1,4 +1,8 @@ # Style: Packages + +You can see an example of the Modules style here: +- [una-example-packages](https://github.com/carderne/una-example-packages) + In this setup, we use Rye's built-in workspace support. The structure will look something like this: ```bash . diff --git a/una/check.py b/una/check.py index 8e13eca..aee6f59 100644 --- a/una/check.py +++ b/una/check.py @@ -39,6 +39,19 @@ def with_ext_deps_from_lock_file(project: Proj) -> Proj: return project +def enriched_with_lock_file_data(project: Proj, is_verbose: bool) -> Proj: + try: + return with_ext_deps_from_lock_file(project) + except ValueError as e: + if is_verbose: + print(f"{project.name}: {e}") + return project + + +def enriched_with_lock_files_data(projects: list[Proj], is_verbose: bool) -> list[Proj]: + return [enriched_with_lock_file_data(p, is_verbose) for p in projects] + + def collect_known_aliases(project: Proj, options: Options) -> set[str]: return distributions.known_aliases_and_sub_dependencies(project.ext_deps, options.alias) diff --git a/una/cli.py b/una/cli.py index ad90bdb..116a662 100644 --- a/una/cli.py +++ b/una/cli.py @@ -5,7 +5,7 @@ from typer import Argument, Exit, Option, Typer from una import check, config, defaults, differ, external_deps, files, internal_deps, sync -from una.types import Options, Proj, Style +from una.types import Options, Style app = Typer(name="una", no_args_is_help=True, add_completion=False) create = Typer(no_args_is_help=True) @@ -20,24 +20,6 @@ option_quiet = Option(help="Do not output any messages.") # type: ignore[reportAny] -def filtered_projects_data(projects: list[Proj]) -> list[Proj]: - dir_path = Path.cwd().name - return [p for p in projects if dir_path in p.path.as_posix()] - - -def enriched_with_lock_file_data(project: Proj, is_verbose: bool) -> Proj: - try: - return check.with_ext_deps_from_lock_file(project) - except ValueError as e: - if is_verbose: - print(f"{project.name}: {e}") - return project - - -def enriched_with_lock_files_data(projects: list[Proj], is_verbose: bool) -> list[Proj]: - return [enriched_with_lock_file_data(p, is_verbose) for p in projects] - - @app.command("info") def info_command( alias: Annotated[str, option_alias] = "", @@ -53,8 +35,8 @@ def info_command( # Deps on external libraries projects = internal_deps.get_projects_data(root, ns) - filtered_projects = filtered_projects_data(projects) - merged_projects_data = enriched_with_lock_files_data(filtered_projects, False) + filtered_projects = internal_deps.filtered_projects_data(projects) + merged_projects_data = check.enriched_with_lock_files_data(filtered_projects, False) results = external_deps.external_deps_from_all(root, ns, merged_projects_data, options) external_deps.print_libs_in_projects(filtered_projects, options) if not all(results): @@ -80,19 +62,24 @@ def sync_command( """Update pyproject.toml with missing int_deps.""" root = config.get_workspace_root() ns = config.get_ns(root) - projects = internal_deps.get_projects_data(root, ns) options = Options( quiet=quiet, verbose=verbose, alias=str.split(alias, ",") if alias else [], ) - filtered_projects = filtered_projects_data(projects) - enriched_projects = enriched_with_lock_files_data(filtered_projects, verbose) if not check_only: + projects = internal_deps.get_projects_data(root, ns) + filtered_projects = internal_deps.filtered_projects_data(projects) + enriched_projects = check.enriched_with_lock_files_data(filtered_projects, verbose) for p in filtered_projects: sync.sync_project_int_deps(root, ns, p, options) + config.clear_conf_cache() + # reload projects so any changes made by sync are picked up + projects = internal_deps.get_projects_data(root, ns) + filtered_projects = internal_deps.filtered_projects_data(projects) + enriched_projects = check.enriched_with_lock_files_data(filtered_projects, verbose) results = {check.check_int_ext_deps(root, ns, p, options) for p in enriched_projects} if not all(results): raise Exit(code=1) @@ -141,7 +128,7 @@ def project_command( console = Console(theme=defaults.una_theme) if style == Style.packages: console.print("You can't create projects in a Packages style workspace") - exit(1) + raise Exit(code=1) files.create_project(root, name, "", from_app) console.print("Success!") diff --git a/una/config.py b/una/config.py index 5afb10c..093e80b 100644 --- a/una/config.py +++ b/una/config.py @@ -18,6 +18,10 @@ def _load_conf(path: Path) -> Conf: return load_conf_from_str(f.read()) +def clear_conf_cache() -> None: + _load_conf.cache_clear() + + def load_conf(path: Path) -> Conf: fullpath = (path / defaults.pyproj).resolve() return _load_conf(fullpath) diff --git a/una/files.py b/una/files.py index 9619c48..cfba738 100644 --- a/una/files.py +++ b/una/files.py @@ -148,7 +148,7 @@ def create_package(path: Path, name: str, top_dir: str, content: str, dependenci create_file( app_dir, defaults.pyproj, - content, + pyproj_content, ) diff --git a/una/internal_deps.py b/una/internal_deps.py index bc158ca..fdda917 100644 --- a/una/internal_deps.py +++ b/una/internal_deps.py @@ -148,6 +148,10 @@ def get_projects_data(root: Path, ns: str) -> list[Proj]: return get_int_deps_in_projects(root, lib_names, app_names, ns) +def filtered_projects_data(projects: list[Proj]) -> list[Proj]: + return [p for p in projects if Path.cwd().name in p.path.as_posix()] + + def int_dep_status_projects(int_dep: str, int_deps: list[str], for_info: bool) -> str: emoji = ":heavy_check_mark:" if for_info else ":gear:" status = emoji if int_dep in int_deps else "-" diff --git a/una/sync.py b/una/sync.py index a531bce..b9233dc 100644 --- a/una/sync.py +++ b/una/sync.py @@ -54,16 +54,10 @@ def print_summary(diff: Diff) -> None: name = diff.name apps_pkgs = diff.apps libs_pkgs = diff.libs - anything_to_sync = apps_pkgs or libs_pkgs - emoji = ":point_right:" if anything_to_sync else ":heavy_check_mark:" - printable_name = f"[proj]{name}[/]" - console.print(f"{emoji} {printable_name}") for b in apps_pkgs: console.print(f"adding [app]{b}[/] app to [proj]{name}[/]") for c in libs_pkgs: console.print(f"adding [lib]{c}[/] lib to [proj]{name}[/]") - if anything_to_sync: - console.print("") def to_package(ns: str, name: str, int_dep_root: str, style: Style) -> Include: