Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package molecule for openSUSE:Factory checked in at 2025-02-23 16:26:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/molecule (Old) and /work/SRC/openSUSE:Factory/.molecule.new.1873 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "molecule" Sun Feb 23 16:26:44 2025 rev:19 rq:1247903 version:25.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/molecule/molecule.changes 2025-01-29 16:11:33.826415001 +0100 +++ /work/SRC/openSUSE:Factory/.molecule.new.1873/molecule.changes 2025-02-23 16:27:05.879576404 +0100 @@ -1,0 +2,17 @@ +Wed Feb 19 13:14:53 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- update to 25.3.1: + * Bugfixes + - Fix molecule matrix with no scenario name. (#4400) @Qalthos + +------------------------------------------------------------------- +Wed Feb 19 06:06:10 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- update to 25.3.0: + * Enhancements + - Select and exclude multiple scenarios (#4388) @Qalthos + * Bugfixes + - Avoid errors when running with readonly virtualenvs (#4398) + @ssbarnea + +------------------------------------------------------------------- Old: ---- molecule-25.2.0.tar.gz New: ---- molecule-25.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ molecule.spec ++++++ --- /var/tmp/diff_new_pack.lp81VM/_old 2025-02-23 16:27:06.363596513 +0100 +++ /var/tmp/diff_new_pack.lp81VM/_new 2025-02-23 16:27:06.367596679 +0100 @@ -39,7 +39,7 @@ %bcond_without test Name: molecule -Version: 25.2.0 +Version: 25.3.1 Release: 0 Summary: Aids in the development and testing of Ansible roles License: MIT @@ -68,7 +68,7 @@ # https://github.com/ansible/molecule/blob/main/.config/requirements.in BuildRequires: %{ansible_python}-base >= 3.9 BuildRequires: ansible-core >= 2.12.10 -BuildRequires: %{ansible_python}-ansible-compat >= 25.1.0 +BuildRequires: %{ansible_python}-ansible-compat >= 25.1.4 BuildRequires: %{ansible_python}-click >= 8.0 BuildRequires: %{ansible_python}-click-help-colors >= 0.9 BuildRequires: %{ansible_python}-enrich >= 1.2.7 @@ -82,7 +82,7 @@ BuildRequires: fdupes # https://github.com/ansible/molecule/blob/main/.config/requirements.in Requires: %{ansible_python}-base >= 3.9 -Requires: %{ansible_python}-ansible-compat >= 25.1.0 +Requires: %{ansible_python}-ansible-compat >= 25.1.4 Requires: ansible-core >= 2.12.10 Requires: %{ansible_python}-click >= 8.0 Requires: %{ansible_python}-click-help-colors >= 0.9 ++++++ molecule-25.2.0.tar.gz -> molecule-25.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/.config/constraints.txt new/molecule-25.3.1/.config/constraints.txt --- old/molecule-25.2.0/.config/constraints.txt 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/.config/constraints.txt 2025-02-19 13:54:07.000000000 +0100 @@ -1,28 +1,27 @@ # This file was autogenerated by uv via the following command: # tox run -e deps ansi2html==1.9.2 # via molecule (pyproject.toml) -ansible-compat==25.1.0 # via ansible-lint, molecule (pyproject.toml) -ansible-lint==25.1.0 # via molecule (pyproject.toml) +ansible-compat==25.1.4 # via ansible-lint, molecule (pyproject.toml) +ansible-lint==25.1.3 # via molecule (pyproject.toml) astroid==3.3.8 # via pylint attrs==25.1.0 # via jsonschema, referencing -babel==2.16.0 # via mkdocs-material -beautifulsoup4==4.12.3 # via linkchecker, mkdocs-htmlproofer-plugin -black==24.10.0 # via ansible-lint, molecule (pyproject.toml) +babel==2.17.0 # via mkdocs-material +beautifulsoup4==4.13.3 # via linkchecker, mkdocs-htmlproofer-plugin +black==25.1.0 # via ansible-lint, molecule (pyproject.toml) bracex==2.5.post1 # via wcmatch -build==1.2.2.post1 # via pip-tools cachetools==5.5.1 # via tox cairocffi==1.7.1 # via cairosvg cairosvg==2.7.1 # via mkdocs-ansible -certifi==2024.12.14 # via requests +certifi==2025.1.31 # via requests cffi==1.17.1 # via cairocffi, cryptography cfgv==3.4.0 # via pre-commit chardet==5.2.0 # via tox charset-normalizer==3.4.1 # via requests -click==8.1.8 # via black, click-help-colors, mkdocs, mkdocstrings, pip-tools, pydoclint, molecule (pyproject.toml) +click==8.1.8 # via black, click-help-colors, mkdocs, pydoclint, molecule (pyproject.toml) click-help-colors==0.9.4 # via molecule (pyproject.toml) colorama==0.4.6 # via griffe, mkdocs-material, tox -coverage==7.6.10 # via molecule (pyproject.toml) -cryptography==44.0.0 # via ansible-core +coverage==7.6.12 # via molecule (pyproject.toml) +cryptography==44.0.1 # via ansible-core csscompressor==0.9.5 # via mkdocs-minify-plugin cssselect2==0.7.0 # via cairosvg defusedxml==0.7.1 # via cairosvg @@ -36,14 +35,14 @@ execnet==2.1.1 # via pytest-xdist filelock==3.17.0 # via ansible-lint, tox, virtualenv, molecule (pyproject.toml) ghp-import==2.1.0 # via mkdocs -griffe==1.5.5 # via mkdocstrings-python +griffe==1.5.7 # via mkdocstrings-python hjson==3.1.0 # via mkdocs-macros-plugin, super-collections htmlmin2==0.1.13 # via mkdocs-minify-plugin -identify==2.6.6 # via pre-commit +identify==2.6.7 # via pre-commit idna==3.10 # via requests importlib-metadata==8.6.1 # via ansible-lint iniconfig==2.0.0 # via pytest -isort==5.13.2 # via pylint +isort==6.0.0 # via pylint jinja2==3.1.5 # via ansible-core, mkdocs, mkdocs-macros-plugin, mkdocs-material, mkdocstrings, molecule (pyproject.toml) jsmin==3.0.1 # via mkdocs-minify-plugin jsonschema==4.23.0 # via ansible-compat, ansible-lint, molecule (pyproject.toml) @@ -58,58 +57,53 @@ mdurl==0.1.2 # via markdown-it-py mergedeep==1.3.4 # via mkdocs, mkdocs-get-deps mkdocs==1.6.1 # via mkdocs-ansible, mkdocs-autorefs, mkdocs-gen-files, mkdocs-htmlproofer-plugin, mkdocs-macros-plugin, mkdocs-material, mkdocs-minify-plugin, mkdocs-monorepo-plugin, mkdocstrings -mkdocs-ansible==24.12.0 # via molecule (pyproject.toml) -mkdocs-autorefs==1.3.0 # via mkdocstrings, mkdocstrings-python +mkdocs-ansible==25.2.0 # via molecule (pyproject.toml) +mkdocs-autorefs==1.3.1 # via mkdocstrings, mkdocstrings-python mkdocs-gen-files==0.5.0 # via mkdocs-ansible -mkdocs-get-deps==0.2.0 # via mkdocs +mkdocs-get-deps==0.2.0 # via mkdocs, mkdocstrings mkdocs-htmlproofer-plugin==1.3.0 # via mkdocs-ansible mkdocs-macros-plugin==1.3.7 # via mkdocs-ansible -mkdocs-material==9.5.50 # via mkdocs-ansible +mkdocs-material==9.6.4 # via mkdocs-ansible mkdocs-material-extensions==1.3.1 # via mkdocs-ansible, mkdocs-material mkdocs-minify-plugin==0.8.0 # via mkdocs-ansible mkdocs-monorepo-plugin==1.1.0 # via mkdocs-ansible -mkdocstrings==0.27.0 # via mkdocs-ansible, mkdocstrings-python -mkdocstrings-python==1.13.0 # via mkdocs-ansible -mypy==1.14.1 # via molecule (pyproject.toml) +mkdocstrings==0.28.1 # via mkdocs-ansible, mkdocstrings-python +mkdocstrings-python==1.16.0 # via mkdocs-ansible +mypy==1.15.0 # via molecule (pyproject.toml) mypy-extensions==1.0.0 # via black, mypy nodeenv==1.9.1 # via pre-commit -packaging==24.2 # via ansible-compat, ansible-core, ansible-lint, black, build, mkdocs, mkdocs-macros-plugin, pipdeptree, pyproject-api, pytest, tox, molecule (pyproject.toml) +packaging==24.2 # via ansible-compat, ansible-core, ansible-lint, black, mkdocs, mkdocs-macros-plugin, pyproject-api, pytest, tox, molecule (pyproject.toml) paginate==0.5.7 # via mkdocs-material pathspec==0.12.1 # via ansible-lint, black, mkdocs, mkdocs-macros-plugin, yamllint pexpect==4.9.0 # via molecule (pyproject.toml) pillow==11.1.0 # via cairosvg, mkdocs-ansible -pip-tools==7.4.1 # via molecule (pyproject.toml) -pipdeptree==2.24.0 # via molecule (pyproject.toml) -platformdirs==4.3.6 # via black, mkdocs-get-deps, mkdocstrings, pylint, tox, virtualenv +platformdirs==4.3.6 # via black, mkdocs-get-deps, pylint, tox, virtualenv pluggy==1.5.0 # via pytest, tox, molecule (pyproject.toml) pre-commit==4.1.0 # via molecule (pyproject.toml) ptyprocess==0.7.0 # via pexpect pycparser==2.22 # via cffi -pydoclint==0.6.0 # via molecule (pyproject.toml) +pydoclint==0.6.2 # via molecule (pyproject.toml) pygments==2.19.1 # via mkdocs-material, rich -pylint==3.3.3 # via molecule (pyproject.toml) -pymdown-extensions==10.14.1 # via markdown-exec, mkdocs-ansible, mkdocs-material, mkdocstrings +pylint==3.3.4 # via molecule (pyproject.toml) +pymdown-extensions==10.14.3 # via markdown-exec, mkdocs-ansible, mkdocs-material, mkdocstrings pyproject-api==1.9.0 # via tox -pyproject-hooks==1.2.0 # via build, pip-tools pytest==8.3.4 # via pytest-instafail, pytest-mock, pytest-plus, pytest-testinfra, pytest-xdist, molecule (pyproject.toml) pytest-instafail==0.5.0 # via molecule (pyproject.toml) pytest-mock==3.14.0 # via molecule (pyproject.toml) -pytest-plus==0.7.0 # via molecule (pyproject.toml) +pytest-plus==0.8.1 # via molecule (pyproject.toml) pytest-testinfra==10.1.1 # via molecule (pyproject.toml) pytest-xdist==3.6.1 # via molecule (pyproject.toml) python-dateutil==2.9.0.post0 # via ghp-import, mkdocs-macros-plugin python-slugify==8.0.4 # via mkdocs-monorepo-plugin pyyaml==6.0.2 # via ansible-compat, ansible-core, ansible-lint, mkdocs, mkdocs-get-deps, mkdocs-macros-plugin, pre-commit, pymdown-extensions, pyyaml-env-tag, yamllint, molecule (pyproject.toml) pyyaml-env-tag==0.1 # via mkdocs -referencing==0.36.2 # via jsonschema, jsonschema-specifications, types-jsonschema +referencing==0.36.2 # via ansible-lint, jsonschema, jsonschema-specifications, types-jsonschema regex==2024.11.6 # via mkdocs-material requests==2.32.3 # via docker, linkchecker, mkdocs-htmlproofer-plugin, mkdocs-material, molecule (pyproject.toml) rich==13.9.4 # via enrich, molecule (pyproject.toml) rpds-py==0.22.3 # via jsonschema, referencing ruamel-yaml==0.18.10 # via ansible-lint -ruamel-yaml-clib==0.2.12 # via ruamel-yaml -ruff==0.9.3 # via molecule (pyproject.toml) -setuptools==75.8.0 # via pip-tools +ruff==0.9.6 # via molecule (pyproject.toml) six==1.17.0 # via python-dateutil soupsieve==2.6 # via beautifulsoup4 subprocess-tee==0.4.2 # via ansible-compat, ansible-lint @@ -118,23 +112,22 @@ text-unidecode==1.3 # via python-slugify tinycss2==1.4.0 # via cairosvg, cssselect2 toml-sort==0.24.2 # via molecule (pyproject.toml) -tomli==2.2.1 # via black, build, coverage, mypy, pip-tools, pydoclint, pylint, pyproject-api, pytest, tox +tomli==2.2.1 # via black, coverage, mypy, pydoclint, pylint, pyproject-api, pytest, tox tomlkit==0.13.2 # via pylint, toml-sort tox==4.24.1 # via molecule (pyproject.toml) types-jsonschema==4.23.0.20241208 # via molecule (pyproject.toml) types-pexpect==4.9.0.20241208 # via molecule (pyproject.toml) types-pyyaml==6.0.12.20241230 # via molecule (pyproject.toml) urllib3==2.3.0 # via docker, requests -virtualenv==20.29.1 # via pre-commit, tox +virtualenv==20.29.2 # via pre-commit, tox watchdog==6.0.0 # via mkdocs wcmatch==10.0 # via ansible-lint, molecule (pyproject.toml) webencodings==0.5.1 # via cssselect2, tinycss2 -wheel==0.45.1 # via pip-tools yamllint==1.35.1 # via ansible-lint zipp==3.21.0 # via importlib-metadata # The following packages were excluded from the output: # ansible-core -# pip # resolvelib +# ruamel-yaml-clib # typing-extensions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/.config/requirements-docs.txt new/molecule-25.3.1/.config/requirements-docs.txt --- old/molecule-25.2.0/.config/requirements-docs.txt 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/.config/requirements-docs.txt 2025-02-19 13:54:07.000000000 +0100 @@ -1,3 +1,2 @@ mkdocs-ansible>=24.3.0 -pipdeptree>=2.4.0 linkchecker>=10.4.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/.config/requirements-test.txt new/molecule-25.3.1/.config/requirements-test.txt --- old/molecule-25.2.0/.config/requirements-test.txt 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/.config/requirements-test.txt 2025-02-19 13:54:07.000000000 +0100 @@ -6,7 +6,6 @@ filelock >= 3.9.0 mypy pexpect >= 4.9.0, < 5 -pip-tools pre-commit pydoclint pylint diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/.config/requirements.in new/molecule-25.3.1/.config/requirements.in --- old/molecule-25.2.0/.config/requirements.in 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/.config/requirements.in 2025-02-19 13:54:07.000000000 +0100 @@ -1,4 +1,4 @@ -ansible-compat >= 25.1.0 +ansible-compat >= 25.1.4 ansible-core >= 2.15.0 click >= 8.0, < 9 click-help-colors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/.pre-commit-config.yaml new/molecule-25.3.1/.pre-commit-config.yaml --- old/molecule-25.2.0/.pre-commit-config.yaml 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/.pre-commit-config.yaml 2025-02-19 13:54:07.000000000 +0100 @@ -47,7 +47,7 @@ - prettier-plugin-sort-json - repo: https://github.com/psf/black - rev: 24.10.0 + rev: 25.1.0 hooks: - id: black @@ -62,14 +62,14 @@ - id: tox-ini-fmt - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.3 + rev: v0.9.4 hooks: - id: ruff args: - --exit-non-zero-on-fix - repo: https://github.com/streetsidesoftware/cspell-cli - rev: v8.17.1 + rev: v8.17.2 hooks: - id: cspell name: Spell check with cspell @@ -83,13 +83,13 @@ pass_filenames: false - repo: https://github.com/pycqa/pylint.git - rev: v3.3.3 + rev: v3.3.4 hooks: - id: pylint args: - --output-format=colorized additional_dependencies: - - ansible-compat>=25.1.0 + - ansible-compat>=25.1.4 - click - click-help-colors - enrich>=1.2.7 @@ -105,7 +105,7 @@ hooks: - id: mypy additional_dependencies: - - ansible-compat>=25.1.0 + - ansible-compat>=25.1.4 - click - click-help-colors - enrich @@ -127,7 +127,8 @@ - id: pip-compile-upgrade # To run it execute: `pre-commit run pip-compile-upgrade --hook-stage manual` name: Upgrade constraints files and requirements - files: ^(pyproject\.toml|requirements\.txt)$ + files: ^(pyproject\.toml|.config/.*)$ + always_run: true language: python entry: python3 -m uv pip compile -q --all-extras --output-file=.config/constraints.txt pyproject.toml --upgrade pass_filenames: false @@ -145,7 +146,7 @@ additional_dependencies: - uv>=0.5.21 - repo: https://github.com/ansible/ansible-lint - rev: v25.1.0 + rev: v25.1.1 hooks: - id: ansible-lint stages: [manual] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/PKG-INFO new/molecule-25.3.1/PKG-INFO --- old/molecule-25.2.0/PKG-INFO 2025-01-28 12:32:22.918431000 +0100 +++ new/molecule-25.3.1/PKG-INFO 2025-02-19 13:54:17.259476000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.2 Name: molecule -Version: 25.2.0 +Version: 25.3.1 Summary: Molecule aids in the development and testing of Ansible roles Author-email: Ansible by Red Hat <i...@ansible.com> Maintainer-email: Ansible by Red Hat <i...@ansible.com> @@ -32,7 +32,7 @@ Requires-Python: >=3.10 Description-Content-Type: text/markdown License-File: LICENSE -Requires-Dist: ansible-compat>=25.1.0 +Requires-Dist: ansible-compat>=25.1.4 Requires-Dist: ansible-core>=2.15.0 Requires-Dist: click<9,>=8.0 Requires-Dist: click-help-colors @@ -46,7 +46,6 @@ Requires-Dist: wcmatch>=8.1.2 Provides-Extra: docs Requires-Dist: mkdocs-ansible>=24.3.0; extra == "docs" -Requires-Dist: pipdeptree>=2.4.0; extra == "docs" Requires-Dist: linkchecker>=10.4.0; extra == "docs" Provides-Extra: test Requires-Dist: ansi2html>=1.8.0; extra == "test" @@ -57,7 +56,6 @@ Requires-Dist: filelock>=3.9.0; extra == "test" Requires-Dist: mypy; extra == "test" Requires-Dist: pexpect<5,>=4.9.0; extra == "test" -Requires-Dist: pip-tools; extra == "test" Requires-Dist: pre-commit; extra == "test" Requires-Dist: pydoclint; extra == "test" Requires-Dist: pylint; extra == "test" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/pyproject.toml new/molecule-25.3.1/pyproject.toml --- old/molecule-25.2.0/pyproject.toml 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/pyproject.toml 2025-02-19 13:54:07.000000000 +0100 @@ -424,6 +424,7 @@ "ansible-core", "pip", "resolvelib", + "ruamel-yaml-clib", "typing_extensions", "uv" ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/_version.py new/molecule-25.3.1/src/molecule/_version.py --- old/molecule-25.2.0/src/molecule/_version.py 2025-01-28 12:32:22.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/_version.py 2025-02-19 13:54:16.000000000 +0100 @@ -12,5 +12,5 @@ __version_tuple__: VERSION_TUPLE version_tuple: VERSION_TUPLE -__version__ = version = '25.2.0' -__version_tuple__ = version_tuple = (25, 2, 0) +__version__ = version = '25.3.1' +__version_tuple__ = version_tuple = (25, 3, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/base.py new/molecule-25.3.1/src/molecule/command/base.py --- old/molecule-25.2.0/src/molecule/command/base.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/base.py 2025-02-19 13:54:07.000000000 +0100 @@ -99,10 +99,11 @@ def execute_cmdline_scenarios( - scenario_name: str | None, + scenario_names: list[str] | None, args: MoleculeArgs, command_args: CommandArgs, ansible_args: tuple[str, ...] = (), + excludes: list[str] | None = None, ) -> None: """Execute scenario sequences based on parsed command-line arguments. @@ -113,28 +114,33 @@ to generate the scenario(s) configuration. Args: - scenario_name: Name of scenario to run, or ``None`` to run all. + scenario_names: Name of scenarios to run, or ``None`` to run all. args: ``args`` dict from ``click`` command context command_args: dict of command arguments, including the target ansible_args: Optional tuple of arguments to pass to the `ansible-playbook` command + excludes: Name of scenarios to not run. Raises: SystemExit: If scenario exits prematurely. """ - glob_str = MOLECULE_GLOB - if scenario_name: - glob_str = glob_str.replace("*", scenario_name) - scenarios = molecule.scenarios.Scenarios( - get_configs(args, command_args, ansible_args, glob_str), - scenario_name, - ) + if excludes is None: + excludes = [] - if scenario_name and scenarios: - LOG.info( - "%s scenario test matrix: %s", - scenario_name, - ", ".join(scenarios.sequence(scenario_name)), - ) + configs: list[config.Config] = [] + if scenario_names is None: + configs = [ + config + for config in get_configs(args, command_args, ansible_args, MOLECULE_GLOB) + if config.scenario.name not in excludes + ] + else: + # filter out excludes + scenario_names = [name for name in scenario_names if name not in excludes] + for scenario_name in scenario_names: + glob_str = MOLECULE_GLOB.replace("*", scenario_name) + configs.extend(get_configs(args, command_args, ansible_args, glob_str)) + + scenarios = _generate_scenarios(scenario_names, configs) for scenario in scenarios: if scenario.config.config["prerun"]: @@ -171,6 +177,36 @@ raise +def _generate_scenarios( + scenario_names: list[str] | None, + configs: list[config.Config], +) -> molecule.scenarios.Scenarios: + """Generate Scenarios object from names and configs. + + Args: + scenario_names: Names of scenarios to include. + configs: List of Config objects to consider. + + Returns: + Combined Scenarios object. + """ + scenarios = molecule.scenarios.Scenarios( + configs, + scenario_names, + ) + + if scenario_names is not None: + for scenario_name in scenario_names: + if scenario_name != "*" and scenarios: + LOG.info( + "%s scenario test matrix: %s", + scenario_name, + ", ".join(scenarios.sequence(scenario_name)), + ) + + return scenarios + + def execute_subcommand( current_config: config.Config, subcommand_and_args: str, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/check.py new/molecule-25.3.1/src/molecule/command/check.py --- old/molecule-25.2.0/src/molecule/command/check.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/check.py 2025-02-19 13:54:07.000000000 +0100 @@ -57,8 +57,21 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Check all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) @click.option( "--parallel/--no-parallel", @@ -67,7 +80,9 @@ ) def check( # pragma: no cover ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 *, parallel: bool, ) -> None: @@ -76,13 +91,18 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. parallel: Whether the scenario(s) should be run in parallel. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"parallel": parallel, "subcommand": subcommand} + if __all: + scenario_name = None + if parallel: util.validate_parallel_cmd_args(command_args) - base.execute_cmdline_scenarios(scenario_name, args, command_args) + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/cleanup.py new/molecule-25.3.1/src/molecule/command/cleanup.py --- old/molecule-25.2.0/src/molecule/command/cleanup.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/cleanup.py 2025-02-19 13:54:07.000000000 +0100 @@ -59,12 +59,27 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Cleanup all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) def cleanup( ctx: click.Context, - scenario_name: str = "default", + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Use the provisioner to cleanup any changes. @@ -73,9 +88,14 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/converge.py new/molecule-25.3.1/src/molecule/command/converge.py --- old/molecule-25.2.0/src/molecule/command/converge.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/converge.py 2025-02-19 13:54:07.000000000 +0100 @@ -55,13 +55,28 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Converge all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) @click.argument("ansible_args", nargs=-1, type=click.UNPROCESSED) def converge( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ansible_args: tuple[str], ) -> None: # pragma: no cover """Use the provisioner to configure instances (dependency, create, prepare converge). @@ -69,10 +84,15 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. ansible_args: Arguments to forward to Ansible. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args, ansible_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, ansible_args, exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/create.py new/molecule-25.3.1/src/molecule/command/create.py --- old/molecule-25.2.0/src/molecule/command/create.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/create.py 2025-02-19 13:54:07.000000000 +0100 @@ -65,8 +65,9 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", ) @click.option( "--driver-name", @@ -74,20 +75,39 @@ type=click.Choice([str(s) for s in drivers()]), help=f"Name of driver to use. ({DEFAULT_DRIVER})", ) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Start all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", +) def create( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], driver_name: str, + __all: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Use the provisioner to start the instances. Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. driver_name: Name of the Molecule driver to use. + __all: Whether molecule should target scenario_name or all scenarios. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand, "driver_name": driver_name} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/dependency.py new/molecule-25.3.1/src/molecule/command/dependency.py --- old/molecule-25.2.0/src/molecule/command/dependency.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/dependency.py 2025-02-19 13:54:07.000000000 +0100 @@ -54,21 +54,41 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Target all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) def dependency( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Manage the role's dependencies. Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/destroy.py new/molecule-25.3.1/src/molecule/command/destroy.py --- old/molecule-25.2.0/src/molecule/command/destroy.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/destroy.py 2025-02-19 13:54:07.000000000 +0100 @@ -65,8 +65,9 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", ) @click.option( "--driver-name", @@ -81,13 +82,20 @@ help="Destroy all scenarios. Default is False.", ) @click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", +) +@click.option( "--parallel/--no-parallel", default=False, help="Enable or disable parallel mode. Default is disabled.", ) def destroy( ctx: click.Context, - scenario_name: str | None, + scenario_name: list[str] | None, + exclude: list[str], driver_name: str, __all: bool, # noqa: FBT001 parallel: bool, # noqa: FBT001 @@ -97,6 +105,7 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. driver_name: Molecule driver to use. __all: Whether molecule should target scenario_name or all scenarios. parallel: Whether the scenario(s) should be run in parallel mode. @@ -115,4 +124,4 @@ if parallel: util.validate_parallel_cmd_args(command_args) - base.execute_cmdline_scenarios(scenario_name, args, command_args) + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/idempotence.py new/molecule-25.3.1/src/molecule/command/idempotence.py --- old/molecule-25.2.0/src/molecule/command/idempotence.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/idempotence.py 2025-02-19 13:54:07.000000000 +0100 @@ -121,13 +121,28 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Target all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) @click.argument("ansible_args", nargs=-1, type=click.UNPROCESSED) def idempotence( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ansible_args: tuple[str, ...], ) -> None: # pragma: no cover """Use the provisioner to configure the instances. @@ -137,10 +152,15 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. ansible_args: Arguments to forward to Ansible. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args, ansible_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, ansible_args, exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/list.py new/molecule-25.3.1/src/molecule/command/list.py --- old/molecule-25.2.0/src/molecule/command/list.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/list.py 2025-02-19 13:54:07.000000000 +0100 @@ -91,7 +91,7 @@ statuses = [] s = scenarios.Scenarios( base.get_configs(args, command_args, glob_str=MOLECULE_GLOB), - scenario_name, + None if scenario_name is None else [scenario_name], ) for scenario in s: statuses.extend(base.execute_subcommand(scenario.config, subcommand)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/login.py new/molecule-25.3.1/src/molecule/command/login.py --- old/molecule-25.2.0/src/molecule/command/login.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/login.py 2025-02-19 13:54:07.000000000 +0100 @@ -146,6 +146,6 @@ subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand, "host": host} - s = scenarios.Scenarios(base.get_configs(args, command_args), scenario_name) + s = scenarios.Scenarios(base.get_configs(args, command_args), [scenario_name]) for scenario in s.all: base.execute_subcommand(scenario.config, subcommand) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/matrix.py new/molecule-25.3.1/src/molecule/command/matrix.py --- old/molecule-25.2.0/src/molecule/command/matrix.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/matrix.py 2025-02-19 13:54:07.000000000 +0100 @@ -94,5 +94,6 @@ args: MoleculeArgs = ctx.obj.get("args") command_args: CommandArgs = {"subcommand": subcommand} - s = scenarios.Scenarios(base.get_configs(args, command_args), scenario_name) + scenario_names = [] if scenario_name is None else [scenario_name] + s = scenarios.Scenarios(base.get_configs(args, command_args), scenario_names) s.print_matrix() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/prepare.py new/molecule-25.3.1/src/molecule/command/prepare.py --- old/molecule-25.2.0/src/molecule/command/prepare.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/prepare.py 2025-02-19 13:54:07.000000000 +0100 @@ -117,8 +117,9 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", ) @click.option( "--driver-name", @@ -127,6 +128,18 @@ help=f"Name of driver to use. ({DEFAULT_DRIVER})", ) @click.option( + "--all/--no-all", + "__all", + default=False, + help="Prepare all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", +) +@click.option( "--force/--no-force", "-f", default=False, @@ -134,8 +147,10 @@ ) def prepare( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], driver_name: str, + __all: bool, # noqa: FBT001 force: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Use the provisioner to prepare the instances into a particular starting state. @@ -143,7 +158,9 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. driver_name: Name of the Molecule driver to use. + __all: Whether molecule should target scenario_name or all scenarios. force: Whether to use force mode. """ args: MoleculeArgs = ctx.obj.get("args") @@ -154,4 +171,7 @@ "force": force, } - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/reset.py new/molecule-25.3.1/src/molecule/command/reset.py --- old/molecule-25.2.0/src/molecule/command/reset.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/reset.py 2025-02-19 13:54:07.000000000 +0100 @@ -59,6 +59,6 @@ subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + base.execute_cmdline_scenarios([scenario_name], args, command_args) for driver in drivers().values(): driver.reset() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/side_effect.py new/molecule-25.3.1/src/molecule/command/side_effect.py --- old/molecule-25.2.0/src/molecule/command/side_effect.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/side_effect.py 2025-02-19 13:54:07.000000000 +0100 @@ -62,21 +62,41 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Target all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) def side_effect( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Use the provisioner to perform side-effects to the instances. Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. """ args = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/syntax.py new/molecule-25.3.1/src/molecule/command/syntax.py --- old/molecule-25.2.0/src/molecule/command/syntax.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/syntax.py 2025-02-19 13:54:07.000000000 +0100 @@ -54,21 +54,41 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Syntax check all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) def syntax( ctx: click.Context, - scenario_name: str, + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Use the provisioner to syntax check the role. Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/test.py new/molecule-25.3.1/src/molecule/command/test.py --- old/molecule-25.2.0/src/molecule/command/test.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/test.py 2025-02-19 13:54:07.000000000 +0100 @@ -60,8 +60,9 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", ) @click.option( "--platform-name", @@ -82,6 +83,12 @@ help="Test all scenarios. Default is False.", ) @click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", +) +@click.option( "--destroy", type=click.Choice(["always", "never"]), default="always", @@ -95,7 +102,8 @@ @click.argument("ansible_args", nargs=-1, type=click.UNPROCESSED) def test( # noqa: PLR0913 ctx: click.Context, - scenario_name: str | None, + scenario_name: list[str] | None, + exclude: list[str], driver_name: str, __all: bool, # noqa: FBT001 destroy: Literal["always", "never"], @@ -108,6 +116,7 @@ Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. driver_name: Name of the driver to use. __all: Whether molecule should target scenario_name or all scenarios. destroy: The destroy strategy to use. @@ -131,4 +140,4 @@ if parallel: util.validate_parallel_cmd_args(command_args) - base.execute_cmdline_scenarios(scenario_name, args, command_args, ansible_args) + base.execute_cmdline_scenarios(scenario_name, args, command_args, ansible_args, exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/command/verify.py new/molecule-25.3.1/src/molecule/command/verify.py --- old/molecule-25.2.0/src/molecule/command/verify.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/command/verify.py 2025-02-19 13:54:07.000000000 +0100 @@ -53,21 +53,41 @@ @click.option( "--scenario-name", "-s", - default=base.MOLECULE_DEFAULT_SCENARIO_NAME, - help=f"Name of the scenario to target. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", + multiple=True, + default=[base.MOLECULE_DEFAULT_SCENARIO_NAME], + help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})", +) +@click.option( + "--all/--no-all", + "__all", + default=False, + help="Verify all scenarios. Default is False.", +) +@click.option( + "--exclude", + "-e", + multiple=True, + help="Name of the scenario to exclude from running. May be specified multiple times.", ) def verify( ctx: click.Context, - scenario_name: str = "default", + scenario_name: list[str] | None, + exclude: list[str], + __all: bool, # noqa: FBT001 ) -> None: # pragma: no cover """Run automated tests against instances. Args: ctx: Click context object holding commandline arguments. scenario_name: Name of the scenario to target. + exclude: Name of the scenarios to avoid targeting. + __all: Whether molecule should target scenario_name or all scenarios. """ args: MoleculeArgs = ctx.obj.get("args") subcommand = base._get_subcommand(__name__) # noqa: SLF001 command_args: CommandArgs = {"subcommand": subcommand} - base.execute_cmdline_scenarios(scenario_name, args, command_args) + if __all: + scenario_name = None + + base.execute_cmdline_scenarios(scenario_name, args, command_args, excludes=exclude) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule/scenarios.py new/molecule-25.3.1/src/molecule/scenarios.py --- old/molecule-25.2.0/src/molecule/scenarios.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/src/molecule/scenarios.py 2025-02-19 13:54:07.000000000 +0100 @@ -41,16 +41,16 @@ def __init__( self, configs: list[Config], - scenario_name: str | None = None, + scenario_names: list[str] | None = None, ) -> None: """Initialize a new scenarios class and returns None. Args: configs: Molecule config instances. - scenario_name: The name of the scenario. + scenario_names: The names of the scenarios. """ self._configs = configs - self._scenario_name = scenario_name + self._scenario_names = [] if scenario_names is None else scenario_names self._scenarios = self.all def __iter__(self) -> Scenarios: @@ -81,7 +81,7 @@ Returns: All Scenario objects. """ - if self._scenario_name: + if self._scenario_names: scenarios = self._filter_for_scenario() self._verify() @@ -123,8 +123,12 @@ def _verify(self) -> None: """Verify the specified scenario was found.""" scenario_names = [c.scenario.name for c in self._configs] - if self._scenario_name not in scenario_names: - msg = f"Scenario '{self._scenario_name}' not found. Exiting." + if missing_names := sorted(set(self._scenario_names).difference(scenario_names)): + scenario = "Scenario" + if len(missing_names) > 1: + scenario += "s" + missing = ", ".join(missing_names) + msg = f"{scenario} '{missing}' not found. Exiting." util.sysexit_with_message(msg) def _filter_for_scenario(self) -> list[Scenario]: @@ -133,7 +137,7 @@ Returns: list """ - return [c.scenario for c in self._configs if c.scenario.name == self._scenario_name] + return [c.scenario for c in self._configs if c.scenario.name in self._scenario_names] def _get_matrix(self) -> dict[str, dict[str, list[str]]]: """Build a matrix of scenarios and step sequences. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule.egg-info/PKG-INFO new/molecule-25.3.1/src/molecule.egg-info/PKG-INFO --- old/molecule-25.2.0/src/molecule.egg-info/PKG-INFO 2025-01-28 12:32:22.000000000 +0100 +++ new/molecule-25.3.1/src/molecule.egg-info/PKG-INFO 2025-02-19 13:54:17.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.2 Name: molecule -Version: 25.2.0 +Version: 25.3.1 Summary: Molecule aids in the development and testing of Ansible roles Author-email: Ansible by Red Hat <i...@ansible.com> Maintainer-email: Ansible by Red Hat <i...@ansible.com> @@ -32,7 +32,7 @@ Requires-Python: >=3.10 Description-Content-Type: text/markdown License-File: LICENSE -Requires-Dist: ansible-compat>=25.1.0 +Requires-Dist: ansible-compat>=25.1.4 Requires-Dist: ansible-core>=2.15.0 Requires-Dist: click<9,>=8.0 Requires-Dist: click-help-colors @@ -46,7 +46,6 @@ Requires-Dist: wcmatch>=8.1.2 Provides-Extra: docs Requires-Dist: mkdocs-ansible>=24.3.0; extra == "docs" -Requires-Dist: pipdeptree>=2.4.0; extra == "docs" Requires-Dist: linkchecker>=10.4.0; extra == "docs" Provides-Extra: test Requires-Dist: ansi2html>=1.8.0; extra == "test" @@ -57,7 +56,6 @@ Requires-Dist: filelock>=3.9.0; extra == "test" Requires-Dist: mypy; extra == "test" Requires-Dist: pexpect<5,>=4.9.0; extra == "test" -Requires-Dist: pip-tools; extra == "test" Requires-Dist: pre-commit; extra == "test" Requires-Dist: pydoclint; extra == "test" Requires-Dist: pylint; extra == "test" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule.egg-info/SOURCES.txt new/molecule-25.3.1/src/molecule.egg-info/SOURCES.txt --- old/molecule-25.2.0/src/molecule.egg-info/SOURCES.txt 2025-01-28 12:32:22.000000000 +0100 +++ new/molecule-25.3.1/src/molecule.egg-info/SOURCES.txt 2025-02-19 13:54:17.000000000 +0100 @@ -308,6 +308,5 @@ tests/unit/verifier/test_testinfra.py tools/get-version.sh tools/opts.txt -tools/smoketest.sh tools/test-setup.sh tools/update-version.sh \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/src/molecule.egg-info/requires.txt new/molecule-25.3.1/src/molecule.egg-info/requires.txt --- old/molecule-25.2.0/src/molecule.egg-info/requires.txt 2025-01-28 12:32:22.000000000 +0100 +++ new/molecule-25.3.1/src/molecule.egg-info/requires.txt 2025-02-19 13:54:17.000000000 +0100 @@ -1,4 +1,4 @@ -ansible-compat>=25.1.0 +ansible-compat>=25.1.4 ansible-core>=2.15.0 click<9,>=8.0 click-help-colors @@ -13,7 +13,6 @@ [docs] mkdocs-ansible>=24.3.0 -pipdeptree>=2.4.0 linkchecker>=10.4.0 [test] @@ -25,7 +24,6 @@ filelock>=3.9.0 mypy pexpect<5,>=4.9.0 -pip-tools pre-commit pydoclint pylint diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/tests/unit/command/test_base.py new/molecule-25.3.1/tests/unit/command/test_base.py --- old/molecule-25.2.0/tests/unit/command/test_base.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/tests/unit/command/test_base.py 2025-02-19 13:54:07.000000000 +0100 @@ -252,7 +252,7 @@ patched_execute_subcommand: Mocked execute_subcommand function. patched_prune: Mocked prune function. """ - scenario_name = "default" + scenario_name = ["default"] args: MoleculeArgs = {} command_args: CommandArgs = {"destroy": "always", "subcommand": "test"} @@ -273,7 +273,7 @@ patched_prune: Mocked prune function. patched_execute_subcommand: Mocked execute_subcommand function. """ - scenario_name = "default" + scenario_name = ["default"] args: MoleculeArgs = {} command_args: CommandArgs = {"destroy": "never", "subcommand": "test"} @@ -301,7 +301,7 @@ patched_execute_subcommand: Mocked execute_subcommand function. patched_sysexit: Mocked util.sysexit function. """ - scenario_name = "default" + scenario_name = ["default"] args: MoleculeArgs = {} command_args: CommandArgs = {"destroy": "always", "subcommand": "test"} patched_execute_scenario.side_effect = SystemExit() @@ -335,7 +335,7 @@ patched_prune: Mocked prune function. patched_sysexit: Mocked util.sysexit function. """ - scenario_name = "default" + scenario_name = ["default"] args: MoleculeArgs = {} command_args: CommandArgs = {"destroy": "never", "subcommand": "test"} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/tests/unit/model/v2/test_provisioner_section.py new/molecule-25.3.1/tests/unit/model/v2/test_provisioner_section.py --- old/molecule-25.2.0/tests/unit/model/v2/test_provisioner_section.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/tests/unit/model/v2/test_provisioner_section.py 2025-02-19 13:54:07.000000000 +0100 @@ -89,7 +89,7 @@ @pytest.mark.parametrize( "config", - [("_model_provisioner_allows_ansible_section_data")], # noqa: PT007 + ["_model_provisioner_allows_ansible_section_data"], # noqa: PT007 indirect=True, ) def test_provisioner_allows_name(config): # type: ignore[no-untyped-def] # noqa: ANN201, D103 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/tests/unit/test_scenarios.py new/molecule-25.3.1/tests/unit/test_scenarios.py --- old/molecule-25.2.0/tests/unit/test_scenarios.py 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/tests/unit/test_scenarios.py 2025-02-19 13:54:07.000000000 +0100 @@ -49,7 +49,7 @@ def test_scenario_name_private_member( # noqa: D103 _instance: scenarios.Scenarios, # noqa: PT019 ) -> None: - assert _instance._scenario_name is None + assert _instance._scenario_names == [] def test_scenarios_private_member( # noqa: D103 @@ -80,7 +80,7 @@ def test_all_filters_on_scenario_name_property( # noqa: D103 _instance: scenarios.Scenarios, # noqa: PT019 ) -> None: - _instance._scenario_name = "default" + _instance._scenario_names = ["default"] assert len(_instance.all) == 1 @@ -126,7 +126,7 @@ def test_verify_does_not_raise_when_found( # noqa: D103 _instance: scenarios.Scenarios, # noqa: PT019 ) -> None: - _instance._scenario_name = "default" + _instance._scenario_names = ["default"] _instance._verify() @@ -135,7 +135,7 @@ _instance: scenarios.Scenarios, # noqa: PT019 caplog: pytest.LogCaptureFixture, ) -> None: - _instance._scenario_name = "invalid" + _instance._scenario_names = ["invalid"] with pytest.raises(SystemExit) as e: _instance._verify() @@ -145,15 +145,29 @@ assert msg in caplog.text +def test_verify_raises_when_multiple_scenarios_not_found( # noqa: D103 + _instance: scenarios.Scenarios, # noqa: PT019 + caplog: pytest.LogCaptureFixture, +) -> None: + _instance._scenario_names = ["invalid", "also invalid"] + with pytest.raises(SystemExit) as e: + _instance._verify() + + assert e.value.code == 1 + + msg = "Scenarios 'also invalid, invalid' not found. Exiting." + assert msg in caplog.text + + def test_filter_for_scenario( # noqa: D103 _instance: scenarios.Scenarios, # noqa: PT019 ) -> None: - _instance._scenario_name = "default" + _instance._scenario_names = ["default"] result = _instance._filter_for_scenario() assert len(result) == 1 assert result[0].name == "default" - _instance._scenario_name = "invalid" + _instance._scenario_names = ["invalid"] result = _instance._filter_for_scenario() assert result == [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/tools/smoketest.sh new/molecule-25.3.1/tools/smoketest.sh --- old/molecule-25.2.0/tools/smoketest.sh 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/tools/smoketest.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,11 +0,0 @@ -#!/bin/bash - -ANSIBLE=$(pipdeptree --reverse -p ansible) - -if [ -z "$ANSIBLE" ]; then - echo "Ansible dependency not detected." -else - echo "FATAL: Detected unexpected dependency on Ansible package" - echo "$ANSIBLE" - exit 2 -fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/molecule-25.2.0/tox.ini new/molecule-25.3.1/tox.ini --- old/molecule-25.2.0/tox.ini 2025-01-28 12:32:12.000000000 +0100 +++ new/molecule-25.3.1/tox.ini 2025-02-19 13:54:07.000000000 +0100 @@ -1,7 +1,7 @@ [tox] requires = tox>=4.23.2 - tox-uv>=1.20.1 + tox-uv>=1.20.2 env_list = py deps @@ -48,10 +48,7 @@ coverage xml --data-file={env:COVERAGE_COMBINED} -o {envdir}/coverage.xml --fail-under=0 coverage lcov --data-file={env:COVERAGE_COMBINED} -o {toxinidir}/.cache/.coverage/lcov.info --fail-under=0 coverage report --data-file={env:COVERAGE_COMBINED} -commands_post = - git clean -f -d allowlist_externals = - git rm sh @@ -64,8 +61,8 @@ extras = commands_pre = commands = - -pre-commit run --all-files --show-diff-on-failure --hook-stage manual deps - -pre-commit autoupdate + pre-commit run --all-files --show-diff-on-failure --hook-stage manual pip-compile-upgrade + pre-commit autoupdate git diff --exit-code env_dir = {toxworkdir}/lint @@ -119,14 +116,13 @@ pip_pre = true deps = molecule-plugins[azure,containers,docker,ec2,gce,podman,vagrant]>=23 - pipdeptree>=2 tox-ansible>=1.5.1 + uv extras = test commands_pre = commands = - pip check - pipdeptree --reverse -e pip,pbr,six,setuptools,toml,urllib3 + uv pip check + uv pip tree --invert molecule --version molecule drivers - sh -c ./tools/smoketest.sh