dbt-bouncer 1.31.2rc3__py3-none-any.whl → 2.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dbt_bouncer/artifact_parsers/dbt_cloud/catalog_latest.py +21 -21
- dbt_bouncer/artifact_parsers/dbt_cloud/manifest_latest.py +1745 -1745
- dbt_bouncer/artifact_parsers/dbt_cloud/run_results_latest.py +22 -22
- dbt_bouncer/artifact_parsers/parsers_catalog.py +26 -24
- dbt_bouncer/artifact_parsers/parsers_common.py +57 -36
- dbt_bouncer/artifact_parsers/parsers_manifest.py +98 -69
- dbt_bouncer/artifact_parsers/parsers_run_results.py +32 -19
- dbt_bouncer/check_base.py +22 -11
- dbt_bouncer/checks/catalog/check_catalog_sources.py +22 -12
- dbt_bouncer/checks/catalog/check_columns.py +175 -105
- dbt_bouncer/checks/common.py +24 -3
- dbt_bouncer/checks/manifest/check_exposures.py +79 -52
- dbt_bouncer/checks/manifest/check_lineage.py +69 -40
- dbt_bouncer/checks/manifest/check_macros.py +177 -104
- dbt_bouncer/checks/manifest/check_metadata.py +28 -18
- dbt_bouncer/checks/manifest/check_models.py +842 -496
- dbt_bouncer/checks/manifest/check_seeds.py +63 -0
- dbt_bouncer/checks/manifest/check_semantic_models.py +28 -20
- dbt_bouncer/checks/manifest/check_snapshots.py +57 -33
- dbt_bouncer/checks/manifest/check_sources.py +246 -137
- dbt_bouncer/checks/manifest/check_unit_tests.py +97 -54
- dbt_bouncer/checks/run_results/check_run_results.py +34 -20
- dbt_bouncer/config_file_parser.py +47 -28
- dbt_bouncer/config_file_validator.py +11 -8
- dbt_bouncer/global_context.py +31 -0
- dbt_bouncer/main.py +128 -67
- dbt_bouncer/runner.py +61 -31
- dbt_bouncer/utils.py +146 -50
- dbt_bouncer/version.py +1 -1
- {dbt_bouncer-1.31.2rc3.dist-info → dbt_bouncer-2.0.0rc1.dist-info}/METADATA +15 -15
- dbt_bouncer-2.0.0rc1.dist-info/RECORD +37 -0
- dbt_bouncer-1.31.2rc3.dist-info/RECORD +0 -35
- {dbt_bouncer-1.31.2rc3.dist-info → dbt_bouncer-2.0.0rc1.dist-info}/WHEEL +0 -0
- {dbt_bouncer-1.31.2rc3.dist-info → dbt_bouncer-2.0.0rc1.dist-info}/entry_points.txt +0 -0
- {dbt_bouncer-1.31.2rc3.dist-info → dbt_bouncer-2.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {dbt_bouncer-1.31.2rc3.dist-info → dbt_bouncer-2.0.0rc1.dist-info}/top_level.txt +0 -0
dbt_bouncer/utils.py
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
# mypy: disable-error-code="arg-type,attr-defined,union-attr"
|
|
2
|
-
|
|
3
1
|
"""Re-usable functions for dbt-bouncer."""
|
|
4
2
|
|
|
5
3
|
import importlib
|
|
4
|
+
import importlib.util
|
|
5
|
+
import inspect
|
|
6
6
|
import logging
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
9
|
import sys
|
|
10
|
+
from collections.abc import Mapping
|
|
10
11
|
from functools import lru_cache
|
|
11
12
|
from pathlib import Path
|
|
12
|
-
from typing import TYPE_CHECKING, Any
|
|
13
|
+
from typing import TYPE_CHECKING, Any
|
|
13
14
|
|
|
14
|
-
import click
|
|
15
15
|
import yaml
|
|
16
16
|
from packaging.version import Version as PyPIVersion
|
|
17
17
|
from semver import Version
|
|
@@ -31,7 +31,7 @@ def clean_path_str(path: str) -> str:
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
def create_github_comment_file(
|
|
34
|
-
failed_checks:
|
|
34
|
+
failed_checks: list[list[str]], show_all_failures: bool
|
|
35
35
|
) -> None:
|
|
36
36
|
"""Create a markdown file containing a comment for GitHub."""
|
|
37
37
|
md_formatted_comment = make_markdown_table(
|
|
@@ -59,7 +59,7 @@ def create_github_comment_file(
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
def get_nested_value(
|
|
62
|
-
d:
|
|
62
|
+
d: dict[str, Any], keys: list[str], default: Any | None = None
|
|
63
63
|
) -> Any:
|
|
64
64
|
"""Retrieve a value from a nested dictionary using a list of keys.
|
|
65
65
|
|
|
@@ -104,11 +104,11 @@ def resource_in_path(check, resource) -> bool:
|
|
|
104
104
|
)
|
|
105
105
|
|
|
106
106
|
|
|
107
|
-
def find_missing_meta_keys(meta_config, required_keys) ->
|
|
107
|
+
def find_missing_meta_keys(meta_config, required_keys) -> list[str]:
|
|
108
108
|
"""Find missing keys in a meta config.
|
|
109
109
|
|
|
110
110
|
Returns:
|
|
111
|
-
|
|
111
|
+
list[str]: List of missing keys.
|
|
112
112
|
|
|
113
113
|
"""
|
|
114
114
|
# Get all keys in meta config
|
|
@@ -150,54 +150,133 @@ def flatten(structure: Any, key: str = "", path: str = "", flattened=None):
|
|
|
150
150
|
return flattened
|
|
151
151
|
|
|
152
152
|
|
|
153
|
+
def _extract_checks_from_module(
|
|
154
|
+
module: Any, module_name: str, check_objects: list[type["BaseCheck"]]
|
|
155
|
+
) -> None:
|
|
156
|
+
"""Extract Check* classes from a loaded module.
|
|
157
|
+
|
|
158
|
+
Inspects the given module and appends any class whose name starts with
|
|
159
|
+
"Check" and is defined within the specified module (not imported from
|
|
160
|
+
elsewhere) to the provided check_objects list.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
module: The loaded module object to inspect.
|
|
164
|
+
module_name: The fully qualified name of the module (used to filter
|
|
165
|
+
out imported classes).
|
|
166
|
+
check_objects: A list to which discovered check classes will be
|
|
167
|
+
appended.
|
|
168
|
+
|
|
169
|
+
"""
|
|
170
|
+
for name, obj in inspect.getmembers(module):
|
|
171
|
+
if (
|
|
172
|
+
inspect.isclass(obj)
|
|
173
|
+
and name.startswith("Check")
|
|
174
|
+
and obj.__module__ == module_name
|
|
175
|
+
):
|
|
176
|
+
check_objects.append(obj)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _load_custom_checks(
|
|
180
|
+
custom_checks_dir: Path, check_objects: list[type["BaseCheck"]]
|
|
181
|
+
) -> None:
|
|
182
|
+
"""Load custom check classes from a directory.
|
|
183
|
+
|
|
184
|
+
Scans the specified directory for Python files in subdirectories
|
|
185
|
+
(e.g., `custom_checks_dir/category/check_file.py`) and loads any
|
|
186
|
+
Check* classes defined in them.
|
|
187
|
+
|
|
188
|
+
Each file is loaded as a uniquely named module to avoid conflicts with
|
|
189
|
+
internal checks or other custom checks.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
custom_checks_dir: Path to the directory containing custom checks.
|
|
193
|
+
check_objects: A list to which discovered check classes will be
|
|
194
|
+
appended.
|
|
195
|
+
|
|
196
|
+
Raises:
|
|
197
|
+
RuntimeError: If a custom check file fails to load.
|
|
198
|
+
|
|
199
|
+
"""
|
|
200
|
+
logging.debug(f"{custom_checks_dir=}")
|
|
201
|
+
if custom_checks_dir.exists():
|
|
202
|
+
custom_check_files = [
|
|
203
|
+
f for f in custom_checks_dir.glob("*/*.py") if f.is_file()
|
|
204
|
+
]
|
|
205
|
+
logging.debug(f"{custom_check_files=}")
|
|
206
|
+
|
|
207
|
+
for check_file in custom_check_files:
|
|
208
|
+
# Use a unique module name to avoid conflicts
|
|
209
|
+
unique_module_name = (
|
|
210
|
+
f"custom_check_{check_file.stem}_{abs(hash(str(check_file)))}"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
spec = importlib.util.spec_from_file_location(
|
|
215
|
+
unique_module_name, check_file
|
|
216
|
+
)
|
|
217
|
+
if spec and spec.loader:
|
|
218
|
+
module = importlib.util.module_from_spec(spec)
|
|
219
|
+
sys.modules[unique_module_name] = module
|
|
220
|
+
spec.loader.exec_module(module)
|
|
221
|
+
|
|
222
|
+
_extract_checks_from_module(
|
|
223
|
+
module, unique_module_name, check_objects
|
|
224
|
+
)
|
|
225
|
+
except Exception as e:
|
|
226
|
+
raise RuntimeError(
|
|
227
|
+
f"Failed to load custom check file {check_file}: {e}"
|
|
228
|
+
) from e
|
|
229
|
+
else:
|
|
230
|
+
logging.warning(
|
|
231
|
+
f"Custom checks directory `{custom_checks_dir}` does not exist."
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
|
|
153
235
|
@lru_cache
|
|
154
|
-
def get_check_objects(
|
|
155
|
-
|
|
236
|
+
def get_check_objects(
|
|
237
|
+
custom_checks_dir: Path | None = None,
|
|
238
|
+
) -> list[type["BaseCheck"]]:
|
|
239
|
+
"""Get list of Check* classes.
|
|
240
|
+
|
|
241
|
+
This function dynamically discovers and loads check classes from two sources:
|
|
242
|
+
1. Internal checks located in the `checks` directory of the package.
|
|
243
|
+
2. Custom checks located in the specified `custom_checks_dir` (if provided).
|
|
244
|
+
|
|
245
|
+
It filters for classes that:
|
|
246
|
+
- Start with "Check".
|
|
247
|
+
- Are defined within the loaded module (not imported).
|
|
248
|
+
|
|
249
|
+
The result is cached using `@lru_cache` to avoid redundant file scanning
|
|
250
|
+
and module loading on subsequent calls. Import errors in individual files
|
|
251
|
+
are logged as warnings and do not stop execution.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
custom_checks_dir: Path to a directory containing custom checks.
|
|
156
255
|
|
|
157
256
|
Returns:
|
|
158
|
-
|
|
257
|
+
list[type[BaseCheck]]: List of Check* classes.
|
|
159
258
|
|
|
160
259
|
"""
|
|
260
|
+
check_objects: list[type["BaseCheck"]] = []
|
|
161
261
|
|
|
162
|
-
|
|
163
|
-
"""Import the Check* class to locals()."""
|
|
164
|
-
spec = importlib.util.spec_from_file_location(check_class_name, check_file_path)
|
|
165
|
-
module = importlib.util.module_from_spec(spec)
|
|
166
|
-
spec.loader.exec_module(module)
|
|
167
|
-
sys._getframe().f_locals[check_class_name] = module
|
|
168
|
-
check_objects.append(locals()[check_class_name])
|
|
169
|
-
|
|
170
|
-
check_objects: List[Type["BaseCheck"]] = []
|
|
262
|
+
# 1. Load internal checks
|
|
171
263
|
check_files = [
|
|
172
264
|
f for f in (Path(__file__).parent / "checks").glob("*/*.py") if f.is_file()
|
|
173
265
|
]
|
|
174
266
|
for check_file in check_files:
|
|
175
|
-
|
|
176
|
-
|
|
267
|
+
# e.g. dbt_bouncer.checks.manifest.check_models
|
|
268
|
+
module_name = ".".join(
|
|
269
|
+
["dbt_bouncer", "checks", check_file.parts[-2], check_file.stem]
|
|
177
270
|
)
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
271
|
+
try:
|
|
272
|
+
module = importlib.import_module(module_name)
|
|
273
|
+
_extract_checks_from_module(module, module_name, check_objects)
|
|
274
|
+
except ImportError:
|
|
275
|
+
logging.warning(f"Failed to import internal check module: {module_name}")
|
|
182
276
|
|
|
183
|
-
|
|
184
|
-
custom_checks_dir = click.get_current_context().obj["custom_checks_dir"]
|
|
277
|
+
# 2. Load custom checks (if any)
|
|
185
278
|
if custom_checks_dir is not None:
|
|
186
|
-
custom_checks_dir
|
|
187
|
-
logging.debug(f"{custom_checks_dir=}")
|
|
188
|
-
custom_check_files = [
|
|
189
|
-
f for f in Path(custom_checks_dir).glob("*/*.py") if f.is_file()
|
|
190
|
-
]
|
|
191
|
-
logging.debug(f"{custom_check_files=}")
|
|
192
|
-
|
|
193
|
-
for check_file in custom_check_files:
|
|
194
|
-
spec = importlib.util.spec_from_file_location("custom_check", check_file)
|
|
195
|
-
foo = importlib.util.module_from_spec(spec)
|
|
196
|
-
sys.modules["custom_check"] = foo
|
|
197
|
-
spec.loader.exec_module(foo)
|
|
198
|
-
for obj in dir(foo):
|
|
199
|
-
if obj.startswith("Check"):
|
|
200
|
-
import_check(obj, check_file.absolute().__str__())
|
|
279
|
+
_load_custom_checks(Path(custom_checks_dir), check_objects)
|
|
201
280
|
|
|
202
281
|
logging.debug(f"Loaded {len(check_objects)} `Check*` classes.")
|
|
203
282
|
|
|
@@ -233,6 +312,26 @@ def get_package_version_number(version_string: str) -> Version:
|
|
|
233
312
|
return Version(*p.release)
|
|
234
313
|
|
|
235
314
|
|
|
315
|
+
def is_description_populated(description: str, min_description_length: int) -> bool:
|
|
316
|
+
"""Check if a description is populated.
|
|
317
|
+
|
|
318
|
+
Args:
|
|
319
|
+
description (str): Description.
|
|
320
|
+
min_description_length (int): Minimum length of the description.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
bool: Whether a description is validly populated.
|
|
324
|
+
|
|
325
|
+
"""
|
|
326
|
+
return len(
|
|
327
|
+
description.strip()
|
|
328
|
+
) >= min_description_length and description.strip().lower() not in (
|
|
329
|
+
"none",
|
|
330
|
+
"null",
|
|
331
|
+
"n/a",
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
|
|
236
335
|
def load_config_from_yaml(config_file: Path) -> Mapping[str, Any]:
|
|
237
336
|
"""Safely load a YAML file to a dict object.
|
|
238
337
|
|
|
@@ -259,7 +358,7 @@ def load_config_from_yaml(config_file: Path) -> Mapping[str, Any]:
|
|
|
259
358
|
return conf
|
|
260
359
|
|
|
261
360
|
|
|
262
|
-
def make_markdown_table(array:
|
|
361
|
+
def make_markdown_table(array: list[list[str]]) -> str:
|
|
263
362
|
"""Transform a list of lists into a markdown table. The first element is the header row.
|
|
264
363
|
|
|
265
364
|
Returns:
|
|
@@ -281,7 +380,7 @@ def make_markdown_table(array: List[List[str]]) -> str:
|
|
|
281
380
|
return markdown
|
|
282
381
|
|
|
283
382
|
|
|
284
|
-
def object_in_path(include_pattern: str, path: str) -> bool:
|
|
383
|
+
def object_in_path(include_pattern: str | None, path: str) -> bool:
|
|
285
384
|
"""Determine if an object is included in the specified path pattern.
|
|
286
385
|
|
|
287
386
|
If no pattern is specified then all objects are included.
|
|
@@ -290,9 +389,6 @@ def object_in_path(include_pattern: str, path: str) -> bool:
|
|
|
290
389
|
bool: True if the object is included in the path pattern, False otherwise.
|
|
291
390
|
|
|
292
391
|
"""
|
|
293
|
-
if include_pattern is
|
|
294
|
-
return (
|
|
295
|
-
re.compile(include_pattern.strip()).match(clean_path_str(path)) is not None
|
|
296
|
-
)
|
|
297
|
-
else:
|
|
392
|
+
if include_pattern is None:
|
|
298
393
|
return True
|
|
394
|
+
return re.compile(include_pattern.strip()).match(clean_path_str(path)) is not None
|
dbt_bouncer/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbt-bouncer
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0rc1
|
|
4
4
|
Summary: Configure and enforce conventions for your dbt project.
|
|
5
5
|
Author-email: Padraic Slattery <pgoslatara@gmail.com>
|
|
6
6
|
Maintainer-email: Padraic Slattery <pgoslatara@gmail.com>
|
|
@@ -13,43 +13,40 @@ Classifier: Programming Language :: Python :: 3 :: Only
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
-
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Requires-Python: <3.15,>=3.11
|
|
17
18
|
Description-Content-Type: text/markdown
|
|
18
19
|
License-File: LICENSE
|
|
19
|
-
Requires-Dist: click
|
|
20
|
+
Requires-Dist: click!=8.3.0,!=8.3.1,<9
|
|
20
21
|
Requires-Dist: dbt-artifacts-parser>=0.8
|
|
21
22
|
Requires-Dist: h11>=0.16.0
|
|
22
23
|
Requires-Dist: jellyfish<2,>=1
|
|
23
24
|
Requires-Dist: jinja2<4,>=3
|
|
24
25
|
Requires-Dist: jinja2-simple-tags<1
|
|
25
|
-
Requires-Dist: packaging<
|
|
26
|
+
Requires-Dist: packaging<26
|
|
26
27
|
Requires-Dist: progress
|
|
27
28
|
Requires-Dist: pydantic<3,>=2
|
|
29
|
+
Requires-Dist: pytest<=10
|
|
28
30
|
Requires-Dist: pyyaml<7
|
|
29
31
|
Requires-Dist: requests<3,>=2
|
|
30
32
|
Requires-Dist: tabulate<1
|
|
31
33
|
Requires-Dist: toml<1
|
|
32
34
|
Requires-Dist: semver<4
|
|
33
35
|
Provides-Extra: dev
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist: dbt-core<2,>=1.10.0; extra == "dev"
|
|
36
|
+
Requires-Dist: bandit~=1.0; extra == "dev"
|
|
37
|
+
Requires-Dist: dbt-core<2,>=1.11.2; extra == "dev"
|
|
37
38
|
Requires-Dist: dbt-duckdb~=1.0; extra == "dev"
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist: mypy~=1.0; extra == "dev"
|
|
40
|
-
Requires-Dist: pre-commit<5,>=3; extra == "dev"
|
|
41
|
-
Requires-Dist: pytest<=10; extra == "dev"
|
|
39
|
+
Requires-Dist: prek<1,>=0.1; extra == "dev"
|
|
42
40
|
Requires-Dist: pytest-cov<8,>=5; extra == "dev"
|
|
43
41
|
Requires-Dist: pytest-xdist~=3.0; extra == "dev"
|
|
42
|
+
Requires-Dist: pyupgrade~=3.0; extra == "dev"
|
|
44
43
|
Requires-Dist: ruff~=0.0; extra == "dev"
|
|
45
44
|
Requires-Dist: shandy-sqlfmt[jinjafmt]~=0.0; extra == "dev"
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist: types-tabulate~=0.0; extra == "dev"
|
|
48
|
-
Requires-Dist: types-toml~=0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: ty>=0.0.7; extra == "dev"
|
|
49
46
|
Provides-Extra: docs
|
|
50
47
|
Requires-Dist: mike~=2.0; extra == "docs"
|
|
51
48
|
Requires-Dist: mkdocs~=1.0; extra == "docs"
|
|
52
|
-
Requires-Dist: mkdocstrings-python<
|
|
49
|
+
Requires-Dist: mkdocstrings-python<3; extra == "docs"
|
|
53
50
|
Requires-Dist: mkdocs-click~=0.0; extra == "docs"
|
|
54
51
|
Requires-Dist: mkdocs-git-revision-date-localized-plugin~=1.0; extra == "docs"
|
|
55
52
|
Requires-Dist: mkdocs-material~=9.0; extra == "docs"
|
|
@@ -75,6 +72,9 @@ Dynamic: license-file
|
|
|
75
72
|
<a>
|
|
76
73
|
<img src="https://img.shields.io/badge/License-MIT-yellow.svg">
|
|
77
74
|
</a>
|
|
75
|
+
<a>
|
|
76
|
+
<img alt="security: bandit" href="https://github.com/PyCQA/bandit" src="https://img.shields.io/badge/security-bandit-yellow.svg">
|
|
77
|
+
</a>
|
|
78
78
|
<a>
|
|
79
79
|
<img src="https://img.shields.io/github/last-commit/godatadriven/dbt-bouncer/main">
|
|
80
80
|
</a>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
dbt_bouncer/__init__.py,sha256=vJ9zw-0crTEO2MzmPQUUCebBQCSYiOleGNUUx_eX3eo,33
|
|
2
|
+
dbt_bouncer/check_base.py,sha256=q40xQ7nG51V7YXhob20_Csgsv57v_4hnIOXGiD7Q4Jg,2920
|
|
3
|
+
dbt_bouncer/config_file_parser.py,sha256=iun73dJfaC6n171YihA4pEVM22wngHOIcwXGVC7BU-k,5653
|
|
4
|
+
dbt_bouncer/config_file_validator.py,sha256=oOs4lgflLIMKdARra3Je0MggzF4gEfBRwFWioSn-BNQ,11330
|
|
5
|
+
dbt_bouncer/global_context.py,sha256=5ct2jjtaTtfgO8vHYCBETaxOoYG4u5lDaBltFn0RJzE,690
|
|
6
|
+
dbt_bouncer/logger.py,sha256=qkwB-SVUE4YUUp-MtmbcDPUX7t3zdniQL5Linuomr94,1804
|
|
7
|
+
dbt_bouncer/main.py,sha256=wQtl3i7QDoo4ymiYrneaRBecDHWSNwSBY7B0GSnT1NU,8694
|
|
8
|
+
dbt_bouncer/runner.py,sha256=1JjMecab6d5UYkWBa4bkw5SWlA0RDb40sbp7YB_9BYw,11650
|
|
9
|
+
dbt_bouncer/utils.py,sha256=WaqIVRCvuHRqnN3lMd9xtzLGJ-E06gz3Ols6jIZZC5k,12810
|
|
10
|
+
dbt_bouncer/version.py,sha256=Xd_u4K-00ASNLNIka953jW8CU5JQazjTBPzuFpHkfQ8,151
|
|
11
|
+
dbt_bouncer/artifact_parsers/parsers_catalog.py,sha256=CbW_8IoNX8Son32Z5Ca2aqoyqPLalD6zKokogZOe-6s,3173
|
|
12
|
+
dbt_bouncer/artifact_parsers/parsers_common.py,sha256=R6CBF8EwpqUZnApLFST3CxSB9eauPaz_oU8bDXU5kCo,7390
|
|
13
|
+
dbt_bouncer/artifact_parsers/parsers_manifest.py,sha256=79zMP2MhOsaqioc8VxO9vMRJcdY1ALQ_CvWEPO8OpWE,10698
|
|
14
|
+
dbt_bouncer/artifact_parsers/parsers_run_results.py,sha256=6gy-O8DtM7wvkK8-CO63e4PDcUrWPPk8fowkCfnc9z4,4301
|
|
15
|
+
dbt_bouncer/artifact_parsers/dbt_cloud/catalog_latest.py,sha256=OxPqLdD5FuBHMasFCrbrMSf2DQLGBBSwWZGq0Yqd9PA,1986
|
|
16
|
+
dbt_bouncer/artifact_parsers/dbt_cloud/manifest_latest.py,sha256=ckKaCAtbUfwxvdBfCaCCYpHKGGU4t8K8tpswhCfVSQs,112404
|
|
17
|
+
dbt_bouncer/artifact_parsers/dbt_cloud/run_results_latest.py,sha256=BtQyf3nOLSYk5kk8zXaGvh1zfwMVQpRLJ3K-WD2h_FY,2048
|
|
18
|
+
dbt_bouncer/checks/common.py,sha256=o_SNf027I5pRDYHGiJozd1oth1mlKEyr6dP-5ARVO-0,701
|
|
19
|
+
dbt_bouncer/checks/catalog/check_catalog_sources.py,sha256=B1genNB-fn_Q9S11M1BjK2LUfmC6ZcD5DgkzQ7akhIU,2589
|
|
20
|
+
dbt_bouncer/checks/catalog/check_columns.py,sha256=XAzVpCitEHtRXdIrR64rSaJzTty8WGW2ehBPGpsbwHE,18866
|
|
21
|
+
dbt_bouncer/checks/manifest/check_exposures.py,sha256=YOqDiXy5kRo8TXPQUCZmD0-6Q3TjyJ7gtbCiYEvUWi8,8108
|
|
22
|
+
dbt_bouncer/checks/manifest/check_lineage.py,sha256=YoUD8J3-k4wMesHZ5RqSFCml-ZXDHAA5L6_JnYNpno4,6887
|
|
23
|
+
dbt_bouncer/checks/manifest/check_macros.py,sha256=3mHLa7nzMhB37Kb4arzcBMADeEI2yFG3VT3Mc4CulXs,15315
|
|
24
|
+
dbt_bouncer/checks/manifest/check_metadata.py,sha256=O7VqiI8FTA7wrs5_dk_DP7PwvARojk5OuAtBbeZSsWU,2473
|
|
25
|
+
dbt_bouncer/checks/manifest/check_models.py,sha256=ixWgqml6sBFc5UoCXrv70wbv33xvWEG6Oa_cHzW5r_w,79436
|
|
26
|
+
dbt_bouncer/checks/manifest/check_seeds.py,sha256=JDl-LbWnPiZbmB2VTX64yqMIM30-g963Qn8pjSYpfSs,2076
|
|
27
|
+
dbt_bouncer/checks/manifest/check_semantic_models.py,sha256=DpFWkLEDvefHGPEYHr2hYYag83R9z29RU8yBwmGpaTk,2847
|
|
28
|
+
dbt_bouncer/checks/manifest/check_snapshots.py,sha256=Ke7OdGHLHYquNjiBrw0lMImAcpB7AHxScIim7WmWohI,4507
|
|
29
|
+
dbt_bouncer/checks/manifest/check_sources.py,sha256=ZsV3aL10vKX_UM4ip2pAEkGUQdTWJcIVl6hzdXXnT6E,20921
|
|
30
|
+
dbt_bouncer/checks/manifest/check_unit_tests.py,sha256=I0orkSnueseUHqCQv7pdmzawnxZTwepDzcl8RgS5GXg,10046
|
|
31
|
+
dbt_bouncer/checks/run_results/check_run_results.py,sha256=WL8neXGyPBhV_znbilVTF57__lXE97kCGB2lSc7931w,4614
|
|
32
|
+
dbt_bouncer-2.0.0rc1.dist-info/licenses/LICENSE,sha256=gGXp4VL__ZWlTWhXHRjWJmkxl5X9UJ7L7n1dr2WlfsY,1074
|
|
33
|
+
dbt_bouncer-2.0.0rc1.dist-info/METADATA,sha256=MjpYiM-8lhn01ALw2HUQxvMRYX2DsM-vjwDawXWZrtc,5717
|
|
34
|
+
dbt_bouncer-2.0.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
35
|
+
dbt_bouncer-2.0.0rc1.dist-info/entry_points.txt,sha256=BGHZ6oZsZjq5MUVKYSdbwy80f7cEOCTC-UqqEN1GrBg,53
|
|
36
|
+
dbt_bouncer-2.0.0rc1.dist-info/top_level.txt,sha256=TnVuJYP3nH_F7nkc63iXA34kAnwrOWWDpTUyd-GLpR4,12
|
|
37
|
+
dbt_bouncer-2.0.0rc1.dist-info/RECORD,,
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
dbt_bouncer/__init__.py,sha256=vJ9zw-0crTEO2MzmPQUUCebBQCSYiOleGNUUx_eX3eo,33
|
|
2
|
-
dbt_bouncer/check_base.py,sha256=haCZiOn-7cod2XPWoOjUozJVVV7JGOK8OSwvZYsLwTw,2565
|
|
3
|
-
dbt_bouncer/config_file_parser.py,sha256=JjFoPhFARgPB_q8BnjRp9C9E5FhO1mcBWrDYEyeOfc4,5009
|
|
4
|
-
dbt_bouncer/config_file_validator.py,sha256=CzuEh_1cNQ-2zl7TA-9RKMECOAOoxcQLgODh9-7JHwA,11262
|
|
5
|
-
dbt_bouncer/logger.py,sha256=qkwB-SVUE4YUUp-MtmbcDPUX7t3zdniQL5Linuomr94,1804
|
|
6
|
-
dbt_bouncer/main.py,sha256=n-jOsKlDwAlB2uF__J_DtkU8BC7CqeKMOU_f8axB1fo,6433
|
|
7
|
-
dbt_bouncer/runner.py,sha256=fdgpOUS8ckS_rZbklOUqFSxmD6I8WYRhQU09HZI0Ghs,10628
|
|
8
|
-
dbt_bouncer/utils.py,sha256=-jZjc6R0tjHWqpTjgHIb7Ej6Cqwdbchbl7L8IB4mo1I,9890
|
|
9
|
-
dbt_bouncer/version.py,sha256=jTw3-MfxlpBMMndkhV7FXFhjGnqbMBCIVzzObL1fknM,152
|
|
10
|
-
dbt_bouncer/artifact_parsers/parsers_catalog.py,sha256=2VbD3zib0jZdy7SCaYNQeYDXlxKpQykgOY7rUNnjQH0,3130
|
|
11
|
-
dbt_bouncer/artifact_parsers/parsers_common.py,sha256=KAbnDHPnC2uHn91FK8UZ8wYOs-jTBYQSzyuowKxCSUU,6729
|
|
12
|
-
dbt_bouncer/artifact_parsers/parsers_manifest.py,sha256=I9UnoNIHiAXXMGkZ-JEAbYKT6oGgBFtIUoOx14HeReU,9644
|
|
13
|
-
dbt_bouncer/artifact_parsers/parsers_run_results.py,sha256=Qv6HhHmD1jxFPypgvmexl5JfVEaltREiCikJPIYQ9dE,3786
|
|
14
|
-
dbt_bouncer/artifact_parsers/dbt_cloud/catalog_latest.py,sha256=W575XZj7U9fC7recAUzf63cFBh4gghyjYSVYmoKGN5Q,2062
|
|
15
|
-
dbt_bouncer/artifact_parsers/dbt_cloud/manifest_latest.py,sha256=EPgjUz2pRW2nS1_ZgLgXK9douoymKJ5vRk7VM3Emm0w,117707
|
|
16
|
-
dbt_bouncer/artifact_parsers/dbt_cloud/run_results_latest.py,sha256=d_bCyY3AM77UEemKnPlHCDcRF_UmfAO_vmPiNQ2kHIY,2111
|
|
17
|
-
dbt_bouncer/checks/common.py,sha256=WTaZZ1vQpi1AfTu_8OLlfADngeNiVAmQ5lVaeYNUBtc,192
|
|
18
|
-
dbt_bouncer/checks/catalog/check_catalog_sources.py,sha256=680dT_lqEem73X9Ur27-GiUskj7ALHaA16HdOUIePAo,2278
|
|
19
|
-
dbt_bouncer/checks/catalog/check_columns.py,sha256=uQoFGW3CDxdsFPVtmGIxbm_gVwUr9AF02zfO-3D8-1s,16124
|
|
20
|
-
dbt_bouncer/checks/manifest/check_exposures.py,sha256=qPeKwIuDmnsu5_eBgco64RYpSzhq1UueutOz-9Cpah4,7085
|
|
21
|
-
dbt_bouncer/checks/manifest/check_lineage.py,sha256=EHUXdR5D-ihwdwfvrIGewH8bL2yHXi1cfghv3VFe1I0,5949
|
|
22
|
-
dbt_bouncer/checks/manifest/check_macros.py,sha256=RzkKCBcyLHGKvKFZ1Cn_QGTAEjH_T_z_8IazKOJZH3c,12318
|
|
23
|
-
dbt_bouncer/checks/manifest/check_metadata.py,sha256=E9M-EXHU9JcR__5FotvVbhWc0M-H-JieB-9Wzbunsxg,2199
|
|
24
|
-
dbt_bouncer/checks/manifest/check_models.py,sha256=_6wL2aMNUSOqk3dInbLpcOYhVGoORnkd9HRjBTcoVTk,67851
|
|
25
|
-
dbt_bouncer/checks/manifest/check_semantic_models.py,sha256=GFVPCn16PcNlXFLCbWMEG6NADccJnxC-latmBQ23OrU,2500
|
|
26
|
-
dbt_bouncer/checks/manifest/check_snapshots.py,sha256=jmQNNVDn2s4UMJd0P7NAzzPPLIXWiDuE9qKTRiA4430,3795
|
|
27
|
-
dbt_bouncer/checks/manifest/check_sources.py,sha256=HW-uZ9toO9veNaahAdxqquerC85zwaTJKQmRhvn8qbo,17092
|
|
28
|
-
dbt_bouncer/checks/manifest/check_unit_tests.py,sha256=3_0FG91nSfC3k_dBDrJgRjF8rpzeA6GKSr3DmDP0ZTo,8417
|
|
29
|
-
dbt_bouncer/checks/run_results/check_run_results.py,sha256=LLX8Uziyc4hv303K31wLtuXMXng3WVJF2z1j_GbogAI,4117
|
|
30
|
-
dbt_bouncer-1.31.2rc3.dist-info/licenses/LICENSE,sha256=gGXp4VL__ZWlTWhXHRjWJmkxl5X9UJ7L7n1dr2WlfsY,1074
|
|
31
|
-
dbt_bouncer-1.31.2rc3.dist-info/METADATA,sha256=Yj1D6xMP47fjUicbowY-IQL8rqPFN7U_Qw2i7ep8rD4,5716
|
|
32
|
-
dbt_bouncer-1.31.2rc3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
33
|
-
dbt_bouncer-1.31.2rc3.dist-info/entry_points.txt,sha256=BGHZ6oZsZjq5MUVKYSdbwy80f7cEOCTC-UqqEN1GrBg,53
|
|
34
|
-
dbt_bouncer-1.31.2rc3.dist-info/top_level.txt,sha256=TnVuJYP3nH_F7nkc63iXA34kAnwrOWWDpTUyd-GLpR4,12
|
|
35
|
-
dbt_bouncer-1.31.2rc3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|