recce-nightly 0.62.0.20250417__py3-none-any.whl → 1.30.0.20251221__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.
Potentially problematic release.
This version of recce-nightly might be problematic. Click here for more details.
- recce/VERSION +1 -1
- recce/__init__.py +27 -22
- recce/adapter/base.py +11 -14
- recce/adapter/dbt_adapter/__init__.py +845 -461
- recce/adapter/dbt_adapter/dbt_version.py +3 -0
- recce/adapter/sqlmesh_adapter.py +24 -35
- recce/apis/check_api.py +59 -42
- recce/apis/check_events_api.py +353 -0
- recce/apis/check_func.py +41 -35
- recce/apis/run_api.py +25 -19
- recce/apis/run_func.py +64 -25
- recce/artifact.py +119 -51
- recce/cli.py +1301 -324
- recce/config.py +43 -34
- recce/connect_to_cloud.py +138 -0
- recce/core.py +55 -47
- recce/data/404/index.html +2 -0
- recce/data/404.html +2 -1
- recce/data/__next.@lineage.!KHNsb3Qp.__PAGE__.txt +7 -0
- recce/data/__next.@lineage.!KHNsb3Qp.txt +4 -0
- recce/data/__next.__PAGE__.txt +6 -0
- recce/data/__next._full.txt +32 -0
- recce/data/__next._head.txt +8 -0
- recce/data/__next._index.txt +14 -0
- recce/data/__next._tree.txt +8 -0
- recce/data/_next/static/chunks/025a7e3e3f9f40ae.js +1 -0
- recce/data/_next/static/chunks/0ce56d67ef5779ca.js +4 -0
- recce/data/_next/static/chunks/1a6a78780155dac7.js +48 -0
- recce/data/_next/static/chunks/1de8485918b9182a.css +2 -0
- recce/data/_next/static/chunks/1e4b1b50d1e34993.js +1 -0
- recce/data/_next/static/chunks/206d5d181e4c738e.js +1 -0
- recce/data/_next/static/chunks/2c357efc34c5b859.js +25 -0
- recce/data/_next/static/chunks/2e9d95d2d48c479c.js +1 -0
- recce/data/_next/static/chunks/2f016dc4a3edad2e.js +2 -0
- recce/data/_next/static/chunks/313251962d698f7c.js +1 -0
- recce/data/_next/static/chunks/3a9f021f38eb5574.css +1 -0
- recce/data/_next/static/chunks/40079da8d2b8f651.js +1 -0
- recce/data/_next/static/chunks/4599182bffb64661.js +38 -0
- recce/data/_next/static/chunks/4e62f6e184173580.js +1 -0
- recce/data/_next/static/chunks/5c4dfb0d09eaa401.js +1 -0
- recce/data/_next/static/chunks/69e4f06ccfdfc3ac.js +1 -0
- recce/data/_next/static/chunks/6b206cb4707d6bee.js +1 -0
- recce/data/_next/static/chunks/6d8557f062aa4386.css +1 -0
- recce/data/_next/static/chunks/7fbe3650bd83b6b5.js +1 -0
- recce/data/_next/static/chunks/83fa823a825674f6.js +1 -0
- recce/data/_next/static/chunks/848a6c9b5f55f7ed.js +1 -0
- recce/data/_next/static/chunks/859462b0858aef88.css +2 -0
- recce/data/_next/static/chunks/923964f18c87d0f1.css +1 -0
- recce/data/_next/static/chunks/939390f911895d7c.js +48 -0
- recce/data/_next/static/chunks/99a9817237a07f43.js +1 -0
- recce/data/_next/static/chunks/9fed8b4b2b924054.js +5 -0
- recce/data/_next/static/chunks/b6949f6c5892110c.js +1 -0
- recce/data/_next/static/chunks/b851a1d3f8149828.js +1 -0
- recce/data/_next/static/chunks/c734f9ad957de0b4.js +1 -0
- recce/data/_next/static/chunks/cdde321b0ec75717.js +2 -0
- recce/data/_next/static/chunks/d0f91117d77ff844.css +1 -0
- recce/data/_next/static/chunks/d6c8667911c2500f.js +1 -0
- recce/data/_next/static/chunks/da8dab68c02752cf.js +74 -0
- recce/data/_next/static/chunks/dc074049c9d12d97.js +109 -0
- recce/data/_next/static/chunks/ee7f1a8227342421.js +1 -0
- recce/data/_next/static/chunks/fa2f4e56c2fccc73.js +1 -0
- recce/data/_next/static/chunks/turbopack-1fad664f62979b93.js +3 -0
- recce/data/_next/static/media/favicon.a8d38d84.ico +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.d80d830d.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.f9d58125.woff +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.076c2a93.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.a4fa76b5.woff +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.cde454cc.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.d5761935.woff +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.40ec0659.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.b671449b.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.9f7b8541.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.f9eb854e.woff2 +0 -0
- recce/data/_next/static/nX-Uz0AH6Tc6hIQUFGqaB/_buildManifest.js +11 -0
- recce/data/_next/static/nX-Uz0AH6Tc6hIQUFGqaB/_clientMiddlewareManifest.json +1 -0
- recce/data/_not-found/__next._full.txt +24 -0
- recce/data/_not-found/__next._head.txt +8 -0
- recce/data/_not-found/__next._index.txt +13 -0
- recce/data/_not-found/__next._not-found.__PAGE__.txt +5 -0
- recce/data/_not-found/__next._not-found.txt +4 -0
- recce/data/_not-found/__next._tree.txt +6 -0
- recce/data/_not-found/index.html +2 -0
- recce/data/_not-found/index.txt +24 -0
- recce/data/auth_callback.html +68 -0
- recce/data/checks/__next.@lineage.__DEFAULT__.txt +7 -0
- recce/data/checks/__next._full.txt +39 -0
- recce/data/checks/__next._head.txt +8 -0
- recce/data/checks/__next._index.txt +14 -0
- recce/data/checks/__next._tree.txt +8 -0
- recce/data/checks/__next.checks.__PAGE__.txt +10 -0
- recce/data/checks/__next.checks.txt +4 -0
- recce/data/checks/index.html +2 -0
- recce/data/checks/index.txt +39 -0
- recce/data/imgs/reload-image.svg +4 -0
- recce/data/index.html +2 -27
- recce/data/index.txt +32 -7
- recce/data/lineage/__next.@lineage.__DEFAULT__.txt +7 -0
- recce/data/lineage/__next._full.txt +39 -0
- recce/data/lineage/__next._head.txt +8 -0
- recce/data/lineage/__next._index.txt +14 -0
- recce/data/lineage/__next._tree.txt +8 -0
- recce/data/lineage/__next.lineage.__PAGE__.txt +10 -0
- recce/data/lineage/__next.lineage.txt +4 -0
- recce/data/lineage/index.html +2 -0
- recce/data/lineage/index.txt +39 -0
- recce/data/query/__next.@lineage.__DEFAULT__.txt +7 -0
- recce/data/query/__next._full.txt +37 -0
- recce/data/query/__next._head.txt +8 -0
- recce/data/query/__next._index.txt +14 -0
- recce/data/query/__next._tree.txt +8 -0
- recce/data/query/__next.query.__PAGE__.txt +9 -0
- recce/data/query/__next.query.txt +4 -0
- recce/data/query/index.html +2 -0
- recce/data/query/index.txt +37 -0
- recce/diff.py +6 -12
- recce/event/CONFIG.bak +1 -0
- recce/event/__init__.py +86 -74
- recce/event/collector.py +33 -22
- recce/event/track.py +49 -27
- recce/exceptions.py +1 -1
- recce/git.py +7 -7
- recce/github.py +57 -53
- recce/mcp_server.py +725 -0
- recce/models/__init__.py +4 -1
- recce/models/check.py +438 -21
- recce/models/run.py +1 -0
- recce/models/types.py +134 -28
- recce/pull_request.py +27 -25
- recce/run.py +179 -122
- recce/server.py +394 -104
- recce/state/__init__.py +31 -0
- recce/state/cloud.py +644 -0
- recce/state/const.py +26 -0
- recce/state/local.py +56 -0
- recce/state/state.py +119 -0
- recce/state/state_loader.py +174 -0
- recce/summary.py +196 -149
- recce/tasks/__init__.py +19 -3
- recce/tasks/core.py +11 -13
- recce/tasks/dataframe.py +82 -18
- recce/tasks/histogram.py +69 -34
- recce/tasks/lineage.py +2 -2
- recce/tasks/profile.py +152 -86
- recce/tasks/query.py +180 -89
- recce/tasks/rowcount.py +37 -31
- recce/tasks/schema.py +18 -15
- recce/tasks/top_k.py +35 -35
- recce/tasks/utils.py +147 -0
- recce/tasks/valuediff.py +247 -155
- recce/util/__init__.py +3 -0
- recce/util/api_token.py +80 -0
- recce/util/breaking.py +105 -100
- recce/util/cll.py +274 -219
- recce/util/cloud/__init__.py +15 -0
- recce/util/cloud/base.py +115 -0
- recce/util/cloud/check_events.py +190 -0
- recce/util/cloud/checks.py +242 -0
- recce/util/io.py +22 -17
- recce/util/lineage.py +65 -16
- recce/util/logger.py +1 -1
- recce/util/onboarding_state.py +45 -0
- recce/util/perf_tracking.py +85 -0
- recce/util/recce_cloud.py +347 -72
- recce/util/singleton.py +4 -4
- recce/util/startup_perf.py +121 -0
- recce/yaml/__init__.py +7 -10
- recce_nightly-1.30.0.20251221.dist-info/METADATA +195 -0
- recce_nightly-1.30.0.20251221.dist-info/RECORD +183 -0
- {recce_nightly-0.62.0.20250417.dist-info → recce_nightly-1.30.0.20251221.dist-info}/WHEEL +1 -2
- recce/data/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js +0 -1
- recce/data/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js +0 -1
- recce/data/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js +0 -1
- recce/data/_next/static/chunks/3998a672-eaad84bdd88cc73e.js +0 -1
- recce/data/_next/static/chunks/450c323b-1bb5db526e54435a.js +0 -1
- recce/data/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js +0 -1
- recce/data/_next/static/chunks/500-e51c92a025a51234.js +0 -65
- recce/data/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js +0 -1
- recce/data/_next/static/chunks/700-3b65fc3666820d00.js +0 -2
- recce/data/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js +0 -1
- recce/data/_next/static/chunks/7f27ae6c-413f6b869a04183a.js +0 -1
- recce/data/_next/static/chunks/9746af58-d74bef4d03eea6ab.js +0 -1
- recce/data/_next/static/chunks/a30376cd-7d806e1602f2dc3a.js +0 -1
- recce/data/_next/static/chunks/app/_not-found/page-8a886fa0855c3105.js +0 -1
- recce/data/_next/static/chunks/app/layout-9102e22cb73f74d6.js +0 -1
- recce/data/_next/static/chunks/app/page-9adc25782272ed2e.js +0 -1
- recce/data/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js +0 -1
- recce/data/_next/static/chunks/c132bf7d-8102037f9ccf372a.js +0 -1
- recce/data/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js +0 -1
- recce/data/_next/static/chunks/cd9f8d63-cf0d5a7b0f7a92e8.js +0 -54
- recce/data/_next/static/chunks/ce84277d-f42c2c58049cea2d.js +0 -1
- recce/data/_next/static/chunks/e24bf851-0f8cbc99656833e7.js +0 -1
- recce/data/_next/static/chunks/fee69bc6-f17d36c080742e74.js +0 -1
- recce/data/_next/static/chunks/framework-ded83d71b51ce901.js +0 -1
- recce/data/_next/static/chunks/main-a0859f1f36d0aa6c.js +0 -1
- recce/data/_next/static/chunks/main-app-0225a2255968e566.js +0 -1
- recce/data/_next/static/chunks/pages/_app-d5672bf3d8b6371b.js +0 -1
- recce/data/_next/static/chunks/pages/_error-ed75be3f25588548.js +0 -1
- recce/data/_next/static/chunks/webpack-567d72f0bc0820d5.js +0 -1
- recce/data/_next/static/css/c9ecb46a4b21c126.css +0 -14
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.94a63aea.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.6f8fa298.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.97e20d5e.woff +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.aff52ab0.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.5f21869b.woff +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2 +0 -0
- recce/data/_next/static/qiyFlux77VkhxiceAJe_F/_buildManifest.js +0 -1
- recce/state.py +0 -753
- recce_nightly-0.62.0.20250417.dist-info/METADATA +0 -311
- recce_nightly-0.62.0.20250417.dist-info/RECORD +0 -139
- recce_nightly-0.62.0.20250417.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- tests/adapter/__init__.py +0 -0
- tests/adapter/dbt_adapter/__init__.py +0 -0
- tests/adapter/dbt_adapter/conftest.py +0 -13
- tests/adapter/dbt_adapter/dbt_test_helper.py +0 -283
- tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -40
- tests/adapter/dbt_adapter/test_dbt_cll.py +0 -102
- tests/adapter/dbt_adapter/test_selector.py +0 -177
- tests/tasks/__init__.py +0 -0
- tests/tasks/conftest.py +0 -4
- tests/tasks/test_histogram.py +0 -137
- tests/tasks/test_lineage.py +0 -42
- tests/tasks/test_preset_checks.py +0 -50
- tests/tasks/test_profile.py +0 -73
- tests/tasks/test_query.py +0 -151
- tests/tasks/test_row_count.py +0 -116
- tests/tasks/test_schema.py +0 -99
- tests/tasks/test_top_k.py +0 -73
- tests/tasks/test_valuediff.py +0 -74
- tests/test_cli.py +0 -122
- tests/test_config.py +0 -45
- tests/test_core.py +0 -27
- tests/test_dbt.py +0 -36
- tests/test_pull_request.py +0 -130
- tests/test_server.py +0 -98
- tests/test_state.py +0 -123
- tests/test_summary.py +0 -57
- /recce/data/_next/static/chunks/{polyfills-42372ed130431b0a.js → a6dad97d9634a72d.js} +0 -0
- /recce/data/_next/static/{qiyFlux77VkhxiceAJe_F → nX-Uz0AH6Tc6hIQUFGqaB}/_ssgManifest.js +0 -0
- {recce_nightly-0.62.0.20250417.dist-info → recce_nightly-1.30.0.20251221.dist-info}/entry_points.txt +0 -0
- {recce_nightly-0.62.0.20250417.dist-info → recce_nightly-1.30.0.20251221.dist-info}/licenses/LICENSE +0 -0
recce/models/types.py
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
from datetime import datetime, timezone
|
|
3
3
|
from enum import Enum
|
|
4
|
-
from typing import Optional,
|
|
4
|
+
from typing import Dict, List, Literal, Optional, Set
|
|
5
5
|
|
|
6
|
-
from pydantic import
|
|
6
|
+
from pydantic import UUID4, BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from recce.util.pydantic_model import pydantic_model_dump
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class RunType(Enum):
|
|
10
|
-
SIMPLE =
|
|
12
|
+
SIMPLE = "simple"
|
|
11
13
|
QUERY = "query"
|
|
12
|
-
QUERY_BASE =
|
|
13
|
-
QUERY_DIFF =
|
|
14
|
-
VALUE_DIFF =
|
|
15
|
-
VALUE_DIFF_DETAIL =
|
|
16
|
-
SCHEMA_DIFF =
|
|
17
|
-
PROFILE =
|
|
18
|
-
PROFILE_DIFF =
|
|
19
|
-
ROW_COUNT =
|
|
20
|
-
ROW_COUNT_DIFF =
|
|
21
|
-
LINEAGE_DIFF =
|
|
22
|
-
TOP_K_DIFF =
|
|
23
|
-
HISTOGRAM_DIFF =
|
|
14
|
+
QUERY_BASE = "query_base"
|
|
15
|
+
QUERY_DIFF = "query_diff"
|
|
16
|
+
VALUE_DIFF = "value_diff"
|
|
17
|
+
VALUE_DIFF_DETAIL = "value_diff_detail"
|
|
18
|
+
SCHEMA_DIFF = "schema_diff"
|
|
19
|
+
PROFILE = "profile"
|
|
20
|
+
PROFILE_DIFF = "profile_diff"
|
|
21
|
+
ROW_COUNT = "row_count"
|
|
22
|
+
ROW_COUNT_DIFF = "row_count_diff"
|
|
23
|
+
LINEAGE_DIFF = "lineage_diff"
|
|
24
|
+
TOP_K_DIFF = "top_k_diff"
|
|
25
|
+
HISTOGRAM_DIFF = "histogram_diff"
|
|
24
26
|
|
|
25
27
|
def __str__(self):
|
|
26
28
|
return self.value
|
|
@@ -32,12 +34,10 @@ class RunProgress(BaseModel):
|
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
class RunStatus(Enum):
|
|
35
|
-
FINISHED =
|
|
36
|
-
FAILED =
|
|
37
|
-
CANCELLED =
|
|
38
|
-
RUNNING =
|
|
39
|
-
# This is a special status only in v0.36.0. Replaced by FINISHED. To be removed in the future.
|
|
40
|
-
SUCCESSFUL = 'successful'
|
|
37
|
+
FINISHED = "finished"
|
|
38
|
+
FAILED = "failed"
|
|
39
|
+
CANCELLED = "cancelled"
|
|
40
|
+
RUNNING = "running"
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
class Run(BaseModel):
|
|
@@ -52,6 +52,39 @@ class Run(BaseModel):
|
|
|
52
52
|
run_id: UUID4 = Field(default_factory=uuid.uuid4)
|
|
53
53
|
run_at: str = Field(default_factory=lambda: datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"))
|
|
54
54
|
|
|
55
|
+
def __init__(self, **data):
|
|
56
|
+
type = data.get("type")
|
|
57
|
+
|
|
58
|
+
if "result" in data and data["result"] is not None:
|
|
59
|
+
result = data.get("result")
|
|
60
|
+
|
|
61
|
+
if type in [RunType.QUERY.value, RunType.QUERY_BASE.value]:
|
|
62
|
+
from recce.tasks.query import QueryResult
|
|
63
|
+
|
|
64
|
+
data["result"] = pydantic_model_dump(QueryResult(**result))
|
|
65
|
+
elif type == RunType.QUERY_DIFF.value:
|
|
66
|
+
from recce.tasks.query import QueryDiffResult
|
|
67
|
+
|
|
68
|
+
data["result"] = pydantic_model_dump(QueryDiffResult(**result))
|
|
69
|
+
elif type == RunType.PROFILE.value:
|
|
70
|
+
from recce.tasks.profile import ProfileResult
|
|
71
|
+
|
|
72
|
+
data["result"] = pydantic_model_dump(ProfileResult(**result))
|
|
73
|
+
elif type == RunType.PROFILE_DIFF.value:
|
|
74
|
+
from recce.tasks.profile import ProfileDiffResult
|
|
75
|
+
|
|
76
|
+
data["result"] = pydantic_model_dump(ProfileDiffResult(**result))
|
|
77
|
+
elif type == RunType.VALUE_DIFF.value:
|
|
78
|
+
from recce.tasks.valuediff import ValueDiffResult
|
|
79
|
+
|
|
80
|
+
data["result"] = pydantic_model_dump(ValueDiffResult(**result))
|
|
81
|
+
elif type == RunType.VALUE_DIFF_DETAIL.value:
|
|
82
|
+
from recce.tasks.valuediff import ValueDiffDetailResult
|
|
83
|
+
|
|
84
|
+
data["result"] = pydantic_model_dump(ValueDiffDetailResult(**result))
|
|
85
|
+
|
|
86
|
+
super().__init__(**data)
|
|
87
|
+
|
|
55
88
|
|
|
56
89
|
class Check(BaseModel):
|
|
57
90
|
name: str
|
|
@@ -60,8 +93,11 @@ class Check(BaseModel):
|
|
|
60
93
|
params: Optional[dict] = {}
|
|
61
94
|
view_options: Optional[dict] = {}
|
|
62
95
|
check_id: UUID4 = Field(default_factory=uuid.uuid4)
|
|
96
|
+
session_id: Optional[UUID4] = Field(default=None)
|
|
63
97
|
is_checked: bool = False
|
|
64
98
|
is_preset: bool = False
|
|
99
|
+
created_by: Optional[str] = None
|
|
100
|
+
updated_by: Optional[str] = None
|
|
65
101
|
created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc).replace(microsecond=0))
|
|
66
102
|
updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc).replace(microsecond=0))
|
|
67
103
|
|
|
@@ -84,15 +120,15 @@ class Check(BaseModel):
|
|
|
84
120
|
|
|
85
121
|
|
|
86
122
|
ChangeStatus = Literal[
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
123
|
+
"added",
|
|
124
|
+
"removed",
|
|
125
|
+
"modified",
|
|
90
126
|
]
|
|
91
127
|
ChangeCategory = Literal[
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
128
|
+
"breaking",
|
|
129
|
+
"non_breaking",
|
|
130
|
+
"partial_breaking",
|
|
131
|
+
"unknown",
|
|
96
132
|
]
|
|
97
133
|
|
|
98
134
|
|
|
@@ -110,3 +146,73 @@ class LineageDiff(BaseModel):
|
|
|
110
146
|
base: dict
|
|
111
147
|
current: dict
|
|
112
148
|
diff: dict[str, NodeDiff]
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# Column Level Linage
|
|
152
|
+
class CllColumnDep(BaseModel):
|
|
153
|
+
node: str
|
|
154
|
+
column: str
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class CllColumn(BaseModel):
|
|
158
|
+
id: Optional[str] = None
|
|
159
|
+
table_id: Optional[str] = None
|
|
160
|
+
name: Optional[str] = None
|
|
161
|
+
|
|
162
|
+
# data type
|
|
163
|
+
type: Optional[str] = None
|
|
164
|
+
|
|
165
|
+
# transformation type
|
|
166
|
+
transformation_type: Literal["source", "passthrough", "renamed", "derived", "unknown"] = "unknown"
|
|
167
|
+
|
|
168
|
+
# change analysis
|
|
169
|
+
change_status: Optional[ChangeStatus] = None
|
|
170
|
+
|
|
171
|
+
# column-to-column dependencies
|
|
172
|
+
depends_on: List[CllColumnDep] = Field(default_factory=list)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class CllNode(BaseModel):
|
|
176
|
+
id: str
|
|
177
|
+
name: str
|
|
178
|
+
package_name: str
|
|
179
|
+
resource_type: str
|
|
180
|
+
raw_code: Optional[str] = None
|
|
181
|
+
source_name: Optional[str] = None
|
|
182
|
+
|
|
183
|
+
# change analysis
|
|
184
|
+
change_status: Optional[ChangeStatus] = None
|
|
185
|
+
change_category: Optional[ChangeCategory] = None
|
|
186
|
+
|
|
187
|
+
# Column to column dependencies
|
|
188
|
+
columns: Dict[str, CllColumn] = Field(default_factory=dict)
|
|
189
|
+
|
|
190
|
+
# If the node is impacted. Only used if option 'change_analysis' is set
|
|
191
|
+
impacted: Optional[bool] = None
|
|
192
|
+
|
|
193
|
+
@classmethod
|
|
194
|
+
def build_cll_node(cls, manifest, resource_key, node_id) -> Optional["CllNode"]:
|
|
195
|
+
resources = getattr(manifest, resource_key)
|
|
196
|
+
if node_id not in resources:
|
|
197
|
+
return None
|
|
198
|
+
n = resources[node_id]
|
|
199
|
+
if resource_key == "nodes" and n.resource_type not in ["model", "seed", "snapshot"]:
|
|
200
|
+
return None
|
|
201
|
+
cll_node = CllNode(
|
|
202
|
+
id=n.unique_id,
|
|
203
|
+
name=n.name,
|
|
204
|
+
package_name=n.package_name,
|
|
205
|
+
resource_type=n.resource_type,
|
|
206
|
+
)
|
|
207
|
+
if resource_key == "sources":
|
|
208
|
+
cll_node.source_name = n.source_name
|
|
209
|
+
elif resource_key == "nodes":
|
|
210
|
+
cll_node.raw_code = n.raw_code
|
|
211
|
+
return cll_node
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class CllData(BaseModel):
|
|
215
|
+
nodes: Dict[str, CllNode] = Field(default_factory=dict)
|
|
216
|
+
columns: Dict[str, CllColumn] = Field(default_factory=dict)
|
|
217
|
+
parent_map: Dict[str, Set[str]] = Field(default_factory=dict)
|
|
218
|
+
child_map: Dict[str, Set[str]] = Field(default_factory=dict)
|
recce/pull_request.py
CHANGED
|
@@ -28,14 +28,14 @@ def fetch_pr_metadata(**kwargs):
|
|
|
28
28
|
# fetch from github action event path
|
|
29
29
|
metadata = fetch_pr_metadata_from_event_path()
|
|
30
30
|
if metadata is not None:
|
|
31
|
-
pr_info.id = metadata.get(
|
|
32
|
-
pr_info.url = metadata.get(
|
|
33
|
-
pr_info.title = metadata.get(
|
|
34
|
-
pr_info.repository = metadata.get(
|
|
31
|
+
pr_info.id = metadata.get("github_pr_id")
|
|
32
|
+
pr_info.url = metadata.get("github_pr_url")
|
|
33
|
+
pr_info.title = metadata.get("github_pr_title")
|
|
34
|
+
pr_info.repository = metadata.get("github_repository")
|
|
35
35
|
else:
|
|
36
36
|
repo = hosting_repo()
|
|
37
|
-
pr, message = recce_pr_information(github_token=kwargs.get(
|
|
38
|
-
if kwargs.get(
|
|
37
|
+
pr, message = recce_pr_information(github_token=kwargs.get("github_token"))
|
|
38
|
+
if kwargs.get("cloud") and message:
|
|
39
39
|
print(message)
|
|
40
40
|
|
|
41
41
|
if pr:
|
|
@@ -47,14 +47,14 @@ def fetch_pr_metadata(**kwargs):
|
|
|
47
47
|
pr_info.branch = pr.head.ref
|
|
48
48
|
|
|
49
49
|
# fetch from cli arguments
|
|
50
|
-
if pr_info.url is None and
|
|
51
|
-
pr_info.url = kwargs.get(
|
|
50
|
+
if pr_info.url is None and "github_pull_request_url" in kwargs:
|
|
51
|
+
pr_info.url = kwargs.get("github_pull_request_url")
|
|
52
52
|
|
|
53
53
|
if pr_info.branch is None:
|
|
54
|
-
pr_info.branch = kwargs.get(
|
|
54
|
+
pr_info.branch = kwargs.get("git_current_branch")
|
|
55
55
|
|
|
56
56
|
if pr_info.base_branch is None:
|
|
57
|
-
pr_info.base_branch = kwargs.get(
|
|
57
|
+
pr_info.base_branch = kwargs.get("git_base_branch")
|
|
58
58
|
|
|
59
59
|
# fetch from env
|
|
60
60
|
if pr_info.url is None:
|
|
@@ -65,17 +65,17 @@ def fetch_pr_metadata(**kwargs):
|
|
|
65
65
|
|
|
66
66
|
def fetch_pr_metadata_from_event_path() -> Optional[dict]:
|
|
67
67
|
"""
|
|
68
|
-
|
|
68
|
+
If recce run is running in a GitHub Action, this function will return the pull request metadata.
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
Example:
|
|
71
|
+
{
|
|
72
|
+
"github_pr_id": 1,
|
|
73
|
+
"github_pr_url": "https://github.com/xyz/abc/pull/1,
|
|
74
|
+
"github_pr_title": "Update README.md",
|
|
75
|
+
"github_repository": "xyz/abc"
|
|
76
|
+
}
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
:return: dict
|
|
79
79
|
"""
|
|
80
80
|
|
|
81
81
|
# get the event json from the path in GITHUB_EVENT_PATH
|
|
@@ -83,7 +83,7 @@ def fetch_pr_metadata_from_event_path() -> Optional[dict]:
|
|
|
83
83
|
github_repository = os.getenv("GITHUB_REPOSITORY")
|
|
84
84
|
if event_path:
|
|
85
85
|
try:
|
|
86
|
-
with open(event_path, "r") as event_file:
|
|
86
|
+
with open(event_path, "r", encoding="utf-8") as event_file:
|
|
87
87
|
event_data = json.load(event_file)
|
|
88
88
|
|
|
89
89
|
pr_id = event_data["number"]
|
|
@@ -92,10 +92,12 @@ def fetch_pr_metadata_from_event_path() -> Optional[dict]:
|
|
|
92
92
|
pr_url = pull_request_data["_links"]["html"]["href"]
|
|
93
93
|
pr_api = pull_request_data["_links"]["self"]["href"]
|
|
94
94
|
pr_title = _fetch_pr_title(pr_api)
|
|
95
|
-
return dict(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
return dict(
|
|
96
|
+
github_pr_id=pr_id,
|
|
97
|
+
github_pr_url=pr_url,
|
|
98
|
+
github_pr_title=pr_title,
|
|
99
|
+
github_repository=github_repository,
|
|
100
|
+
)
|
|
99
101
|
else:
|
|
100
102
|
print("Not a pull request event, skip.")
|
|
101
103
|
except Exception as e:
|
|
@@ -115,7 +117,7 @@ def _fetch_pr_title(endpoint) -> Optional[str]:
|
|
|
115
117
|
|
|
116
118
|
if response.status_code == 200:
|
|
117
119
|
pull_request_data = response.json()
|
|
118
|
-
return pull_request_data.get(
|
|
120
|
+
return pull_request_data.get("title")
|
|
119
121
|
except Exception as e:
|
|
120
122
|
print("Cannot fetch PR title: ", e)
|
|
121
123
|
|