diff --git a/.changes/unreleased/Under the Hood-20230117-213729.yaml b/.changes/unreleased/Under the Hood-20230117-213729.yaml new file mode 100644 index 00000000000..8500a0a70b7 --- /dev/null +++ b/.changes/unreleased/Under the Hood-20230117-213729.yaml @@ -0,0 +1,6 @@ +kind: Under the Hood +body: dbt list working with click +time: 2023-01-17T21:37:29.91632-05:00 +custom: + Author: michelleark + Issue: "5549" diff --git a/core/dbt/cli/main.py b/core/dbt/cli/main.py index 4ebcc4722cd..80e0ed7e83c 100644 --- a/core/dbt/cli/main.py +++ b/core/dbt/cli/main.py @@ -15,15 +15,11 @@ from dbt.task.run import RunTask from dbt.task.test import TestTask from dbt.task.snapshot import SnapshotTask +from dbt.task.list import ListTask # CLI invocation def cli_runner(): - # Alias "list" to "ls" - ls = copy(cli.commands["list"]) - ls.hidden = True - cli.add_command(ls, "ls") - # Run the cli cli() @@ -155,6 +151,7 @@ def docs(ctx, **kwargs): @p.compile_docs @p.defer @p.exclude +@p.models @p.profile @p.profiles_dir @p.project_dir @@ -196,6 +193,7 @@ def docs_serve(ctx, **kwargs): @p.defer @p.exclude @p.full_refresh +@p.models @p.parse_only @p.profile @p.profiles_dir @@ -278,6 +276,7 @@ def init(ctx, **kwargs): @click.pass_context @p.exclude @p.indirect_selection +@p.models @p.output @p.output_keys @p.profile @@ -290,10 +289,21 @@ def init(ctx, **kwargs): @p.target @p.vars @requires.preflight +@requires.profile +@requires.project def list(ctx, **kwargs): """List the resources in your project""" - click.echo(f"`{inspect.stack()[0][3]}` called\n flags: {ctx.obj['flags']}") - return None, True + config = RuntimeConfig.from_parts(ctx.obj["project"], ctx.obj["profile"], ctx.obj["flags"]) + task = ListTask(ctx.obj["flags"], config) + + results = task.run() + success = task.interpret_results(results) + return results, success + + +ls = copy(cli.commands["list"]) +ls.hidden = True +cli.add_command(ls, "ls") # dbt parse @@ -323,6 +333,7 @@ def parse(ctx, **kwargs): @p.exclude @p.fail_fast @p.full_refresh +@p.models @p.profile @p.profiles_dir @p.project_dir @@ -368,6 +379,7 @@ def run_operation(ctx, **kwargs): @click.pass_context @p.exclude @p.full_refresh +@p.models @p.profile @p.profiles_dir @p.project_dir @@ -392,6 +404,7 @@ def seed(ctx, **kwargs): @click.pass_context @p.defer @p.exclude +@p.models @p.profile @p.profiles_dir @p.project_dir @@ -425,6 +438,7 @@ 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 @@ -449,6 +463,7 @@ def freshness(ctx, **kwargs): @p.exclude @p.fail_fast @p.indirect_selection +@p.models @p.profile @p.profiles_dir @p.project_dir diff --git a/core/dbt/cli/option_types.py b/core/dbt/cli/option_types.py index 1df8bef1f7a..e0294c2a096 100644 --- a/core/dbt/cli/option_types.py +++ b/core/dbt/cli/option_types.py @@ -1,4 +1,4 @@ -from click import ParamType +from click import ParamType, Choice from dbt.config.utils import parse_cli_vars from dbt.exceptions import ValidationException @@ -33,3 +33,13 @@ def convert(self, value, param, ctx): return None else: return value + + +class ChoiceTuple(Choice): + name = "CHOICE_TUPLE" + + def convert(self, value, param, ctx): + for value_item in value: + super().convert(value_item, param, ctx) + + return value diff --git a/core/dbt/cli/options.py b/core/dbt/cli/options.py new file mode 100644 index 00000000000..4ac705dc140 --- /dev/null +++ b/core/dbt/cli/options.py @@ -0,0 +1,44 @@ +import click + + +# Implementation from: https://stackoverflow.com/a/48394004 +# Note MultiOption options must be specified with type=tuple or type=ChoiceTuple (https://github.com/pallets/click/issues/2012) +class MultiOption(click.Option): + def __init__(self, *args, **kwargs): + self.save_other_options = kwargs.pop("save_other_options", True) + nargs = kwargs.pop("nargs", -1) + assert nargs == -1, "nargs, if set, must be -1 not {}".format(nargs) + super(MultiOption, self).__init__(*args, **kwargs) + self._previous_parser_process = None + self._eat_all_parser = None + + def add_to_parser(self, parser, ctx): + def parser_process(value, state): + # method to hook to the parser.process + done = False + value = [value] + if self.save_other_options: + # grab everything up to the next option + while state.rargs and not done: + for prefix in self._eat_all_parser.prefixes: + if state.rargs[0].startswith(prefix): + done = True + if not done: + value.append(state.rargs.pop(0)) + else: + # grab everything remaining + value += state.rargs + state.rargs[:] = [] + value = tuple(value) + # call the actual process + self._previous_parser_process(value, state) + + retval = super(MultiOption, self).add_to_parser(parser, ctx) + for name in self.opts: + our_parser = parser._long_opt.get(name) or parser._short_opt.get(name) + if our_parser: + self._eat_all_parser = our_parser + self._previous_parser_process = our_parser.process + our_parser.process = parser_process + break + return retval diff --git a/core/dbt/cli/params.py b/core/dbt/cli/params.py index 7795fb9d218..6173081ad75 100644 --- a/core/dbt/cli/params.py +++ b/core/dbt/cli/params.py @@ -1,7 +1,8 @@ from pathlib import Path, PurePath import click -from dbt.cli.option_types import YAML +from dbt.cli.options import MultiOption +from dbt.cli.option_types import YAML, ChoiceTuple from dbt.cli.resolvers import default_project_dir, default_profiles_dir @@ -80,7 +81,9 @@ hidden=True, ) -exclude = click.option("--exclude", envvar=None, help="Specify the nodes to exclude.") +exclude = click.option( + "--exclude", envvar=None, type=tuple, cls=MultiOption, help="Specify the nodes to exclude." +) fail_fast = click.option( "--fail-fast/--no-fail-fast", @@ -133,13 +136,22 @@ 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, help="TODO: No current help text", type=click.Choice(["json", "name", "path", "selector"], case_sensitive=False), - default="name", + default="selector", ) output_keys = click.option( @@ -233,10 +245,11 @@ ) resource_type = click.option( + "--resource-types", "--resource-type", envvar=None, help="TODO: No current help text", - type=click.Choice( + type=ChoiceTuple( [ "metric", "source", @@ -251,16 +264,17 @@ ], case_sensitive=False, ), - default="default", + cls=MultiOption, + default=(), ) select = click.option( - "-m", "-s", - "select", + "--select", envvar=None, help="Specify the nodes to include.", - multiple=True, + cls=MultiOption, + type=tuple, ) selector = click.option( diff --git a/core/dbt/docs/build/doctrees/environment.pickle b/core/dbt/docs/build/doctrees/environment.pickle index 9c9eb6d15e3..71d7f331d79 100644 Binary files a/core/dbt/docs/build/doctrees/environment.pickle and b/core/dbt/docs/build/doctrees/environment.pickle differ diff --git a/core/dbt/docs/build/doctrees/index.doctree b/core/dbt/docs/build/doctrees/index.doctree index 19f1fe1cd87..19135572dd5 100644 Binary files a/core/dbt/docs/build/doctrees/index.doctree and b/core/dbt/docs/build/doctrees/index.doctree differ diff --git a/core/dbt/docs/build/html/index.html b/core/dbt/docs/build/html/index.html index 0c4438bc8ea..d0fd61a3227 100644 --- a/core/dbt/docs/build/html/index.html +++ b/core/dbt/docs/build/html/index.html @@ -59,7 +59,7 @@
Type: string
+Type: unknown
Specify the nodes to exclude.
Type: string
+Type: unknown
Specify the nodes to include.
Type: string
+Type: unknown
Specify the nodes to exclude.
Type: unknown
+Specify the nodes to include.
+Type: boolean
@@ -206,7 +211,7 @@Type: string
+Type: unknown
Specify the nodes to include.
Type: string
+Type: unknown
Specify the nodes to exclude.
Select all tests that are adjacent to selected resources, even if they those resources have been explicitly selected.
Type: unknown
+Specify the nodes to include.
+Type: choice: [‘json’, ‘name’, ‘path’, ‘selector’]
@@ -374,14 +384,85 @@Type: choice: [‘metric’, ‘source’, ‘analysis’, ‘model’, ‘test’, ‘exposure’, ‘snapshot’, ‘seed’, ‘default’, ‘all’]
+Type: unknown
TODO: No current help text
Type: unknown
+Specify the nodes to include.
+Type: string
+The selector name to use, as defined in selectors.yml
+Type: path
+If set, use the given directory as the source for json files to compare with this project.
+Type: string
+Which target to load for the given profile
+Type: YAML
+Supply variables to the project. This argument overrides variables defined in your dbt_project.yml file. This argument should be a YAML string, eg. ‘{my_variable: my_value}’
+Type: unknown
+Specify the nodes to exclude.
+Type: choice: [‘eager’, ‘cautious’]
+Select all tests that are adjacent to selected resources, even if they those resources have been explicitly selected.
+Type: unknown
+Specify the nodes to include.
+Type: choice: [‘json’, ‘name’, ‘path’, ‘selector’]
+TODO: No current help text
+Type: string
+TODO: No current help text
+Type: string
+Which profile to load. Overrides setting in dbt_project.yml.
+Type: path
+Which directory to look in for the profiles.yml file. If not set, dbt will look in the current working directory first, then HOME/.dbt/
+Type: path
+Which directory to look in for the dbt_project.yml file. Default is the current working directory and its parents.
+Type: unknown
+TODO: No current help text
+Type: unknown
Specify the nodes to include.
Type: string
+Type: unknown
Specify the nodes to exclude.
Type: unknown
+Specify the nodes to include.
+Type: string
@@ -493,7 +579,7 @@Type: string
+Type: unknown
Specify the nodes to include.
Type: string
+Type: unknown
Specify the nodes to exclude.
Type: unknown
+Specify the nodes to include.
+Type: string
@@ -590,7 +681,7 @@Type: string
+Type: unknown
Specify the nodes to include.
Type: string
+Type: unknown
Specify the nodes to exclude.
Type: unknown
+Specify the nodes to include.
+Type: string
@@ -661,7 +757,7 @@Type: string
+Type: unknown
Specify the nodes to include.
Type: string
+Type: unknown
Specify the nodes to exclude.
Select all tests that are adjacent to selected resources, even if they those resources have been explicitly selected.
Type: unknown
+Specify the nodes to include.
+Type: string
@@ -728,7 +829,7 @@Type: string
+Type: unknown
Specify the nodes to include.