diff --git a/README.md b/README.md index a1d0f29..d78a119 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Manifestoo is a command line tool that provides the following features: * listing addons, * listing direct and transitive dependencies of selected addons, +* listing direct and transitive co-dependencies of selected addons, * listing core Odoo CE and EE addons, * listing external dependencies, * listing missing dependencies, @@ -84,6 +85,14 @@ $ manifestoo -d /tmp/myaddons list-depends --separator=, crm,mail ``` +The `list-codepends` command shows the transitive co-dependencies. +It is handy to know which modules are impacted by changes in selected modules. + +```console +$ manifestoo --addons-path /tmp/myaddons --select a list-codepends --separator=, +b,c +``` + You can explore the dependency tree of module `a` like this: ```console diff --git a/src/manifestoo/commands/list_codepends.py b/src/manifestoo/commands/list_codepends.py new file mode 100644 index 0000000..4438cb5 --- /dev/null +++ b/src/manifestoo/commands/list_codepends.py @@ -0,0 +1,29 @@ +from typing import Iterable, Set + +from ..addons_selection import AddonsSelection +from ..addons_set import AddonsSet + + +def list_codepends_command( + addons_selection: AddonsSelection, + addons_set: AddonsSet, + transitive: bool = True, + include_selected: bool = True, +) -> Iterable[str]: + result: Set[str] = set(addons_selection) if include_selected else set() + codeps = direct_codependencies(addons_selection, addons_set, result) + result |= codeps + while transitive and codeps: + codeps = direct_codependencies(codeps, addons_set, result) + result |= codeps + return result if include_selected else result - addons_selection + + +def direct_codependencies( + root_addons: Set[str], addons_set: AddonsSet, accumulator: Set[str] +) -> Set[str]: + return { + a + for a in addons_set + if set(addons_set[a].manifest.depends) & root_addons and a not in accumulator + } diff --git a/src/manifestoo/main.py b/src/manifestoo/main.py index 76b985e..eace382 100644 --- a/src/manifestoo/main.py +++ b/src/manifestoo/main.py @@ -7,6 +7,7 @@ from .commands.check_dev_status import check_dev_status_command from .commands.check_licenses import check_licenses_command from .commands.list import list_command +from .commands.list_codepends import list_codepends_command from .commands.list_depends import list_depends_command from .commands.list_external_dependencies import list_external_dependencies_command from .commands.tree import tree_command @@ -253,6 +254,36 @@ def list_depends( ) +@app.command() +def list_codepends( + ctx: typer.Context, + separator: Optional[str] = typer.Option( + None, + help="Separator character to use (by default, print one item per line).", + ), + transitive: bool = typer.Option( + True, + "--transitive", + help="Print all transitive co-dependencies.", + ), + include_selected: bool = typer.Option( + True, + "--include-selected", + help="Print the selected addons along with their co-dependencies" + "(the set of addons that depends on the set of selected addons).", + ), +) -> None: + """Print the co-dependencies of selected addons.""" + main_options: MainOptions = ctx.obj + result = list_codepends_command( + main_options.addons_selection, + main_options.addons_set, + transitive, + include_selected, + ) + print_list(result, separator or main_options.separator or "\n") + + @app.command() def list_external_dependencies( ctx: typer.Context,