Repository: dbt-labs/dbt-core

Issue:
[CT-1947]  `--models` not working as expected in Click cli
Per #6774
@ChenyuLInx I figured it out! The tests fail for me locally, and then pass when I switch `-m` to `-s` in the arguments to `run_dbt` (https://github.com/dbt-labs/dbt-core/commit/83850f51214c0b61aaf4ecd0b0b4123acced392f)! It seems like this might be a genuine bug where we're not passing through `--models`/`-m` appropriately. That's important for backward compatibility.

**Desirable behavior:**
- For almost all commands, `--models` should be a pure alias for `--select` (and the two should be mutually exclusive)
- EXCEPTION: `dbt list` historically accepted _both_ `--select` and `--models`, with slightly different behavior, [which we've preserved for back compat](https://github.com/dbt-labs/dbt-core/blob/a8abc496323f741d3218d298d5d2bb118fa01017/core/dbt/task/list.py#L153-L177)

This issue was surfaced when running `dbt test `


Discussion:
Per BLG 1/30/23:
Good ideas:
- Create one aliased models/select param use it for all tasks except list.
- Re-name select and models MiltOption params to list_select and list_models.
- Add re-named params to `list` and make any adjustments needed in list task
- Hide `list_models` from help text .

Resolving patch:
diff --git a/core/dbt/cli/main.py b/core/dbt/cli/main.py
--- a/core/dbt/cli/main.py
+++ b/core/dbt/cli/main.py
@@ -172,7 +172,6 @@ def docs(ctx, **kwargs):
 @p.defer
 @p.exclude
 @p.favor_state
-@p.models
 @p.profile
 @p.profiles_dir
 @p.project_dir
@@ -237,7 +236,6 @@ def docs_serve(ctx, **kwargs):
 @p.exclude
 @p.favor_state
 @p.full_refresh
-@p.models
 @p.parse_only
 @p.profile
 @p.profiles_dir
@@ -347,7 +345,7 @@ def init(ctx, **kwargs):
 @p.profiles_dir
 @p.project_dir
 @p.resource_type
-@p.select
+@p.raw_select
 @p.selector
 @p.state
 @p.target
@@ -408,7 +406,6 @@ def parse(ctx, **kwargs):
 @p.exclude
 @p.fail_fast
 @p.full_refresh
-@p.models
 @p.profile
 @p.profiles_dir
 @p.project_dir
@@ -471,7 +468,6 @@ def run_operation(ctx, **kwargs):
 @click.pass_context
 @p.exclude
 @p.full_refresh
-@p.models
 @p.profile
 @p.profiles_dir
 @p.project_dir
@@ -508,7 +504,6 @@ def seed(ctx, **kwargs):
 @p.defer
 @p.exclude
 @p.favor_state
-@p.models
 @p.profile
 @p.profiles_dir
 @p.project_dir
@@ -547,7 +542,6 @@ def source(ctx, **kwargs):
 @source.command("freshness")
 @click.pass_context
 @p.exclude
-@p.models
 @p.output_path  # TODO: Is this ok to re-use?  We have three different output params, how much can we consolidate?
 @p.profile
 @p.profiles_dir
@@ -590,7 +584,6 @@ def freshness(ctx, **kwargs):
 @p.fail_fast
 @p.favor_state
 @p.indirect_selection
-@p.models
 @p.profile
 @p.profiles_dir
 @p.project_dir
diff --git a/core/dbt/cli/params.py b/core/dbt/cli/params.py
--- a/core/dbt/cli/params.py
+++ b/core/dbt/cli/params.py
@@ -142,16 +142,6 @@
     hidden=True,
 )
 
-models = click.option(
-    "--models",
-    "--model",
-    "-m",
-    envvar=None,
-    help="Specify the nodes to include.",
-    cls=MultiOption,
-    type=tuple,
-)
-
 output = click.option(
     "--output",
     envvar=None,
@@ -274,14 +264,22 @@
     default=(),
 )
 
-select = click.option(
-    "-s",
-    "--select",
-    envvar=None,
-    help="Specify the nodes to include.",
-    cls=MultiOption,
-    type=tuple,
-)
+model_decls = ("-m", "--models", "--model")
+select_decls = ("-s", "--select")
+select_attrs = {
+    "envvar": None,
+    "help": "Specify the nodes to include.",
+    "cls": MultiOption,
+    "type": tuple,
+}
+
+# `--select` and `--models` are analogous for most commands except `dbt list` for legacy reasons.
+# Most CLI arguments should use the combined `select` option that aliases `--models` to `--select`.
+# However, if you need to split out these separators (like `dbt ls`), use the `models` and `raw_select` options instead.
+# See https://github.com/dbt-labs/dbt-core/pull/6774#issuecomment-1408476095 for more info.
+models = click.option(*model_decls, **select_attrs)
+raw_select = click.option(*select_decls, **select_attrs)
+select = click.option(*select_decls, *model_decls, **select_attrs)
 
 selector = click.option(
     "--selector", envvar=None, help="The selector name to use, as defined in selectors.yml"


Test patch:
diff --git a/tests/unit/test_cli.py b/tests/unit/test_cli.py
--- a/tests/unit/test_cli.py
+++ b/tests/unit/test_cli.py
@@ -1,8 +1,5 @@
-import ast
-from inspect import getsource
-
 import click
-from dbt.cli import params
+
 from dbt.cli.main import cli
 
 
@@ -42,10 +39,3 @@ def run_test(command):
                     run_test(command)
 
         run_test(cli)
-
-    def test_params_are_alpha_sorted(self):
-        root_node = ast.parse(getsource(params))
-        param_var_names = [
-            node.targets[0].id for node in ast.walk(root_node) if isinstance(node, ast.Assign)
-        ]
-        assert param_var_names == sorted(param_var_names)