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

Reply via email to