recce-nightly 1.3.0.20250507__py3-none-any.whl → 1.4.0.20250515__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.

Files changed (93) hide show
  1. recce/VERSION +1 -1
  2. recce/__init__.py +22 -22
  3. recce/adapter/base.py +11 -14
  4. recce/adapter/dbt_adapter/__init__.py +355 -316
  5. recce/adapter/dbt_adapter/dbt_version.py +3 -0
  6. recce/adapter/sqlmesh_adapter.py +24 -35
  7. recce/apis/check_api.py +39 -28
  8. recce/apis/check_func.py +33 -27
  9. recce/apis/run_api.py +25 -19
  10. recce/apis/run_func.py +29 -23
  11. recce/artifact.py +44 -49
  12. recce/cli.py +484 -285
  13. recce/config.py +42 -33
  14. recce/core.py +52 -44
  15. recce/data/404.html +1 -1
  16. recce/data/_next/static/chunks/{368-7587b306577df275.js → 778-aef312bffb4c0312.js} +15 -15
  17. recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js +1 -0
  18. recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js +1 -0
  19. recce/data/_next/static/chunks/app/page-7086764277331fcb.js +1 -0
  20. recce/data/_next/static/chunks/{cd9f8d63-cf0d5a7b0f7a92e8.js → cd9f8d63-e020f408095ed77c.js} +3 -3
  21. recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js +1 -0
  22. recce/data/_next/static/css/88b8abc134cfd59a.css +3 -0
  23. recce/data/index.html +2 -2
  24. recce/data/index.txt +2 -2
  25. recce/diff.py +6 -12
  26. recce/event/__init__.py +74 -72
  27. recce/event/collector.py +27 -20
  28. recce/event/track.py +39 -27
  29. recce/exceptions.py +1 -1
  30. recce/git.py +7 -7
  31. recce/github.py +57 -53
  32. recce/models/__init__.py +1 -1
  33. recce/models/check.py +6 -7
  34. recce/models/run.py +1 -0
  35. recce/models/types.py +27 -27
  36. recce/pull_request.py +26 -24
  37. recce/run.py +148 -111
  38. recce/server.py +103 -89
  39. recce/state.py +209 -177
  40. recce/summary.py +168 -143
  41. recce/tasks/__init__.py +3 -3
  42. recce/tasks/core.py +11 -13
  43. recce/tasks/dataframe.py +19 -17
  44. recce/tasks/histogram.py +69 -34
  45. recce/tasks/lineage.py +2 -2
  46. recce/tasks/profile.py +147 -86
  47. recce/tasks/query.py +139 -87
  48. recce/tasks/rowcount.py +33 -30
  49. recce/tasks/schema.py +14 -14
  50. recce/tasks/top_k.py +35 -35
  51. recce/tasks/valuediff.py +216 -152
  52. recce/util/breaking.py +77 -84
  53. recce/util/cll.py +55 -51
  54. recce/util/io.py +19 -17
  55. recce/util/logger.py +1 -1
  56. recce/util/recce_cloud.py +70 -72
  57. recce/util/singleton.py +4 -4
  58. recce/yaml/__init__.py +7 -10
  59. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/METADATA +5 -2
  60. recce_nightly-1.4.0.20250515.dist-info/RECORD +143 -0
  61. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/WHEEL +1 -1
  62. tests/adapter/dbt_adapter/conftest.py +1 -0
  63. tests/adapter/dbt_adapter/dbt_test_helper.py +28 -18
  64. tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -15
  65. tests/adapter/dbt_adapter/test_dbt_cll.py +39 -32
  66. tests/adapter/dbt_adapter/test_selector.py +22 -21
  67. tests/tasks/test_histogram.py +58 -66
  68. tests/tasks/test_lineage.py +36 -23
  69. tests/tasks/test_preset_checks.py +45 -31
  70. tests/tasks/test_profile.py +340 -15
  71. tests/tasks/test_query.py +40 -40
  72. tests/tasks/test_row_count.py +65 -46
  73. tests/tasks/test_schema.py +65 -42
  74. tests/tasks/test_top_k.py +22 -18
  75. tests/tasks/test_valuediff.py +43 -32
  76. tests/test_cli.py +71 -58
  77. tests/test_config.py +7 -9
  78. tests/test_core.py +5 -3
  79. tests/test_dbt.py +7 -7
  80. tests/test_pull_request.py +1 -1
  81. tests/test_server.py +19 -13
  82. tests/test_state.py +40 -27
  83. tests/test_summary.py +18 -14
  84. recce/data/_next/static/chunks/8d700b6a-f0b1f6b9e0d97ce2.js +0 -1
  85. recce/data/_next/static/chunks/app/layout-9102e22cb73f74d6.js +0 -1
  86. recce/data/_next/static/chunks/app/page-92f13c8fad9fae3d.js +0 -1
  87. recce/data/_next/static/chunks/webpack-567d72f0bc0820d5.js +0 -1
  88. recce_nightly-1.3.0.20250507.dist-info/RECORD +0 -142
  89. /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → q0Xsc9Sd6PDuo1lshYpLu}/_buildManifest.js +0 -0
  90. /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → q0Xsc9Sd6PDuo1lshYpLu}/_ssgManifest.js +0 -0
  91. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/entry_points.txt +0 -0
  92. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/licenses/LICENSE +0 -0
  93. {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250515.dist-info}/top_level.txt +0 -0
recce/git.py CHANGED
@@ -1,12 +1,12 @@
1
1
  import os
2
2
 
3
- from git import Repo, InvalidGitRepositoryError
3
+ from git import InvalidGitRepositoryError, Repo
4
4
 
5
5
 
6
6
  def current_default_branch():
7
7
  try:
8
8
  repo = Repo(search_parent_directories=True)
9
- return repo.remotes.origin.refs['HEAD'].reference.remote_head
9
+ return repo.remotes.origin.refs["HEAD"].reference.remote_head
10
10
  except Exception:
11
11
  return None
12
12
 
@@ -53,19 +53,19 @@ def commit_hash_from_branch(branch: str, short_length: int = 7, short: bool = Fa
53
53
  return None
54
54
 
55
55
 
56
- def hosting_repo(remote: str = 'origin'):
56
+ def hosting_repo(remote: str = "origin"):
57
57
  try:
58
58
  repo = Repo(search_parent_directories=True)
59
59
  origin_url = repo.remote(name=remote).url
60
60
  remote_repo = None
61
61
 
62
- if origin_url.startswith('git@'):
62
+ if origin_url.startswith("git@"):
63
63
  # Handle git@github.com:user/repo.git
64
- remote_repo = origin_url.split(':')[1].replace('.git', '')
64
+ remote_repo = origin_url.split(":")[1].replace(".git", "")
65
65
 
66
- elif origin_url.startswith('https://') or origin_url.startswith('http://'):
66
+ elif origin_url.startswith("https://") or origin_url.startswith("http://"):
67
67
  # Handle https://github.com/user/repo.git or http://github.com/user/repo.git
68
- remote_repo = '/'.join(origin_url.split('/')[-2:]).replace('.git', '')
68
+ remote_repo = "/".join(origin_url.split("/")[-2:]).replace(".git", "")
69
69
 
70
70
  return remote_repo
71
71
  except ValueError:
recce/github.py CHANGED
@@ -3,10 +3,10 @@ import os
3
3
  import re
4
4
  import zipfile
5
5
  from datetime import datetime
6
- from typing import List, Tuple, Optional
6
+ from typing import List, Optional, Tuple
7
7
 
8
8
  import requests
9
- from github import Artifact, Github, Auth, UnknownObjectException, PullRequest
9
+ from github import Artifact, Auth, Github, PullRequest, UnknownObjectException
10
10
 
11
11
  from recce.git import current_branch, hosting_repo
12
12
 
@@ -16,7 +16,7 @@ def download_artifact(github_token: str, artifact: Artifact) -> List[str]:
16
16
  Download the artifact from the Github.
17
17
  """
18
18
  headers = {
19
- 'Authorization': f'Bearer {github_token}',
19
+ "Authorization": f"Bearer {github_token}",
20
20
  }
21
21
  r = requests.get(artifact.archive_download_url, headers=headers)
22
22
  r.raise_for_status()
@@ -27,17 +27,17 @@ def download_artifact(github_token: str, artifact: Artifact) -> List[str]:
27
27
 
28
28
  def recce_ci_artifact(**kwargs):
29
29
  """
30
- Download the artifact from the GitHub CI.
30
+ Download the artifact from the GitHub CI.
31
31
  """
32
- from rich.console import Console
33
-
34
32
  import git
33
+
35
34
  # Authentication is defined via github.Auth
36
35
  from github import Auth, Github
36
+ from rich.console import Console
37
37
 
38
38
  console = Console()
39
- github_token = kwargs.get('github_token')
40
- github_repository = kwargs.get('github_repository')
39
+ github_token = kwargs.get("github_token")
40
+ github_repository = kwargs.get("github_repository")
41
41
 
42
42
  if github_token is None:
43
43
  console.print("[[red]Error[/red]] Missing GitHub token. Please provide a GitHub token.")
@@ -70,11 +70,11 @@ def recce_ci_artifact(**kwargs):
70
70
 
71
71
  head_branch = github_repo.get_branch(current_branch)
72
72
 
73
- console.rule('GitHub Repository Information')
74
- console.print(f'Repository: {github_repository}')
75
- console.print(f'Current Branch: {current_branch}')
73
+ console.rule("GitHub Repository Information")
74
+ console.print(f"Repository: {github_repository}")
75
+ console.print(f"Current Branch: {current_branch}")
76
76
 
77
- pull_requests = github_repo.get_pulls(head=f'{github_owner}:{current_branch}')
77
+ pull_requests = github_repo.get_pulls(head=f"{github_owner}:{current_branch}")
78
78
  if pull_requests.totalCount == 0:
79
79
  # No pull request found for the current branch
80
80
  console.print("[[red]Error[/red]] No pull request found for the current branch.")
@@ -82,32 +82,32 @@ def recce_ci_artifact(**kwargs):
82
82
 
83
83
  pr = pull_requests[0]
84
84
 
85
- console.rule('GitHub Pull Request Information')
86
- console.print(f'{pr.title} - {pr.html_url}')
87
- console.print(f'State: {pr.state.title()}')
88
- console.print(f'Author: {pr.user.name}')
89
- console.print(f'Created At: {pr.created_at}')
85
+ console.rule("GitHub Pull Request Information")
86
+ console.print(f"{pr.title} - {pr.html_url}")
87
+ console.print(f"State: {pr.state.title()}")
88
+ console.print(f"Author: {pr.user.name}")
89
+ console.print(f"Created At: {pr.created_at}")
90
90
 
91
91
  workflow_runs = github_repo.get_workflow_runs(
92
- event='pull_request',
93
- status='success',
92
+ event="pull_request",
93
+ status="success",
94
94
  branch=head_branch,
95
95
  )
96
96
  if workflow_runs.totalCount == 0:
97
97
  console.print("[[yellow]Skip[/yellow]] No successful workflow runs found.")
98
98
  return 0
99
99
  last_workflow_run = workflow_runs[0]
100
- console.rule('GitHub Workflow Run Information')
101
- console.print(f'Last Workflow Run: {last_workflow_run.name} {last_workflow_run.html_url}')
100
+ console.rule("GitHub Workflow Run Information")
101
+ console.print(f"Last Workflow Run: {last_workflow_run.name} {last_workflow_run.html_url}")
102
102
  artifacts = last_workflow_run.get_artifacts()
103
103
  if artifacts.totalCount == 0:
104
104
  console.print("[[yellow]Skip[/yellow]] No artifacts found.")
105
105
  return 0
106
106
  for artifact in artifacts:
107
- console.print(f'Artifact: {artifact.name} {artifact.archive_download_url}')
107
+ console.print(f"Artifact: {artifact.name} {artifact.archive_download_url}")
108
108
  artifact_files = download_artifact(github_token, artifact)
109
109
  console.print(f'Extracted Files: {", ".join(artifact_files)}')
110
- console.rule('Complete')
110
+ console.rule("Complete")
111
111
  return 0
112
112
 
113
113
 
@@ -121,7 +121,7 @@ def get_pull_request(branch, owner, repo_name, github_token=None) -> Tuple[Optio
121
121
 
122
122
  try:
123
123
  repo = g.get_repo(f"{owner}/{repo_name}")
124
- pulls = repo.get_pulls(state='open')
124
+ pulls = repo.get_pulls(state="open")
125
125
 
126
126
  for pr in pulls:
127
127
  if pr.head.ref == branch:
@@ -129,7 +129,10 @@ def get_pull_request(branch, owner, repo_name, github_token=None) -> Tuple[Optio
129
129
 
130
130
  except UnknownObjectException:
131
131
  if github_token is not None:
132
- return None, f"Repository {owner}/{repo_name} not found. If it is private repo, please add the 'repo' scope to the token."
132
+ return (
133
+ None,
134
+ f"Repository {owner}/{repo_name} not found. If it is private repo, please add the 'repo' scope to the token.",
135
+ )
133
136
 
134
137
  return None, None
135
138
 
@@ -139,53 +142,54 @@ def recce_pr_information(github_token=None) -> Tuple[Optional[type(PullRequest)]
139
142
  repo = hosting_repo()
140
143
 
141
144
  if not repo:
142
- return None, 'This is not a git repository.'
143
- if '/' not in repo:
144
- return None, 'This is not a GitHub repository.'
145
+ return None, "This is not a git repository."
146
+ if "/" not in repo:
147
+ return None, "This is not a GitHub repository."
145
148
 
146
- owner, repo_name = repo.split('/')
149
+ owner, repo_name = repo.split("/")
147
150
 
148
151
  github_token = github_token if github_token else os.getenv("GITHUB_TOKEN")
149
152
  return get_pull_request(branch, owner, repo_name, github_token)
150
153
 
151
154
 
152
155
  def is_github_codespace():
153
- return os.getenv('CODESPACES') == 'true'
156
+ return os.getenv("CODESPACES") == "true"
154
157
 
155
158
 
156
159
  def get_github_codespace_name():
157
- return os.getenv('CODESPACE_NAME')
160
+ return os.getenv("CODESPACE_NAME")
158
161
 
159
162
 
160
163
  def get_github_codespace_info():
161
164
  if is_github_codespace() is False:
162
165
  return None
163
166
 
164
- codespace_name = os.environ.get('CODESPACE_NAME')
165
- github_token = os.environ.get('GITHUB_TOKEN')
167
+ codespace_name = os.environ.get("CODESPACE_NAME")
168
+ github_token = os.environ.get("GITHUB_TOKEN")
166
169
 
167
170
  response = requests.get(
168
- f'https://api.github.com/user/codespaces/{codespace_name}',
171
+ f"https://api.github.com/user/codespaces/{codespace_name}",
169
172
  headers={
170
- 'Accept': 'application/vnd.github+json',
171
- 'Authorization': f'token {github_token}',
172
- 'X-GitHub-Api-Version': '2022-11-28',
173
- })
173
+ "Accept": "application/vnd.github+json",
174
+ "Authorization": f"token {github_token}",
175
+ "X-GitHub-Api-Version": "2022-11-28",
176
+ },
177
+ )
174
178
 
175
179
  if response.status_code != 200:
176
180
  return None
177
181
  codespace_info = response.json()
178
182
 
179
183
  return dict(
180
- name=codespace_info.get('name'),
181
- machine=codespace_info.get('machine'),
182
- prebuild=codespace_info.get('prebuild'),
183
- created_at=codespace_info.get('created_at'),
184
- updated_at=codespace_info.get('updated_at'),
185
- last_used_at=codespace_info.get('last_used_at'),
186
- state=codespace_info.get('state'),
187
- location=codespace_info.get('location'),
188
- idle_timeout_minutes=codespace_info.get('idle_timeout_minutes'),
184
+ name=codespace_info.get("name"),
185
+ machine=codespace_info.get("machine"),
186
+ prebuild=codespace_info.get("prebuild"),
187
+ created_at=codespace_info.get("created_at"),
188
+ updated_at=codespace_info.get("updated_at"),
189
+ last_used_at=codespace_info.get("last_used_at"),
190
+ state=codespace_info.get("state"),
191
+ location=codespace_info.get("location"),
192
+ idle_timeout_minutes=codespace_info.get("idle_timeout_minutes"),
189
193
  )
190
194
 
191
195
 
@@ -194,25 +198,25 @@ def get_github_codespace_available_at(codespace):
194
198
  return None
195
199
 
196
200
  def search_in_file(file_path, search_string):
197
- with open(file_path, 'r') as f:
201
+ with open(file_path, "r") as f:
198
202
  for _, line in enumerate(f, 1):
199
203
  if search_string in line:
200
204
  return line
201
205
  return None
202
206
 
203
207
  def extract_datatime(log_line):
204
- pattern = r'\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*\]'
208
+ pattern = r"\[(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*\]"
205
209
  match = re.search(pattern, log_line)
206
210
  if match:
207
211
  datetime_str = match.group(1)
208
- return datetime.strptime(datetime_str, '%Y-%m-%d %H:%M:%S.%f')
212
+ return datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S.%f")
209
213
  return None
210
214
 
211
- github_codepsce_log_dir = '/tmp/codespaces_logs'
215
+ github_codepsce_log_dir = "/tmp/codespaces_logs"
212
216
  try:
213
217
  log_file = os.listdir(github_codepsce_log_dir)[-1] # Get the latest log file
214
- start_monitor_line = search_in_file(f'{github_codepsce_log_dir}/{log_file}', 'Starting monitor')
218
+ start_monitor_line = search_in_file(f"{github_codepsce_log_dir}/{log_file}", "Starting monitor")
215
219
  return extract_datatime(start_monitor_line)
216
220
  except Exception:
217
221
  # If there is any error, use the updated_at time from the codespace info
218
- return datetime.fromisoformat(codespace.get('updated_at'))
222
+ return datetime.fromisoformat(codespace.get("updated_at"))
recce/models/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from .check import CheckDAO
2
2
  from .run import RunDAO
3
- from .types import Check, Run, RunType, RunProgress
3
+ from .types import Check, Run, RunProgress, RunType
recce/models/check.py CHANGED
@@ -1,6 +1,7 @@
1
- from typing import Optional, List
1
+ from typing import List, Optional
2
2
 
3
3
  from recce.exceptions import RecceException
4
+
4
5
  from .types import Check
5
6
 
6
7
 
@@ -12,6 +13,7 @@ class CheckDAO:
12
13
  @property
13
14
  def _checks(self):
14
15
  from recce.core import default_context
16
+
15
17
  return default_context().checks
16
18
 
17
19
  def create(self, check) -> None:
@@ -38,10 +40,10 @@ class CheckDAO:
38
40
  def reorder(self, source: int, destination: int):
39
41
 
40
42
  if source < 0 or source >= len(self._checks):
41
- raise RecceException('Failed to reorder checks. Source index out of range')
43
+ raise RecceException("Failed to reorder checks. Source index out of range")
42
44
 
43
45
  if destination < 0 or destination >= len(self._checks):
44
- raise RecceException('Failed to reorder checks. Destination index out of range')
46
+ raise RecceException("Failed to reorder checks. Destination index out of range")
45
47
 
46
48
  check_to_move = self._checks.pop(source)
47
49
  self._checks.insert(destination, check_to_move)
@@ -50,7 +52,4 @@ class CheckDAO:
50
52
  self._checks.clear()
51
53
 
52
54
  def status(self):
53
- return {
54
- 'total': len(self._checks),
55
- 'approved': len([c for c in self._checks if c.is_checked])
56
- }
55
+ return {"total": len(self._checks), "approved": len([c for c in self._checks if c.is_checked])}
recce/models/run.py CHANGED
@@ -9,6 +9,7 @@ class RunDAO:
9
9
  @property
10
10
  def _runs(self):
11
11
  from recce.core import default_context
12
+
12
13
  return default_context().runs
13
14
 
14
15
  def create(self, run: Run):
recce/models/types.py CHANGED
@@ -1,26 +1,26 @@
1
1
  import uuid
2
2
  from datetime import datetime, timezone
3
3
  from enum import Enum
4
- from typing import Optional, Literal
4
+ from typing import Literal, Optional
5
5
 
6
- from pydantic import BaseModel, UUID4, Field
6
+ from pydantic import UUID4, BaseModel, Field
7
7
 
8
8
 
9
9
  class RunType(Enum):
10
- SIMPLE = 'simple'
10
+ SIMPLE = "simple"
11
11
  QUERY = "query"
12
- QUERY_BASE = 'query_base'
13
- QUERY_DIFF = 'query_diff'
14
- VALUE_DIFF = 'value_diff'
15
- VALUE_DIFF_DETAIL = 'value_diff_detail'
16
- SCHEMA_DIFF = 'schema_diff'
17
- PROFILE = 'profile'
18
- PROFILE_DIFF = 'profile_diff'
19
- ROW_COUNT = 'row_count'
20
- ROW_COUNT_DIFF = 'row_count_diff'
21
- LINEAGE_DIFF = 'lineage_diff'
22
- TOP_K_DIFF = 'top_k_diff'
23
- HISTOGRAM_DIFF = 'histogram_diff'
12
+ QUERY_BASE = "query_base"
13
+ QUERY_DIFF = "query_diff"
14
+ VALUE_DIFF = "value_diff"
15
+ VALUE_DIFF_DETAIL = "value_diff_detail"
16
+ SCHEMA_DIFF = "schema_diff"
17
+ PROFILE = "profile"
18
+ PROFILE_DIFF = "profile_diff"
19
+ ROW_COUNT = "row_count"
20
+ ROW_COUNT_DIFF = "row_count_diff"
21
+ LINEAGE_DIFF = "lineage_diff"
22
+ TOP_K_DIFF = "top_k_diff"
23
+ HISTOGRAM_DIFF = "histogram_diff"
24
24
 
25
25
  def __str__(self):
26
26
  return self.value
@@ -32,12 +32,12 @@ class RunProgress(BaseModel):
32
32
 
33
33
 
34
34
  class RunStatus(Enum):
35
- FINISHED = 'finished'
36
- FAILED = 'failed'
37
- CANCELLED = 'cancelled'
38
- RUNNING = 'running'
35
+ FINISHED = "finished"
36
+ FAILED = "failed"
37
+ CANCELLED = "cancelled"
38
+ RUNNING = "running"
39
39
  # This is a special status only in v0.36.0. Replaced by FINISHED. To be removed in the future.
40
- SUCCESSFUL = 'successful'
40
+ SUCCESSFUL = "successful"
41
41
 
42
42
 
43
43
  class Run(BaseModel):
@@ -84,15 +84,15 @@ class Check(BaseModel):
84
84
 
85
85
 
86
86
  ChangeStatus = Literal[
87
- 'added',
88
- 'removed',
89
- 'modified',
87
+ "added",
88
+ "removed",
89
+ "modified",
90
90
  ]
91
91
  ChangeCategory = Literal[
92
- 'breaking',
93
- 'non_breaking',
94
- 'partial_breaking',
95
- 'unknown',
92
+ "breaking",
93
+ "non_breaking",
94
+ "partial_breaking",
95
+ "unknown",
96
96
  ]
97
97
 
98
98
 
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('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')
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('github_token'))
38
- if kwargs.get('cloud') and message:
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 'github_pull_request_url' in kwargs:
51
- pr_info.url = kwargs.get('github_pull_request_url')
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('git_current_branch')
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('git_base_branch')
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
- If recce run is running in a GitHub Action, this function will return the pull request metadata.
68
+ If recce run is running in a GitHub Action, this function will return the pull request metadata.
69
69
 
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
- }
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
- :return: dict
78
+ :return: dict
79
79
  """
80
80
 
81
81
  # get the event json from the path in GITHUB_EVENT_PATH
@@ -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(github_pr_id=pr_id,
96
- github_pr_url=pr_url,
97
- github_pr_title=pr_title,
98
- github_repository=github_repository)
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('title')
120
+ return pull_request_data.get("title")
119
121
  except Exception as e:
120
122
  print("Cannot fetch PR title: ", e)
121
123