/ github / Commit.py
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"])