dbt-bouncer 1.29.0__py3-none-any.whl → 1.30.0__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.
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  import warnings
3
- from typing import TYPE_CHECKING, List, Union
3
+ from typing import TYPE_CHECKING, List, Optional, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
@@ -50,6 +50,7 @@ class DbtBouncerCatalogNode(BaseModel):
50
50
  def parse_catalog(
51
51
  artifact_dir: "Path",
52
52
  manifest_obj: "DbtBouncerManifest",
53
+ package_name: Optional[str] = None,
53
54
  ) -> tuple[List[DbtBouncerCatalogNode], List[DbtBouncerCatalogNode]]:
54
55
  """Parse the catalog.json artifact.
55
56
 
@@ -73,7 +74,8 @@ def parse_catalog(
73
74
  },
74
75
  )
75
76
  for k, v in catalog_obj.catalog.nodes.items()
76
- if k.split(".")[-2] == manifest_obj.manifest.metadata.project_name
77
+ if k.split(".")[-2]
78
+ == (package_name or manifest_obj.manifest.metadata.project_name)
77
79
  ]
78
80
  project_catalog_sources = [
79
81
  DbtBouncerCatalogNode(
@@ -86,7 +88,8 @@ def parse_catalog(
86
88
  },
87
89
  )
88
90
  for k, v in catalog_obj.catalog.sources.items()
89
- if k.split(".")[1] == manifest_obj.manifest.metadata.project_name
91
+ if k.split(".")[1]
92
+ == (package_name or manifest_obj.manifest.metadata.project_name)
90
93
  ]
91
94
  logging.info(
92
95
  f"Parsed `catalog.json`: {len(project_catalog_nodes)} nodes, {len(project_catalog_sources)} sources.",
@@ -145,7 +145,7 @@ def parse_dbt_artifacts(
145
145
  project_tests,
146
146
  project_unit_tests,
147
147
  ) = parse_manifest_artifact(
148
- manifest_obj=manifest_obj,
148
+ manifest_obj=manifest_obj, package_name=bouncer_config.package_name
149
149
  )
150
150
 
151
151
  # Catalog, must come after manifest is parsed
@@ -158,6 +158,7 @@ def parse_dbt_artifacts(
158
158
  project_catalog_nodes, project_catalog_sources = parse_catalog(
159
159
  artifact_dir=dbt_artifacts_dir,
160
160
  manifest_obj=manifest_obj,
161
+ package_name=bouncer_config.package_name,
161
162
  )
162
163
  else:
163
164
  project_catalog_nodes = []
@@ -175,6 +176,7 @@ def parse_dbt_artifacts(
175
176
  project_run_results = parse_run_results_artifact(
176
177
  artifact_dir=dbt_artifacts_dir,
177
178
  manifest_obj=manifest_obj,
179
+ package_name=bouncer_config.package_name,
178
180
  )
179
181
  else:
180
182
  project_run_results = []
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import warnings
3
3
  from enum import Enum
4
- from typing import Any, Dict, List, Union
4
+ from typing import Any, Dict, List, Optional, Union
5
5
 
6
6
  from pydantic import BaseModel
7
7
 
@@ -173,7 +173,7 @@ def parse_manifest(
173
173
 
174
174
 
175
175
  def parse_manifest_artifact(
176
- manifest_obj: DbtBouncerManifest,
176
+ manifest_obj: DbtBouncerManifest, package_name: Optional[str] = None
177
177
  ) -> tuple[
178
178
  List[Exposures],
179
179
  List[Macros],
@@ -200,12 +200,14 @@ def parse_manifest_artifact(
200
200
  project_exposures = [
201
201
  v
202
202
  for _, v in manifest_obj.manifest.exposures.items()
203
- if v.package_name == manifest_obj.manifest.metadata.project_name
203
+ if v.package_name
204
+ == (package_name or manifest_obj.manifest.metadata.project_name)
204
205
  ]
205
206
  project_macros = [
206
207
  v
207
208
  for _, v in manifest_obj.manifest.macros.items()
208
- if v.package_name == manifest_obj.manifest.metadata.project_name
209
+ if v.package_name
210
+ == (package_name or manifest_obj.manifest.metadata.project_name)
209
211
  ]
210
212
  project_models = []
211
213
  project_snapshots = []
@@ -214,7 +216,9 @@ def parse_manifest_artifact(
214
216
  if (
215
217
  isinstance(v.resource_type, Enum) and v.resource_type.value == "model"
216
218
  ) or v.resource_type == "model":
217
- if v.package_name == manifest_obj.manifest.metadata.project_name:
219
+ if v.package_name == (
220
+ package_name or manifest_obj.manifest.metadata.project_name
221
+ ):
218
222
  project_models.append(
219
223
  DbtBouncerModel(
220
224
  **{
@@ -228,7 +232,9 @@ def parse_manifest_artifact(
228
232
  elif (
229
233
  (isinstance(v.resource_type, Enum) and v.resource_type.value == "snapshot")
230
234
  or v.resource_type == "snapshot"
231
- ) and v.package_name == manifest_obj.manifest.metadata.project_name:
235
+ ) and v.package_name == (
236
+ package_name or manifest_obj.manifest.metadata.project_name
237
+ ):
232
238
  project_snapshots.append(
233
239
  DbtBouncerSnapshot(
234
240
  **{
@@ -241,7 +247,9 @@ def parse_manifest_artifact(
241
247
  elif (
242
248
  (isinstance(v.resource_type, Enum) and v.resource_type.value == "test")
243
249
  or v.resource_type == "test"
244
- ) and v.package_name == manifest_obj.manifest.metadata.project_name:
250
+ ) and v.package_name == (
251
+ package_name or manifest_obj.manifest.metadata.project_name
252
+ ):
245
253
  project_tests.append(
246
254
  DbtBouncerTest(
247
255
  **{
@@ -258,7 +266,8 @@ def parse_manifest_artifact(
258
266
  project_unit_tests = [
259
267
  v
260
268
  for _, v in manifest_obj.manifest.unit_tests.items()
261
- if v.package_name == manifest_obj.manifest.metadata.project_name
269
+ if v.package_name
270
+ == (package_name or manifest_obj.manifest.metadata.project_name)
262
271
  ]
263
272
  else:
264
273
  project_unit_tests = []
@@ -272,7 +281,8 @@ def parse_manifest_artifact(
272
281
  },
273
282
  )
274
283
  for _, v in manifest_obj.manifest.semantic_models.items()
275
- if v.package_name == manifest_obj.manifest.metadata.project_name
284
+ if v.package_name
285
+ == (package_name or manifest_obj.manifest.metadata.project_name)
276
286
  ]
277
287
 
278
288
  project_sources = [
@@ -284,11 +294,12 @@ def parse_manifest_artifact(
284
294
  },
285
295
  )
286
296
  for _, v in manifest_obj.manifest.sources.items()
287
- if v.package_name == manifest_obj.manifest.metadata.project_name
297
+ if v.package_name
298
+ == (package_name or manifest_obj.manifest.metadata.project_name)
288
299
  ]
289
300
 
290
301
  logging.info(
291
- f"Parsed `manifest.json`, found `{manifest_obj.manifest.metadata.project_name}` project: {len(project_exposures)} exposures, {len(project_macros)} macros, {len(project_models)} nodes, {len(project_semantic_models)} semantic models, {len(project_snapshots)} snapshots, {len(project_sources)} sources, {len(project_tests)} tests, {len(project_unit_tests)} unit tests.",
302
+ f"Parsed `manifest.json`, found `{(package_name or manifest_obj.manifest.metadata.project_name)}` project: {len(project_exposures)} exposures, {len(project_macros)} macros, {len(project_models)} nodes, {len(project_semantic_models)} semantic models, {len(project_snapshots)} snapshots, {len(project_sources)} sources, {len(project_tests)} tests, {len(project_unit_tests)} unit tests.",
292
303
  )
293
304
  return (
294
305
  project_exposures,
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  import warnings
3
- from typing import TYPE_CHECKING, Any, Dict, List, Union
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
4
4
 
5
5
  from pydantic import BaseModel
6
6
 
@@ -64,6 +64,7 @@ def parse_run_results(
64
64
  def parse_run_results_artifact(
65
65
  artifact_dir: "Path",
66
66
  manifest_obj: "DbtBouncerManifest",
67
+ package_name: Optional[str] = None,
67
68
  ) -> List[DbtBouncerRunResult]:
68
69
  """Parse the run_results.json artifact.
69
70
 
@@ -112,7 +113,8 @@ def parse_run_results_artifact(
112
113
  },
113
114
  )
114
115
  for r in run_results_obj.results
115
- if r.unique_id.split(".")[1] == manifest_obj.manifest.metadata.project_name
116
+ if r.unique_id.split(".")[1]
117
+ == (package_name or manifest_obj.manifest.metadata.project_name)
116
118
  ]
117
119
  logging.info(
118
120
  f"Parsed `run_results.json`: {len(project_run_results)} results.",
@@ -1,7 +1,7 @@
1
1
  # mypy: disable-error-code="union-attr"
2
2
 
3
3
  import re
4
- from typing import TYPE_CHECKING, List, Literal
4
+ from typing import TYPE_CHECKING, List, Literal, Optional
5
5
 
6
6
  from dbt_bouncer.check_base import BaseCheck
7
7
 
@@ -53,6 +53,7 @@ class CheckLineagePermittedUpstreamModels(BaseCheck):
53
53
  model: "DbtBouncerModelBase" = Field(default=None)
54
54
  models: List["DbtBouncerModelBase"] = Field(default=[])
55
55
  name: Literal["check_lineage_permitted_upstream_models"]
56
+ package_name: Optional[str] = Field(default=None)
56
57
  upstream_path_pattern: str
57
58
 
58
59
  def execute(self) -> None:
@@ -61,7 +62,8 @@ class CheckLineagePermittedUpstreamModels(BaseCheck):
61
62
  x
62
63
  for x in self.model.depends_on.nodes
63
64
  if x.split(".")[0] == "model"
64
- and x.split(".")[1] == self.manifest_obj.manifest.metadata.project_name
65
+ and x.split(".")[1]
66
+ == (self.package_name or self.manifest_obj.manifest.metadata.project_name)
65
67
  ]
66
68
  not_permitted_upstream_models = [
67
69
  upstream_model
@@ -43,6 +43,7 @@ class CheckProjectName(BaseModel):
43
43
  )
44
44
  manifest_obj: "DbtBouncerManifest" = Field(default=None)
45
45
  name: Literal["check_project_name"]
46
+ package_name: Optional[str] = Field(default=None)
46
47
  project_name_pattern: str
47
48
  severity: Optional[Literal["error", "warn"]] = Field(
48
49
  default="error",
@@ -51,11 +52,14 @@ class CheckProjectName(BaseModel):
51
52
 
52
53
  def execute(self) -> None:
53
54
  """Execute the check."""
55
+ package_name = (
56
+ self.package_name or self.manifest_obj.manifest.metadata.project_name
57
+ )
54
58
  assert (
55
59
  re.compile(self.project_name_pattern.strip()).match(
56
- self.manifest_obj.manifest.metadata.project_name,
60
+ package_name,
57
61
  )
58
62
  is not None
59
63
  ), (
60
- f"Project name (`{self.manifest_obj.manifest.metadata.project_name}`) does not conform to the supplied regex `({self.project_name_pattern.strip()})`."
64
+ f"Project name (`{package_name}`) does not conform to the supplied regex `({self.project_name_pattern.strip()})`."
61
65
  )
@@ -924,6 +924,7 @@ class CheckModelMaxChainedViews(BaseCheck):
924
924
  model: "DbtBouncerModelBase" = Field(default=None)
925
925
  models: List["DbtBouncerModelBase"] = Field(default=[])
926
926
  name: Literal["check_model_max_chained_views"]
927
+ package_name: Optional[str] = Field(default=None)
927
928
 
928
929
  def execute(self) -> None:
929
930
  """Execute the check."""
@@ -984,7 +985,10 @@ class CheckModelMaxChainedViews(BaseCheck):
984
985
  max_chained_views=self.max_chained_views,
985
986
  models=self.models,
986
987
  model_unique_ids_to_check=[self.model.unique_id],
987
- package_name=self.manifest_obj.manifest.metadata.project_name,
988
+ package_name=(
989
+ self.package_name
990
+ or self.manifest_obj.manifest.metadata.project_name
991
+ ),
988
992
  ),
989
993
  )
990
994
  == 0
@@ -72,6 +72,9 @@ class DbtBouncerConfBase(BaseModel):
72
72
  default=None,
73
73
  description="Regexp to match which paths to include.",
74
74
  )
75
+ package_name: Optional[str] = Field(
76
+ default=None, description="If you want to run `dbt-bouncer` against a package."
77
+ )
75
78
  severity: Union[Literal["error", "warn"], None] = Field(
76
79
  default=None,
77
80
  description="Severity of the check, one of 'error' or 'warn'.",
dbt_bouncer/version.py CHANGED
@@ -5,4 +5,4 @@ def version() -> str:
5
5
  str: The version of `dbt-bouncer`.
6
6
 
7
7
  """
8
- return "1.29.0"
8
+ return "1.30.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dbt-bouncer
3
- Version: 1.29.0
3
+ Version: 1.30.0
4
4
  Summary: Configure and enforce conventions for your dbt project.
5
5
  License: MIT
6
6
  Keywords: python,cli,dbt,CI/CD
@@ -3,33 +3,33 @@ dbt_bouncer/artifact_parsers/dbt_cloud/README.md,sha256=MOOGbm2KHjlcvtiSxDVnQlCX
3
3
  dbt_bouncer/artifact_parsers/dbt_cloud/catalog_latest.py,sha256=W575XZj7U9fC7recAUzf63cFBh4gghyjYSVYmoKGN5Q,2062
4
4
  dbt_bouncer/artifact_parsers/dbt_cloud/manifest_latest.py,sha256=EPgjUz2pRW2nS1_ZgLgXK9douoymKJ5vRk7VM3Emm0w,117707
5
5
  dbt_bouncer/artifact_parsers/dbt_cloud/run_results_latest.py,sha256=d_bCyY3AM77UEemKnPlHCDcRF_UmfAO_vmPiNQ2kHIY,2111
6
- dbt_bouncer/artifact_parsers/parsers_catalog.py,sha256=QTmRowL9dh4n7gSmOFzTe6l33KFj2YS7UdrJD2EDObE,3028
7
- dbt_bouncer/artifact_parsers/parsers_common.py,sha256=ZGBpGZPMdb1n0uGO0Yd6nkRnSNXkxDcjqMQrO2CMc04,6580
8
- dbt_bouncer/artifact_parsers/parsers_manifest.py,sha256=hBQTi1QuMFKvAN9GEXAZVndEBT7Js-V8ceDTL5_BNCo,9319
9
- dbt_bouncer/artifact_parsers/parsers_run_results.py,sha256=ceySu_s4in_ArBFYG_I0fE5A_eSpOtMzAejVbIlqOSk,3710
6
+ dbt_bouncer/artifact_parsers/parsers_catalog.py,sha256=2VbD3zib0jZdy7SCaYNQeYDXlxKpQykgOY7rUNnjQH0,3130
7
+ dbt_bouncer/artifact_parsers/parsers_common.py,sha256=KAbnDHPnC2uHn91FK8UZ8wYOs-jTBYQSzyuowKxCSUU,6729
8
+ dbt_bouncer/artifact_parsers/parsers_manifest.py,sha256=I9UnoNIHiAXXMGkZ-JEAbYKT6oGgBFtIUoOx14HeReU,9644
9
+ dbt_bouncer/artifact_parsers/parsers_run_results.py,sha256=Qv6HhHmD1jxFPypgvmexl5JfVEaltREiCikJPIYQ9dE,3786
10
10
  dbt_bouncer/check_base.py,sha256=haCZiOn-7cod2XPWoOjUozJVVV7JGOK8OSwvZYsLwTw,2565
11
11
  dbt_bouncer/checks/catalog/check_catalog_sources.py,sha256=680dT_lqEem73X9Ur27-GiUskj7ALHaA16HdOUIePAo,2278
12
12
  dbt_bouncer/checks/catalog/check_columns.py,sha256=uQoFGW3CDxdsFPVtmGIxbm_gVwUr9AF02zfO-3D8-1s,16124
13
13
  dbt_bouncer/checks/common.py,sha256=WTaZZ1vQpi1AfTu_8OLlfADngeNiVAmQ5lVaeYNUBtc,192
14
14
  dbt_bouncer/checks/manifest/check_exposures.py,sha256=JLHpbIpm1TmFieU88RrKRcJUdtdnHdOb17SL3p55bY8,7077
15
- dbt_bouncer/checks/manifest/check_lineage.py,sha256=Q0K6iA_Va4DYLwMjuRoDBYrjE2GdvVU0gvVBFtf0cq0,5850
15
+ dbt_bouncer/checks/manifest/check_lineage.py,sha256=EHUXdR5D-ihwdwfvrIGewH8bL2yHXi1cfghv3VFe1I0,5949
16
16
  dbt_bouncer/checks/manifest/check_macros.py,sha256=RzkKCBcyLHGKvKFZ1Cn_QGTAEjH_T_z_8IazKOJZH3c,12318
17
- dbt_bouncer/checks/manifest/check_metadata.py,sha256=6o5zBRsJYYfEQU351hlUFQCHkVjQHKWgvyVcUxtF-xs,2100
18
- dbt_bouncer/checks/manifest/check_models.py,sha256=aiKKSpRrjGXekTy6uJnRVKOSUUhUbSGT8f2iP9Fy0fs,65928
17
+ dbt_bouncer/checks/manifest/check_metadata.py,sha256=E9M-EXHU9JcR__5FotvVbhWc0M-H-JieB-9Wzbunsxg,2199
18
+ dbt_bouncer/checks/manifest/check_models.py,sha256=38LIoiJE_7QY6t4HQFE4Th0FrbGlwk7O8QMXVMhsXLA,66075
19
19
  dbt_bouncer/checks/manifest/check_semantic_models.py,sha256=GFVPCn16PcNlXFLCbWMEG6NADccJnxC-latmBQ23OrU,2500
20
20
  dbt_bouncer/checks/manifest/check_snapshots.py,sha256=jmQNNVDn2s4UMJd0P7NAzzPPLIXWiDuE9qKTRiA4430,3795
21
21
  dbt_bouncer/checks/manifest/check_sources.py,sha256=HW-uZ9toO9veNaahAdxqquerC85zwaTJKQmRhvn8qbo,17092
22
22
  dbt_bouncer/checks/manifest/check_unit_tests.py,sha256=3_0FG91nSfC3k_dBDrJgRjF8rpzeA6GKSr3DmDP0ZTo,8417
23
23
  dbt_bouncer/checks/run_results/check_run_results.py,sha256=LLX8Uziyc4hv303K31wLtuXMXng3WVJF2z1j_GbogAI,4117
24
- dbt_bouncer/config_file_parser.py,sha256=gq7fINTmLFVWR4todXkPd_dnh0-9vnM3jHYtgk1g_WU,4874
24
+ dbt_bouncer/config_file_parser.py,sha256=JjFoPhFARgPB_q8BnjRp9C9E5FhO1mcBWrDYEyeOfc4,5009
25
25
  dbt_bouncer/config_file_validator.py,sha256=wB241_aV0HTX_NLLfdD2snI831MsRIWdO5Y2lRdx7Ug,11256
26
26
  dbt_bouncer/logger.py,sha256=qkwB-SVUE4YUUp-MtmbcDPUX7t3zdniQL5Linuomr94,1804
27
27
  dbt_bouncer/main.py,sha256=n-jOsKlDwAlB2uF__J_DtkU8BC7CqeKMOU_f8axB1fo,6433
28
28
  dbt_bouncer/runner.py,sha256=fdgpOUS8ckS_rZbklOUqFSxmD6I8WYRhQU09HZI0Ghs,10628
29
29
  dbt_bouncer/utils.py,sha256=-jZjc6R0tjHWqpTjgHIb7Ej6Cqwdbchbl7L8IB4mo1I,9890
30
- dbt_bouncer/version.py,sha256=T6qaKJ5jDdQcME1sfophY-dqPLnCjO2lXd6l-yLY1UA,149
31
- dbt_bouncer-1.29.0.dist-info/LICENSE,sha256=gGXp4VL__ZWlTWhXHRjWJmkxl5X9UJ7L7n1dr2WlfsY,1074
32
- dbt_bouncer-1.29.0.dist-info/METADATA,sha256=T1O24rYH597lJNTxlMnV1zegkZoJFoxEdDT8eJRNO9Q,4606
33
- dbt_bouncer-1.29.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
34
- dbt_bouncer-1.29.0.dist-info/entry_points.txt,sha256=jEl2FZDm4gO8u4x9m8qS0zMf9Fk2FAwLfI4N4sreGxI,52
35
- dbt_bouncer-1.29.0.dist-info/RECORD,,
30
+ dbt_bouncer/version.py,sha256=peiKdfhYuV1tr1aFIP2HBNzq0JXTP49RcFqmcJrN-pY,149
31
+ dbt_bouncer-1.30.0.dist-info/LICENSE,sha256=gGXp4VL__ZWlTWhXHRjWJmkxl5X9UJ7L7n1dr2WlfsY,1074
32
+ dbt_bouncer-1.30.0.dist-info/METADATA,sha256=hLea625CoInl_srhE31N6XADFivQPGSQMLbIEeTV-uQ,4606
33
+ dbt_bouncer-1.30.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
34
+ dbt_bouncer-1.30.0.dist-info/entry_points.txt,sha256=jEl2FZDm4gO8u4x9m8qS0zMf9Fk2FAwLfI4N4sreGxI,52
35
+ dbt_bouncer-1.30.0.dist-info/RECORD,,