Commit.py
1 ############################ Copyrights and license ############################ 2 # # 3 # Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> # 4 # Copyright 2012 Zearin <zearin@gonk.net> # 5 # Copyright 2013 AKFish <akfish@gmail.com> # 6 # Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> # 7 # Copyright 2013 martinqt <m.ki2@laposte.net> # 8 # Copyright 2014 Andy Casey <acasey@mso.anu.edu.au> # 9 # Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> # 10 # Copyright 2016 Jannis Gebauer <ja.geb@me.com> # 11 # Copyright 2016 John Eskew <jeskew@edx.org> # 12 # Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> # 13 # Copyright 2018 sfdye <tsfdye@gmail.com> # 14 # # 15 # This file is part of PyGithub. # 16 # http://pygithub.readthedocs.io/ # 17 # # 18 # PyGithub is free software: you can redistribute it and/or modify it under # 19 # the terms of the GNU Lesser General Public License as published by the Free # 20 # Software Foundation, either version 3 of the License, or (at your option) # 21 # any later version. # 22 # # 23 # PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY # 24 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # 25 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # 26 # details. # 27 # # 28 # You should have received a copy of the GNU Lesser General Public License # 29 # along with PyGithub. If not, see <http://www.gnu.org/licenses/>. # 30 # # 31 ################################################################################ 32 from __future__ import annotations 33 34 from typing import TYPE_CHECKING, Any 35 36 import github.CheckRun 37 import github.CheckSuite 38 import github.CommitCombinedStatus 39 import github.CommitComment 40 import github.CommitStats 41 import github.CommitStatus 42 import github.File 43 import github.GitCommit 44 import github.NamedUser 45 import github.PaginatedList 46 from github.GithubObject import Attribute, CompletableGithubObject, NotSet, Opt, is_optional 47 from github.PaginatedList import PaginatedList 48 49 if TYPE_CHECKING: 50 from github.CheckRun import CheckRun 51 from github.CheckSuite import CheckSuite 52 from github.CommitCombinedStatus import CommitCombinedStatus 53 from github.CommitComment import CommitComment 54 from github.CommitStats import CommitStats 55 from github.CommitStatus import CommitStatus 56 from github.File import File 57 from github.GitCommit import GitCommit 58 from github.NamedUser import NamedUser 59 from github.PullRequest import PullRequest 60 61 62 class Commit(CompletableGithubObject): 63 """ 64 This class represents Commits. The reference can be found here https://docs.github.com/en/rest/reference/git#commits 65 """ 66 67 def _initAttributes(self) -> None: 68 self._author: Attribute[NamedUser] = NotSet 69 self._comments_url: Attribute[str] = NotSet 70 self._commit: Attribute[GitCommit] = NotSet 71 self._committer: Attribute[NamedUser] = NotSet 72 self._files: Attribute[list[File]] = NotSet 73 self._html_url: Attribute[str] = NotSet 74 self._parents: Attribute[list[Commit]] = NotSet 75 self._sha: Attribute[str] = NotSet 76 self._stats: Attribute[CommitStats] = NotSet 77 self._url: Attribute[str] = NotSet 78 79 def __repr__(self) -> str: 80 return self.get__repr__({"sha": self._sha.value}) 81 82 @property 83 def author(self) -> NamedUser: 84 self._completeIfNotSet(self._author) 85 return self._author.value 86 87 @property 88 def comments_url(self) -> str: 89 self._completeIfNotSet(self._comments_url) 90 return self._comments_url.value 91 92 @property 93 def commit(self) -> GitCommit: 94 self._completeIfNotSet(self._commit) 95 return self._commit.value 96 97 @property 98 def committer(self) -> NamedUser: 99 self._completeIfNotSet(self._committer) 100 return self._committer.value 101 102 @property 103 def files(self) -> list[File]: 104 self._completeIfNotSet(self._files) 105 return self._files.value 106 107 @property 108 def html_url(self) -> str: 109 self._completeIfNotSet(self._html_url) 110 return self._html_url.value 111 112 @property 113 def parents(self) -> list[Commit]: 114 self._completeIfNotSet(self._parents) 115 return self._parents.value 116 117 @property 118 def sha(self) -> str: 119 self._completeIfNotSet(self._sha) 120 return self._sha.value 121 122 @property 123 def stats(self) -> CommitStats: 124 self._completeIfNotSet(self._stats) 125 return self._stats.value 126 127 @property 128 def url(self) -> str: 129 self._completeIfNotSet(self._url) 130 return self._url.value 131 132 def create_comment( 133 self, 134 body: str, 135 line: Opt[int] = NotSet, 136 path: Opt[str] = NotSet, 137 position: Opt[int] = NotSet, 138 ) -> CommitComment: 139 """ 140 :calls: `POST /repos/{owner}/{repo}/commits/{sha}/comments <https://docs.github.com/en/rest/reference/repos#comments>`_ 141 """ 142 assert isinstance(body, str), body 143 assert is_optional(line, int), line 144 assert is_optional(path, str), path 145 assert is_optional(position, int), position 146 post_parameters = NotSet.remove_unset_items({"body": body, "line": line, "path": path, "position": position}) 147 148 headers, data = self._requester.requestJsonAndCheck("POST", f"{self.url}/comments", input=post_parameters) 149 return github.CommitComment.CommitComment(self._requester, headers, data, completed=True) 150 151 def create_status( 152 self, 153 state: str, 154 target_url: Opt[str] = NotSet, 155 description: Opt[str] = NotSet, 156 context: Opt[str] = NotSet, 157 ) -> CommitStatus: 158 """ 159 :calls: `POST /repos/{owner}/{repo}/statuses/{sha} <https://docs.github.com/en/rest/reference/repos#statuses>`_ 160 """ 161 assert isinstance(state, str), state 162 assert is_optional(target_url, str), target_url 163 assert is_optional(description, str), description 164 assert is_optional(context, str), context 165 post_parameters = NotSet.remove_unset_items( 166 { 167 "state": state, 168 "target_url": target_url, 169 "description": description, 170 "context": context, 171 } 172 ) 173 174 headers, data = self._requester.requestJsonAndCheck( 175 "POST", 176 f"{self._parentUrl(self._parentUrl(self.url))}/statuses/{self.sha}", 177 input=post_parameters, 178 ) 179 return github.CommitStatus.CommitStatus(self._requester, headers, data, completed=True) 180 181 def get_comments(self) -> PaginatedList[CommitComment]: 182 """ 183 :calls: `GET /repos/{owner}/{repo}/commits/{sha}/comments <https://docs.github.com/en/rest/reference/repos#comments>`_ 184 """ 185 return PaginatedList( 186 github.CommitComment.CommitComment, 187 self._requester, 188 f"{self.url}/comments", 189 None, 190 ) 191 192 def get_statuses(self) -> PaginatedList[CommitStatus]: 193 """ 194 :calls: `GET /repos/{owner}/{repo}/statuses/{ref} <https://docs.github.com/en/rest/reference/repos#statuses>`_ 195 """ 196 return PaginatedList( 197 github.CommitStatus.CommitStatus, 198 self._requester, 199 f"{self._parentUrl(self._parentUrl(self.url))}/statuses/{self.sha}", 200 None, 201 ) 202 203 def get_combined_status(self) -> CommitCombinedStatus: 204 """ 205 :calls: `GET /repos/{owner}/{repo}/commits/{ref}/status/ <http://docs.github.com/en/rest/reference/repos#statuses>`_ 206 """ 207 headers, data = self._requester.requestJsonAndCheck("GET", f"{self.url}/status") 208 return github.CommitCombinedStatus.CommitCombinedStatus(self._requester, headers, data, completed=True) 209 210 def get_pulls(self) -> PaginatedList[PullRequest]: 211 """ 212 :calls: `GET /repos/{owner}/{repo}/commits/{sha}/pulls <https://docs.github.com/en/rest/reference/repos#list-pull-requests-associated-with-a-commit>`_ 213 """ 214 return PaginatedList( 215 github.PullRequest.PullRequest, 216 self._requester, 217 f"{self.url}/pulls", 218 None, 219 headers={"Accept": "application/vnd.github.groot-preview+json"}, 220 ) 221 222 def get_check_runs( 223 self, 224 check_name: Opt[str] = NotSet, 225 status: Opt[str] = NotSet, 226 filter: Opt[str] = NotSet, 227 ) -> PaginatedList[CheckRun]: 228 """ 229 :calls: `GET /repos/{owner}/{repo}/commits/{sha}/check-runs <https://docs.github.com/en/rest/reference/checks#list-check-runs-for-a-git-reference>`_ 230 """ 231 assert is_optional(check_name, str), check_name 232 assert is_optional(status, str), status 233 assert is_optional(filter, str), filter 234 url_parameters = NotSet.remove_unset_items({"check_name": check_name, "status": status, "filter": filter}) 235 236 return PaginatedList( 237 github.CheckRun.CheckRun, 238 self._requester, 239 f"{self.url}/check-runs", 240 url_parameters, 241 headers={"Accept": "application/vnd.github.v3+json"}, 242 list_item="check_runs", 243 ) 244 245 def get_check_suites(self, app_id: Opt[int] = NotSet, check_name: Opt[str] = NotSet) -> PaginatedList[CheckSuite]: 246 """ 247 :class: `GET /repos/{owner}/{repo}/commits/{ref}/check-suites <https://docs.github.com/en/rest/reference/checks#list-check-suites-for-a-git-reference>`_ 248 """ 249 assert is_optional(app_id, int), app_id 250 assert is_optional(check_name, str), check_name 251 parameters = NotSet.remove_unset_items({"app_id": app_id, "check_name": check_name}) 252 253 request_headers = {"Accept": "application/vnd.github.v3+json"} 254 return PaginatedList( 255 github.CheckSuite.CheckSuite, 256 self._requester, 257 f"{self.url}/check-suites", 258 parameters, 259 headers=request_headers, 260 list_item="check_suites", 261 ) 262 263 @property 264 def _identity(self) -> str: 265 return self.sha 266 267 def _useAttributes(self, attributes: dict[str, Any]) -> None: 268 if "author" in attributes: # pragma no branch 269 self._author = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["author"]) 270 if "comments_url" in attributes: # pragma no branch 271 self._comments_url = self._makeStringAttribute(attributes["comments_url"]) 272 if "commit" in attributes: # pragma no branch 273 self._commit = self._makeClassAttribute(github.GitCommit.GitCommit, attributes["commit"]) 274 if "committer" in attributes: # pragma no branch 275 self._committer = self._makeClassAttribute(github.NamedUser.NamedUser, attributes["committer"]) 276 if "files" in attributes: # pragma no branch 277 self._files = self._makeListOfClassesAttribute(github.File.File, attributes["files"]) 278 if "html_url" in attributes: # pragma no branch 279 self._html_url = self._makeStringAttribute(attributes["html_url"]) 280 if "parents" in attributes: # pragma no branch 281 self._parents = self._makeListOfClassesAttribute(Commit, attributes["parents"]) 282 if "sha" in attributes: # pragma no branch 283 self._sha = self._makeStringAttribute(attributes["sha"]) 284 if "stats" in attributes: # pragma no branch 285 self._stats = self._makeClassAttribute(github.CommitStats.CommitStats, attributes["stats"]) 286 if "url" in attributes: # pragma no branch 287 self._url = self._makeStringAttribute(attributes["url"])