diff --git a/.changes/unreleased/Under the Hood-20240502-154430.yaml b/.changes/unreleased/Under the Hood-20240502-154430.yaml new file mode 100644 index 00000000000..6c17df3a6c6 --- /dev/null +++ b/.changes/unreleased/Under the Hood-20240502-154430.yaml @@ -0,0 +1,6 @@ +kind: Under the Hood +body: Clear error message for Private package in dbt-core +time: 2024-05-02T15:44:30.713097-07:00 +custom: + Author: ChenyuLInx + Issue: "10083" diff --git a/core/dbt/contracts/project.py b/core/dbt/contracts/project.py index 4b98143f4b4..b0b7179f333 100644 --- a/core/dbt/contracts/project.py +++ b/core/dbt/contracts/project.py @@ -78,6 +78,16 @@ def get_revisions(self) -> List[str]: return [str(self.revision)] +@dataclass +class PrivatePackage(Package): + private: str + provider: Optional[str] = None + revision: Optional[RawVersion] = None + warn_unpinned: Optional[bool] = field(default=None, metadata={"alias": "warn-unpinned"}) + subdirectory: Optional[str] = None + unrendered: Dict[str, Any] = field(default_factory=dict) + + @dataclass class RegistryPackage(Package): package: str @@ -92,7 +102,7 @@ def get_versions(self) -> List[str]: return [str(self.version)] -PackageSpec = Union[LocalPackage, TarballPackage, GitPackage, RegistryPackage] +PackageSpec = Union[LocalPackage, TarballPackage, GitPackage, RegistryPackage, PrivatePackage] @dataclass diff --git a/core/dbt/deps/resolver.py b/core/dbt/deps/resolver.py index 0ac27835511..b4a0c60ef6c 100644 --- a/core/dbt/deps/resolver.py +++ b/core/dbt/deps/resolver.py @@ -7,6 +7,7 @@ GitPackage, LocalPackage, PackageSpec, + PrivatePackage, RegistryPackage, TarballPackage, ) @@ -16,7 +17,7 @@ from dbt.deps.registry import RegistryUnpinnedPackage from dbt.deps.tarball import TarballUnpinnedPackage from dbt.exceptions import ( - DbtInternalError, + DependencyError, DuplicateDependencyToRootError, DuplicateProjectDependencyError, MismatchedDependencyTypeError, @@ -74,10 +75,14 @@ def update_from(self, src: List[PackageSpec]) -> None: pkg = TarballUnpinnedPackage.from_contract(contract) elif isinstance(contract, GitPackage): pkg = GitUnpinnedPackage.from_contract(contract) + elif isinstance(contract, PrivatePackage): + raise DependencyError( + f'Cannot resolve private package {contract.private} because git provider integration is missing. Please use a "git" package instead.' + ) elif isinstance(contract, RegistryPackage): pkg = RegistryUnpinnedPackage.from_contract(contract) else: - raise DbtInternalError("Invalid package type {}".format(type(contract))) + raise DependencyError("Invalid package type {}".format(type(contract))) self.incorporate(pkg) @classmethod diff --git a/tests/functional/configs/test_custom_node_colors_configs.py b/tests/functional/configs/test_custom_node_colors_configs.py index 1ca28d67795..7772e3d44ca 100644 --- a/tests/functional/configs/test_custom_node_colors_configs.py +++ b/tests/functional/configs/test_custom_node_colors_configs.py @@ -1,5 +1,6 @@ import pytest +from dbt.exceptions import ConfigUpdateError from dbt.tests.util import get_manifest, run_dbt from dbt_common.dataclass_schema import ValidationError @@ -304,7 +305,7 @@ def test__invalid_color_config_block( self, project, ): - with pytest.raises(ValidationError): + with pytest.raises((ValidationError, ConfigUpdateError)): run_dbt(["compile"]) diff --git a/tests/unit/test_deps.py b/tests/unit/test_deps.py index 1ca640c50c3..339bbbc5d23 100644 --- a/tests/unit/test_deps.py +++ b/tests/unit/test_deps.py @@ -791,6 +791,19 @@ def test_dependency_resolution(self): self.assertEqual(resolved[1].name, "dbt-labs-test/b") self.assertEqual(resolved[1].version, "0.2.1") + def test_private_package_raise_error(self): + package_config = PackageConfig.from_dict( + { + "packages": [ + {"private": "dbt-labs-test/a", "subdirectory": "foo-bar"}, + ], + } + ) + with self.assertRaisesRegex( + dbt.exceptions.DependencyError, "Cannot resolve private package" + ): + resolve_packages(package_config.packages, mock.MagicMock(project_name="test"), {}) + def test_dependency_resolution_allow_prerelease(self): package_config = PackageConfig.from_dict( {