Skip to content

Commit ad57142

Browse files
authoredMar 17, 2025··
Pull out common action options (#4411)
This lets us add or modify scenario-level options on all actions simultaneously.
1 parent a7c7ce8 commit ad57142

13 files changed

+43
-229
lines changed
 

‎src/molecule/command/base.py

+30
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,36 @@ def click_command_ex(name: str | None = None) -> ClickCommand:
400400
)
401401

402402

403+
def click_command_options(func: Callable[..., None]) -> Callable[..., None]:
404+
"""Provide a baseline set of reusable options for molecule actions.
405+
406+
Args:
407+
func: Function to be decorated.
408+
409+
Returns:
410+
Function with click options for scenario_name, exclude, and all added.
411+
"""
412+
func = click.option(
413+
"--exclude",
414+
"-e",
415+
multiple=True,
416+
help="Name of the scenario to exclude from targeting. May be specified multiple times. Can exclude scenarios already included with scenario-name or all.",
417+
)(func)
418+
func = click.option(
419+
"--all/--no-all",
420+
"__all",
421+
default=False,
422+
help="Target all scenarios. Overrides scenario-name. Default is disabled.",
423+
)(func)
424+
return click.option(
425+
"--scenario-name",
426+
"-s",
427+
multiple=True,
428+
default=[MOLECULE_DEFAULT_SCENARIO_NAME],
429+
help=f"Name of the scenario to target. May be specified multiple times. ({MOLECULE_DEFAULT_SCENARIO_NAME})",
430+
)(func)
431+
432+
403433
def result_callback(
404434
*args: object, # noqa: ARG001
405435
**kwargs: object, # noqa: ARG001

‎src/molecule/command/check.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,7 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
5454

5555
@base.click_command_ex()
5656
@click.pass_context
57-
@click.option(
58-
"--scenario-name",
59-
"-s",
60-
multiple=True,
61-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
62-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
63-
)
64-
@click.option(
65-
"--all/--no-all",
66-
"__all",
67-
default=False,
68-
help="Check all scenarios. Default is False.",
69-
)
70-
@click.option(
71-
"--exclude",
72-
"-e",
73-
multiple=True,
74-
help="Name of the scenario to exclude from running. May be specified multiple times.",
75-
)
57+
@base.click_command_options
7658
@click.option(
7759
"--parallel/--no-parallel",
7860
default=MOLECULE_PARALLEL,

‎src/molecule/command/cleanup.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -56,25 +56,7 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
5656

5757
@base.click_command_ex()
5858
@click.pass_context
59-
@click.option(
60-
"--scenario-name",
61-
"-s",
62-
multiple=True,
63-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
64-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
65-
)
66-
@click.option(
67-
"--all/--no-all",
68-
"__all",
69-
default=False,
70-
help="Cleanup all scenarios. Default is False.",
71-
)
72-
@click.option(
73-
"--exclude",
74-
"-e",
75-
multiple=True,
76-
help="Name of the scenario to exclude from running. May be specified multiple times.",
77-
)
59+
@base.click_command_options
7860
def cleanup(
7961
ctx: click.Context,
8062
scenario_name: list[str] | None,

‎src/molecule/command/converge.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -52,25 +52,7 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
5252

5353
@base.click_command_ex()
5454
@click.pass_context
55-
@click.option(
56-
"--scenario-name",
57-
"-s",
58-
multiple=True,
59-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
60-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
61-
)
62-
@click.option(
63-
"--all/--no-all",
64-
"__all",
65-
default=False,
66-
help="Converge all scenarios. Default is False.",
67-
)
68-
@click.option(
69-
"--exclude",
70-
"-e",
71-
multiple=True,
72-
help="Name of the scenario to exclude from running. May be specified multiple times.",
73-
)
55+
@base.click_command_options
7456
@click.argument("ansible_args", nargs=-1, type=click.UNPROCESSED)
7557
def converge(
7658
ctx: click.Context,

‎src/molecule/command/create.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -62,31 +62,13 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
6262

6363
@base.click_command_ex()
6464
@click.pass_context
65-
@click.option(
66-
"--scenario-name",
67-
"-s",
68-
multiple=True,
69-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
70-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
71-
)
65+
@base.click_command_options
7266
@click.option(
7367
"--driver-name",
7468
"-d",
7569
type=click.Choice([str(s) for s in drivers()]),
7670
help=f"Name of driver to use. ({DEFAULT_DRIVER})",
7771
)
78-
@click.option(
79-
"--all/--no-all",
80-
"__all",
81-
default=False,
82-
help="Start all scenarios. Default is False.",
83-
)
84-
@click.option(
85-
"--exclude",
86-
"-e",
87-
multiple=True,
88-
help="Name of the scenario to exclude from running. May be specified multiple times.",
89-
)
9072
def create(
9173
ctx: click.Context,
9274
scenario_name: list[str] | None,

‎src/molecule/command/dependency.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,7 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
5151

5252
@base.click_command_ex()
5353
@click.pass_context
54-
@click.option(
55-
"--scenario-name",
56-
"-s",
57-
multiple=True,
58-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
59-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
60-
)
61-
@click.option(
62-
"--all/--no-all",
63-
"__all",
64-
default=False,
65-
help="Target all scenarios. Default is False.",
66-
)
67-
@click.option(
68-
"--exclude",
69-
"-e",
70-
multiple=True,
71-
help="Name of the scenario to exclude from running. May be specified multiple times.",
72-
)
54+
@base.click_command_options
7355
def dependency(
7456
ctx: click.Context,
7557
scenario_name: list[str] | None,

‎src/molecule/command/destroy.py

+2-20
Original file line numberDiff line numberDiff line change
@@ -62,34 +62,16 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
6262

6363
@base.click_command_ex()
6464
@click.pass_context
65-
@click.option(
66-
"--scenario-name",
67-
"-s",
68-
multiple=True,
69-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
70-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
71-
)
65+
@base.click_command_options
7266
@click.option(
7367
"--driver-name",
7468
"-d",
7569
type=click.Choice([str(s) for s in drivers()]),
7670
help=f"Name of driver to use. ({DEFAULT_DRIVER})",
7771
)
78-
@click.option(
79-
"--all/--no-all",
80-
"__all",
81-
default=MOLECULE_PARALLEL,
82-
help="Destroy all scenarios. Default is False.",
83-
)
84-
@click.option(
85-
"--exclude",
86-
"-e",
87-
multiple=True,
88-
help="Name of the scenario to exclude from running. May be specified multiple times.",
89-
)
9072
@click.option(
9173
"--parallel/--no-parallel",
92-
default=False,
74+
default=MOLECULE_PARALLEL,
9375
help="Enable or disable parallel mode. Default is disabled.",
9476
)
9577
def destroy(

‎src/molecule/command/idempotence.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -118,25 +118,7 @@ def _non_idempotent_tasks(self, output: str) -> list[str]:
118118

119119
@base.click_command_ex()
120120
@click.pass_context
121-
@click.option(
122-
"--scenario-name",
123-
"-s",
124-
multiple=True,
125-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
126-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
127-
)
128-
@click.option(
129-
"--all/--no-all",
130-
"__all",
131-
default=False,
132-
help="Target all scenarios. Default is False.",
133-
)
134-
@click.option(
135-
"--exclude",
136-
"-e",
137-
multiple=True,
138-
help="Name of the scenario to exclude from running. May be specified multiple times.",
139-
)
121+
@base.click_command_options
140122
@click.argument("ansible_args", nargs=-1, type=click.UNPROCESSED)
141123
def idempotence(
142124
ctx: click.Context,

‎src/molecule/command/prepare.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -114,31 +114,13 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
114114

115115
@base.click_command_ex()
116116
@click.pass_context
117-
@click.option(
118-
"--scenario-name",
119-
"-s",
120-
multiple=True,
121-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
122-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
123-
)
117+
@base.click_command_options
124118
@click.option(
125119
"--driver-name",
126120
"-d",
127121
type=click.Choice([str(s) for s in drivers()]),
128122
help=f"Name of driver to use. ({DEFAULT_DRIVER})",
129123
)
130-
@click.option(
131-
"--all/--no-all",
132-
"__all",
133-
default=False,
134-
help="Prepare all scenarios. Default is False.",
135-
)
136-
@click.option(
137-
"--exclude",
138-
"-e",
139-
multiple=True,
140-
help="Name of the scenario to exclude from running. May be specified multiple times.",
141-
)
142124
@click.option(
143125
"--force/--no-force",
144126
"-f",

‎src/molecule/command/side_effect.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,7 @@ def execute(self, action_args: list[str] | None = None) -> None:
5959

6060
@base.click_command_ex()
6161
@click.pass_context
62-
@click.option(
63-
"--scenario-name",
64-
"-s",
65-
multiple=True,
66-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
67-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
68-
)
69-
@click.option(
70-
"--all/--no-all",
71-
"__all",
72-
default=False,
73-
help="Target all scenarios. Default is False.",
74-
)
75-
@click.option(
76-
"--exclude",
77-
"-e",
78-
multiple=True,
79-
help="Name of the scenario to exclude from running. May be specified multiple times.",
80-
)
62+
@base.click_command_options
8163
def side_effect(
8264
ctx: click.Context,
8365
scenario_name: list[str] | None,

‎src/molecule/command/syntax.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,7 @@ def execute(self, action_args: list[str] | None = None) -> None: # noqa: ARG002
5151

5252
@base.click_command_ex()
5353
@click.pass_context
54-
@click.option(
55-
"--scenario-name",
56-
"-s",
57-
multiple=True,
58-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
59-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
60-
)
61-
@click.option(
62-
"--all/--no-all",
63-
"__all",
64-
default=False,
65-
help="Syntax check all scenarios. Default is False.",
66-
)
67-
@click.option(
68-
"--exclude",
69-
"-e",
70-
multiple=True,
71-
help="Name of the scenario to exclude from running. May be specified multiple times.",
72-
)
54+
@base.click_command_options
7355
def syntax(
7456
ctx: click.Context,
7557
scenario_name: list[str] | None,

‎src/molecule/command/test.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,7 @@ def execute(self, action_args: list[str] | None = None) -> None:
5757

5858
@base.click_command_ex()
5959
@click.pass_context
60-
@click.option(
61-
"--scenario-name",
62-
"-s",
63-
multiple=True,
64-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
65-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
66-
)
60+
@base.click_command_options
6761
@click.option(
6862
"--platform-name",
6963
"-p",
@@ -76,18 +70,6 @@ def execute(self, action_args: list[str] | None = None) -> None:
7670
type=click.Choice([str(s) for s in drivers()]),
7771
help=f"Name of driver to use. ({DEFAULT_DRIVER})",
7872
)
79-
@click.option(
80-
"--all/--no-all",
81-
"__all",
82-
default=False,
83-
help="Test all scenarios. Default is False.",
84-
)
85-
@click.option(
86-
"--exclude",
87-
"-e",
88-
multiple=True,
89-
help="Name of the scenario to exclude from running. May be specified multiple times.",
90-
)
9173
@click.option(
9274
"--destroy",
9375
type=click.Choice(["always", "never"]),

‎src/molecule/command/verify.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,7 @@ def execute(self, action_args: list[str] | None = None) -> None:
5050

5151
@base.click_command_ex()
5252
@click.pass_context
53-
@click.option(
54-
"--scenario-name",
55-
"-s",
56-
multiple=True,
57-
default=[base.MOLECULE_DEFAULT_SCENARIO_NAME],
58-
help=f"Name of the scenario to target. May be specified multiple times. ({base.MOLECULE_DEFAULT_SCENARIO_NAME})",
59-
)
60-
@click.option(
61-
"--all/--no-all",
62-
"__all",
63-
default=False,
64-
help="Verify all scenarios. Default is False.",
65-
)
66-
@click.option(
67-
"--exclude",
68-
"-e",
69-
multiple=True,
70-
help="Name of the scenario to exclude from running. May be specified multiple times.",
71-
)
53+
@base.click_command_options
7254
def verify(
7355
ctx: click.Context,
7456
scenario_name: list[str] | None,

0 commit comments

Comments
 (0)