Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ restructure deps command with package-lock.yml #6735

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/Features-20230125-165933.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Features
body: add log file of installed packages via dbt deps
time: 2023-01-25T16:59:33.786304-05:00
custom:
Author: jusbaldw
Issue: "6643"
56 changes: 52 additions & 4 deletions core/dbt/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from dbt.contracts.graph.manifest import Manifest
from dbt.task.clean import CleanTask
from dbt.task.compile import CompileTask
from dbt.task.deps import DepsTask
from dbt.task.deps import AddTask, DepsTask, LockTask
from dbt.task.debug import DebugTask
from dbt.task.run import RunTask
from dbt.task.serve import ServeTask
Expand Down Expand Up @@ -289,7 +289,13 @@ def debug(ctx, **kwargs):


# dbt deps
@cli.command("deps")
@cli.group()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured out why invoke_without_command=True doesn't work for this case. Everything in click works, but in Flags we did some not ideal lookup here that made the assumption that a function name should always match the last part of input command. I will create a follow up ticket for that but you will find that if you change function name deps_install and deps_lock below to just install and lock, you should be able to run without any issue. One thing that I didn't check is whether the params at group level is correctly represented in Flags.

@click.pass_context
def deps(ctx, **kwargs):
"""Pull the most recent version of the dependencies listed in packages.yml"""


@deps.command("install")
@click.pass_context
@p.profile
@p.profiles_dir
Expand All @@ -299,14 +305,56 @@ def debug(ctx, **kwargs):
@requires.preflight
@requires.unset_profile
@requires.project
def deps(ctx, **kwargs):
"""Pull the most recent version of the dependencies listed in packages.yml"""
def deps_install(ctx, **kwargs):
"""Install the most recent version of the dependencies listed in packages.yml"""
task = DepsTask(ctx.obj["flags"], ctx.obj["project"])
results = task.run()
success = task.interpret_results(results)
return results, success


# dbt deps lock
@deps.command("lock")
@click.pass_context
@p.profile
@p.profiles_dir
@p.project_dir
@p.target
@p.vars
@requires.preflight
@requires.unset_profile
@requires.project
def deps_lock(ctx, **kwargs):
"""Pull the most recent version of the dependencies listed in packages.yml into package-lock.yml file"""
task = LockTask(ctx.obj["flags"], ctx.obj["project"])
results = task.run()
success = task.interpret_results(results)
return results, success


# dbt deps add
@deps.command("add")
@click.pass_context
@p.profile
@p.profiles_dir
@p.project_dir
@p.target
@p.vars
@p.package
@p.package_version
@p.source
@p.dry_run
@requires.preflight
@requires.unset_profile
@requires.project
def deps_add(ctx, **kwargs):
"""Add a new package to the packages.yml file"""
task = AddTask(ctx.obj["flags"], ctx.obj["project"])
results = task.run()
success = task.interpret_results(results)
return results, success


# dbt init
@cli.command("init")
@click.pass_context
Expand Down
24 changes: 24 additions & 0 deletions core/dbt/cli/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@
help="If set, defer to the state variable for resolving unselected nodes.",
)

dry_run = click.option(
"--dry-run",
envvar=None,
help="Option to run `dbt deps add` without updating package-lock.yml file.",
default=False,
type=click.BOOL,
)

enable_legacy_logger = click.option(
"--enable-legacy-logger/--no-enable-legacy-logger",
envvar="DBT_ENABLE_LEGACY_LOGGER",
Expand Down Expand Up @@ -160,6 +168,14 @@
default=PurePath.joinpath(Path.cwd(), "target/sources.json"),
)

package = click.option(
"--package", envvar=None, help="Name of package to add to packages.yml.", type=click.STRING
)

package_version = click.option(
"--version", envvar=None, help="Version of the package to install.", type=click.STRING
)

parse_only = click.option(
"--parse-only",
envvar=None,
Expand Down Expand Up @@ -312,6 +328,14 @@
"--skip-profile-setup", "-s", envvar=None, help="Skip interactive profile setup.", is_flag=True
)

source = click.option(
"--source",
envvar=None,
help="Source to download page from, must be one of hub, git, or local. Defaults to hub.",
type=click.Choice(["hub", "git", "local"], case_sensitive=True),
default="hub",
)

# TODO: The env var and name (reflected in flags) are corrections!
# The original name was `ARTIFACT_STATE_PATH` and used the env var `DBT_ARTIFACT_STATE_PATH`.
# Both of which break existing naming conventions.
Expand Down
7 changes: 5 additions & 2 deletions core/dbt/config/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,14 @@ def _load_yaml(path):
return load_yaml_text(contents)


def package_data_from_root(project_root):
package_filepath = resolve_path_from_base("packages.yml", project_root)
def package_data_from_root(project_root, package_file_name="packages.yml"):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the update and how this is being used it seems like just more of a function to load a yaml file vs anything related to package data. Maybe consider not have the default value for package_file_name and just rename the function completely?

package_filepath = resolve_path_from_base(package_file_name, project_root)

if path_exists(package_filepath):
packages_dict = _load_yaml(package_filepath)
else:
packages_dict = None

return packages_dict


Expand Down Expand Up @@ -502,6 +503,7 @@ def from_project_root(
project_root = os.path.normpath(project_root)
project_dict = load_raw_project(project_root)
config_version = project_dict.get("config-version", 1)

if config_version != 2:
raise DbtProjectError(
f"Invalid config version: {config_version}, expected 2",
Expand All @@ -510,6 +512,7 @@ def from_project_root(

packages_dict = package_data_from_root(project_root)
selectors_dict = selector_data_from_root(project_root)

return cls.from_dicts(
project_root=project_root,
project_dict=project_dict,
Expand Down
12 changes: 12 additions & 0 deletions core/dbt/deps/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,15 @@ def resolve_packages(
resolved = final.resolved()
_check_for_duplicate_project_names(resolved, project, renderer)
return resolved


def resolve_lock_packages(packages: List[PackageContract]) -> List[PinnedPackage]:
lock_packages = PackageListing.from_contracts(packages)
final = PackageListing()

for package in lock_packages:
final.incorporate(package)

resolved = final.resolved()

return resolved
67 changes: 67 additions & 0 deletions core/dbt/events/proto_types.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions core/dbt/events/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1392,6 +1392,51 @@ def message(self) -> str:
return f"The selection criterion '{self.spec_raw}' does not match any nodes"


@dataclass
class DepsLockCreated(InfoLevel, pt.DepsLockCreated):
def code(self):
return "M031"

def message(self) -> str:
return f"Created lock file in file path: {self.lock_filepath}"


@dataclass
class DepsLockUpdating(InfoLevel, pt.DepsLockUpdating):
def code(self):
return "M032"

def message(self) -> str:
return f"Updating lock file in file path: {self.lock_filepath}"


@dataclass
class DepsAddPackage(InfoLevel, pt.DepsAddPackage):
def code(self):
return "M033"

def message(self) -> str:
return f"Added new package {self.package_name}@{self.version} to {self.packages_filepath}"


@dataclass
class DepsFoundDuplicatePackage(InfoLevel, pt.DepsFoundDuplicatePackage):
def code(self):
return "M034"

def message(self) -> str:
return f"Found duplicate package in packages.yml, removing: {self.removed_package}"


@dataclass
class DepsVersionMissing(InfoLevel, pt.DepsVersionMissing):
def code(self):
return "M035"

def message(self) -> str:
return f"Version is required to add a package when source is {self.source}"


# =======================================================
# Q - Node execution
# =======================================================
Expand Down
Loading