Skip to content

Commit

Permalink
Merge pull request #72 from nicholasyager/nicholasyager-update_owner_…
Browse files Browse the repository at this point in the history
…entry_ui

Feature: Update CLI for group creation to use explicit option names for group owner properties
  • Loading branch information
nicholasyager authored Jun 26, 2023
2 parents a4efdc5 + f20c0ef commit 0a42cd3
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pip install dbt-meshify
# create a group of all models tagged with "finance"
# leaf nodes and nodes with cross-group dependencies will be `public`
# public nodes will also have contracts added to them
dbt-meshify group finance --owner name Monopoly Man -s +tag:finance
dbt-meshify group finance --owner-name "Monopoly Man" -s +tag:finance

# optionally use the add-version operation to add a new version to a model
dbt-meshify operation add-version -s fct_orders
Expand Down
67 changes: 66 additions & 1 deletion dbt_meshify/cli.py
Original file line number Diff line number Diff line change
@@ -1 +1,66 @@
# TODO add the logic for each meshify command to independent tasks here to make cli thinner
import functools

import click

# define common parameters
project_path = click.option(
"--project-path",
type=click.Path(exists=True),
default=".",
help="The path to the dbt project to operate on. Defaults to the current directory.",
)

exclude = click.option(
"--exclude",
"-e",
default=None,
help="The dbt selection syntax specifying the resources to exclude in the operation",
)

group_yml_path = click.option(
"--group-yml-path",
type=click.Path(exists=False),
help="An optional path to store the new group YAML definition.",
)

select = click.option(
"--select",
"-s",
default=None,
help="The dbt selection syntax specifying the resources to include in the operation",
)

selector = click.option(
"--selector",
default=None,
help="The name of the YML selector specifying the resources to include in the operation",
)

owner_name = click.option(
"--owner-name",
help="The group Owner's name.",
)

owner_email = click.option(
"--owner-email",
help="The group Owner's email address.",
)

owner_properties = click.option(
"--owner-properties",
help="Additional properties to assign to a group Owner.",
)


def owner(func):
"""Add click options and argument validation for creating Owner objects."""

@functools.wraps(func)
def wrapper_decorator(*args, **kwargs):
if kwargs.get('owner_name') is None and kwargs.get('owner_email') is None:
raise click.UsageError(
"Groups require an Owner to be defined using --owner-name and/or --owner-email."
)
return func(*args, **kwargs)

return wrapper_decorator
76 changes: 29 additions & 47 deletions dbt_meshify/main.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,25 @@
import os
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
from typing import Optional

import click
import yaml
from dbt.contracts.graph.unparsed import Owner

from .cli import (
exclude,
group_yml_path,
owner,
owner_email,
owner_name,
owner_properties,
project_path,
select,
selector,
)
from .dbt_projects import DbtProject, DbtProjectHolder, DbtSubProject
from .storage.yaml_editors import DbtMeshModelConstructor

# define common parameters
project_path = click.option(
"--project-path",
type=click.Path(exists=True),
default=".",
help="The path to the dbt project to operate on. Defaults to the current directory.",
)

exclude = click.option(
"--exclude",
"-e",
default=None,
help="The dbt selection syntax specifying the resources to exclude in the operation",
)

group_yml_path = click.option(
"--group-yml-path",
type=click.Path(exists=False),
help="An optional path to store the new group YAML definition.",
)

select = click.option(
"--select",
"-s",
default=None,
help="The dbt selection syntax specifying the resources to include in the operation",
)

owner = click.option(
"--owner",
nargs=2,
multiple=True,
type=click.Tuple([str, str]),
help="A tuple of Owner information for the group. For example " "`--owner name example`",
)

selector = click.option(
"--selector",
default=None,
help="The name of the YML selector specifying the resources to include in the operation",
)


# define cli group
@click.group()
Expand Down Expand Up @@ -187,14 +157,19 @@ def add_version(select, exclude, project_path, selector, prerelease, defined_in)
@select
@selector
@click.argument("name")
@owner_name
@owner_email
@owner_properties
@owner
@group_yml_path
def create_group(
name,
project_path: os.PathLike,
owner: List[Tuple[str, str]],
group_yml_path: os.PathLike,
select: str,
owner_name: Optional[str] = None,
owner_email: Optional[str] = None,
owner_properties: Optional[str] = None,
exclude: Optional[str] = None,
selector: Optional[str] = None,
):
Expand All @@ -216,12 +191,14 @@ def create_group(
"The provided group-yml-path is not contained within the provided dbt project."
)

owner: Owner = Owner(**{key: value for key, value in owner})
group_owner: Owner = Owner(
name=owner_name, email=owner_email, _extra=yaml.safe_load(owner_properties or '{}')
)

grouper = ResourceGrouper(project)
grouper.add_group(
name=name,
owner=owner,
owner=group_owner,
select=select,
exclude=exclude,
selector=selector,
Expand All @@ -235,16 +212,21 @@ def create_group(
@select
@selector
@click.argument("name")
@owner_name
@owner_email
@owner_properties
@owner
@group_yml_path
@click.pass_context
def group(
ctx,
name,
project_path: os.PathLike,
owner: List[Tuple[str, str]],
group_yml_path: os.PathLike,
select: str,
owner_name: Optional[str] = None,
owner_email: Optional[str] = None,
owner_properties: Optional[str] = None,
exclude: Optional[str] = None,
selector: Optional[str] = None,
):
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Here's how that might look for the process of creating a separate `finance` subp
# create a group of all models tagged with "finance"
# leaf nodes and nodes with cross-group dependencies will be `public`
# public nodes will also have contracts added to them
dbt-meshify group finance --owner name Monopoly Man -s +tag:finance
dbt-meshify group finance --owner-name "Monopoly Man" -s +tag:finance

# optionally use the add-version operation to add a new version to a model
dbt-meshify operation add-version -s fct_orders
Expand Down
10 changes: 4 additions & 6 deletions tests/integration/test_create_group_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ def test_create_group_command(model_yml, start_group_yml, end_group_yml):
"shared_model",
"--project-path",
proj_path_string,
"--owner",
"name",
"--owner-name",
"Shaina Fake",
"--owner",
"email",
"--owner-email",
"fake@example.com",
],
)
Expand Down Expand Up @@ -97,10 +95,10 @@ def test_group_group_owner_properties(name, email, end_group_yml):
args = ["test_group", "--select", "shared_model", "--project-path", proj_path_string]

if name:
args += ["--owner", "name", name]
args += ["--owner-name", name]

if email:
args += ["--owner", "email", email]
args += ["--owner-email", email]

runner = CliRunner()
result = runner.invoke(create_group, args)
Expand Down
3 changes: 1 addition & 2 deletions tests/integration/test_group_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ def test_group_command(select, expected_public_contracted_models):
group,
[
"test_group",
"--owner",
"name",
"--owner-name",
"Teenage Mutant Jinja Turtles",
"--select",
select,
Expand Down

0 comments on commit 0a42cd3

Please sign in to comment.