1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Nit object oriented interface to [Github api](https://developer.github.com/v3/).
17 # This modules reifies Github API elements as Nit classes.
19 # For most use-cases you need to use the `GithubAPI` client.
22 intrude import json
::serialization_read
29 # Client to Github API
31 # To access the API you need an instance of a `GithubAPI` client.
34 # # Get Github authentification token.
35 # var token = get_github_oauth
36 # assert not token.is_empty
39 # var api = new GithubAPI(token)
42 # The API client allows you to get Github API entities.
45 # var repo = api.get_repo("nitlang/nit")
47 # assert repo.name == "nit"
49 # var user = api.get_user("Morriar")
51 # assert user.login == "Morriar"
55 # Github API OAuth token
57 # To access your private ressources, you must
58 # [authenticate](https://developer.github.com/guides/basics-of-authentication/).
60 # For client applications, Github recommands to use the
61 # [OAuth tokens](https://developer.github.com/v3/oauth/) authentification method.
65 # Be aware that there is [rate limits](https://developer.github.com/v3/rate_limit/)
66 # associated to the key.
67 var auth
: nullable String = null is optional
69 # User agent used for HTTP requests.
71 # Default is `nit_github_api`.
73 # See <https://developer.github.com/v3/#user-agent-required>
74 var user_agent
: String = "nit_github_api" is optional
76 # Headers to use on all requests
77 fun new_headers
: HeaderMap do
78 var map
= new HeaderMap
81 map
["Authorization"] = "token {auth}"
83 map
["User-Agent"] = user_agent
84 # FIXME remove when projects and team are no more in beta
85 map
["Accept"] = "application/vnd.github.inertia-preview+json"
86 map
["Accept"] = "application/vnd.github.hellcat-preview+json"
90 # Github API base url.
92 # Default is `https://api.github.com` and should not be changed.
93 var api_url
= "https://api.github.com"
97 # * `0`: only errors (default)
99 var verbose_lvl
= 0 is public
writable
101 # Send a HTTPRequest to the Github API
102 fun send
(method
, path
: String, headers
: nullable HeaderMap, body
: nullable String): nullable String do
104 path
= sanitize_uri
(path
)
105 var uri
= "{api_url}{path}"
106 var request
= new CurlHTTPRequest(uri
)
107 request
.method
= method
108 request
.user_agent
= user_agent
109 request
.headers
= headers
or else self.new_headers
111 return check_response
(uri
, request
.execute
)
114 private fun check_response
(uri
: String, response
: CurlResponse): nullable String do
115 if response
isa CurlResponseSuccess then
117 return response
.body_str
118 else if response
isa CurlResponseFailed then
119 last_error
= new GithubAPIError(
129 # Deserialize an object
130 fun deserialize
(string
: nullable Serializable): nullable Object do
131 if string
== null then return null
132 var deserializer
= new GithubDeserializer(string
.to_s
)
133 var res
= deserializer
.deserialize
134 if deserializer
.errors
.not_empty
then
136 last_error
= new GithubDeserializerErrors("Deserialization failed", deserializer
.errors
)
138 else if res
isa GithubError then
147 # Display a message depending on `verbose_lvl`.
148 fun message
(lvl
: Int, message
: String) do
149 if lvl
<= verbose_lvl
then print message
152 # Escape `uri` in an acceptable format for Github.
153 private fun sanitize_uri
(uri
: String): String do
154 # TODO better URI escape.
155 return uri
.replace
(" ", "%20")
158 # Last error occured during Github API communications.
159 var last_error
: nullable Error = null is public
writable
161 # Does the last request provoqued an error?
162 var was_error
= false is protected writable
164 # Execute a GET request on Github API.
166 # This method returns a deserialized result.
168 # For raw data see `send`.
171 # var api = new GithubAPI(get_github_oauth)
172 # var obj = api.get("/repos/nitlang/nit")
173 # assert obj isa Repo
174 # assert obj.name == "nit"
177 # Returns `null` in case of `error`.
180 # obj = api.get("/foo/bar/baz")
182 # assert api.was_error
183 # assert api.last_error isa GithubError
185 fun get
(path
: String, headers
: nullable HeaderMap, data
: nullable String): nullable Object do
186 return deserialize
(send
("GET", path
, headers
, data
))
189 # Get the Github logged user from `auth` token.
191 # Loads the `User` from the API or returns `null` if the user cannot be found.
194 # var api = new GithubAPI(get_github_oauth)
195 # var user = api.get_auth_user
196 # assert user.login == "Morriar"
198 fun get_auth_user
: nullable User do
199 return get
("/user").as(nullable User)
202 # Get the Github user with `login`
204 # Loads the `User` from the API or returns `null` if the user cannot be found.
207 # var api = new GithubAPI(get_github_oauth)
208 # var user = api.get_user("Morriar")
209 # print user or else "null"
210 # assert user.login == "Morriar"
212 fun get_user
(login
: String): nullable User do
213 return get
("/users/{login}").as(nullable User)
216 # Get the Github repo with `full_name`.
218 # Loads the `Repo` from the API or returns `null` if the repo cannot be found.
221 # var api = new GithubAPI(get_github_oauth)
222 # var repo = api.get_repo("nitlang/nit")
223 # assert repo.name == "nit"
224 # assert repo.owner.login == "nitlang"
225 # assert repo.default_branch == "master"
227 fun get_repo
(repo_slug
: String): nullable Repo do
228 return get
("/repos/{repo_slug}").as(nullable Repo)
231 # List of repo branches.
234 # * `page`: page to fetch (default: 1)
235 # * `per_page`: number of branches by page (default: 30)
236 fun get_repo_branches
(repo_slug
: String, page
, per_page
: nullable Int): Array[Branch] do
237 return new GithubArray[Branch].from
(get
(
238 "/repos/{repo_slug}/branches?{pagination(page, per_page)}"))
241 # List of issues associated with their ids.
242 fun get_repo_issues
(repo_slug
: String, page
, per_page
: nullable Int): Array[Issue] do
243 return new GithubArray[Issue].from
(get
(
244 "/repos/{repo_slug}/issues?{pagination(page, per_page)}"))
247 # Search issues in this repo form an advanced query.
252 # var issues = repo.search_issues("is:open label:need_review")
255 # See <https://developer.github.com/v3/search/#search-issues>.
256 fun search_repo_issues
(repo_slug
: String, query
: String, page
, per_page
: nullable Int): nullable SearchResults do
257 return get
("/search/issues?q={query} repo:{repo_slug}&{pagination(page, per_page)}").as(nullable SearchResults)
260 # List of labels associated with their names.
261 fun get_repo_labels
(repo_slug
: String, page
, per_page
: nullable Int): Array[Label] do
262 return new GithubArray[Label].from
(get
(
263 "/repos/{repo_slug}/labels?{pagination(page, per_page)}"))
266 # List of milestones associated with their ids.
267 fun get_repo_milestones
(repo_slug
: String, page
, per_page
: nullable Int): Array[Milestone] do
268 return new GithubArray[Milestone].from
(get
(
269 "/repos/{repo_slug}/milestones?{pagination(page, per_page)}"))
272 # List of pull-requests associated with their ids.
274 # Implementation notes: because PR numbers are not consecutive,
275 # PR are loaded from pages.
276 # See: https://developer.github.com/v3/pulls/#list-pull-requests
277 fun get_repo_pulls
(repo_slug
: String, page
, per_page
: nullable Int): Array[PullRequest] do
278 return new GithubArray[PullRequest].from
(get
(
279 "/repos/{repo_slug}/pulls?{pagination(page, per_page)}"))
282 # List of contributor related statistics.
283 fun get_repo_contrib_stats
(repo_slug
: String): Array[ContributorStats] do
284 message
(1, "Get contributor stats for {repo_slug}")
285 var res
= new Array[ContributorStats]
286 var array
= get
("/repos/{repo_slug}/stats/contributors")
287 if not array
isa JsonArray then return res
288 return deserialize
(array
.to_json
).as(Array[ContributorStats])
291 # Get the Github branch with `name`.
293 # Returns `null` if the branch cannot be found.
296 # var api = new GithubAPI(get_github_oauth)
297 # var repo = api.get_repo("nitlang/nit")
298 # assert repo != null
299 # var branch = api.get_branch(repo, "master")
300 # assert branch.name == "master"
301 # assert branch.commit isa Commit
303 fun get_branch
(repo_slug
: String, name
: String): nullable Branch do
304 return get
("/repos/{repo_slug}/branches/{name}").as(nullable Branch)
307 # Get the Github commit with `sha`.
309 # Returns `null` if the commit cannot be found.
312 # var api = new GithubAPI(get_github_oauth)
313 # var repo = api.get_repo("nitlang/nit")
314 # assert repo != null
315 # var commit = api.get_commit(repo, "64ce1f")
316 # assert commit isa Commit
318 fun get_commit
(repo_slug
: String, sha
: String): nullable Commit do
319 return get
("/repos/{repo_slug}/commits/{sha}").as(nullable Commit)
322 # Get the status of a commit
324 # The status holds the result of each check ran on a commit like CI, reviews etc.
325 fun get_commit_status
(repo_slug
: String, sha
: String): nullable CommitStatus do
326 return get
("/repos/{repo_slug}/commits/{sha}/status").as(nullable CommitStatus)
329 # Get the Github issue #`number`.
331 # Returns `null` if the issue cannot be found.
334 # var api = new GithubAPI(get_github_oauth)
335 # var repo = api.get_repo("nitlang/nit")
336 # assert repo != null
337 # var issue = api.get_issue(repo, 1)
338 # assert issue.title == "Doc"
340 fun get_issue
(repo_slug
: String, number
: Int): nullable Issue do
341 return get
("/repos/{repo_slug}/issues/{number}").as(nullable Issue)
344 # List of event on this issue.
345 fun get_issue_comments
(repo_slug
: String, issue_number
: Int, page
, per_page
: nullable Int): Array[IssueComment] do
346 return new GithubArray[IssueComment].from
(get
(
347 "/repos/{repo_slug}/issues/{issue_number}/comments?{pagination(page, per_page)}"))
350 # List of events on this issue.
351 fun get_issue_events
(repo_slug
: String, issue_number
: Int, page
, per_page
: nullable Int): Array[IssueEvent] do
352 return new GithubArray[IssueEvent].from
(get
(
353 "/repos/{repo_slug}/issues/{issue_number}/events?{pagination(page, per_page)}"))
356 # Get the Github pull request #`number`.
358 # Returns `null` if the pull request cannot be found.
361 # var api = new GithubAPI(get_github_oauth)
362 # var repo = api.get_repo("nitlang/nit")
363 # assert repo != null
364 # var pull = api.get_pull(repo, 1)
365 # assert pull.title == "Doc"
366 # assert pull.user.login == "Morriar"
368 fun get_pull
(repo_slug
: String, number
: Int): nullable PullRequest do
369 return get
("/repos/{repo_slug}/pulls/{number}").as(nullable PullRequest)
372 # Get a specific pull request comment
373 fun get_pull_comment
(repo_slug
: String, id
: Int): nullable PullComment do
374 return get
("/repos/{repo_slug}/pulls/comments/{id}").as(nullable PullComment)
377 # Get the Github label with `name`.
379 # Returns `null` if the label cannot be found.
382 # var api = new GithubAPI(get_github_oauth)
383 # var repo = api.get_repo("nitlang/nit")
384 # assert repo != null
385 # var labl = api.get_label(repo, "ok_will_merge")
386 # assert labl != null
388 fun get_label
(repo_slug
: String, name
: String): nullable Label do
389 return get
("/repos/{repo_slug}/labels/{name}").as(nullable Label)
392 # Get the Github milestone with `id`.
394 # Returns `null` if the milestone cannot be found.
397 # var api = new GithubAPI(get_github_oauth)
398 # var repo = api.get_repo("nitlang/nit")
399 # assert repo != null
400 # var stone = api.get_milestone(repo, 4)
401 # assert stone.title == "v1.0prealpha"
403 fun get_milestone
(repo_slug
: String, id
: Int): nullable Milestone do
404 return get
("/repos/{repo_slug}/milestones/{id}").as(nullable Milestone)
407 # Get the Github issue event with `id`.
409 # Returns `null` if the event cannot be found.
412 # var api = new GithubAPI(get_github_oauth)
413 # var repo = api.get_repo("nitlang/nit")
414 # assert repo isa Repo
415 # var event = api.get_issue_event(repo, 199674194)
416 # assert event isa IssueEvent
417 # assert event.actor.login == "privat"
418 # assert event.event == "labeled"
419 # assert event.labl isa Label
420 # assert event.labl.name == "need_review"
422 fun get_issue_event
(repo_slug
: String, id
: Int): nullable IssueEvent do
423 return get
("/repos/{repo_slug}/issues/events/{id}").as(nullable IssueEvent)
426 # Get the Github commit comment with `id`.
428 # Returns `null` if the comment cannot be found.
431 # var api = new GithubAPI(get_github_oauth)
432 # var repo = api.get_repo("nitlang/nit")
433 # assert repo != null
434 # var comment = api.get_commit_comment(repo, 8982707)
435 # assert comment.user.login == "Morriar"
436 # assert comment.body == "For testing purposes...\n"
437 # assert comment.commit_id == "7eacb86d1e24b7e72bc9ac869bf7182c0300ceca"
439 fun get_commit_comment
(repo_slug
: String, id
: Int): nullable CommitComment do
440 return get
("/repos/{repo_slug}/comments/{id}").as(nullable CommitComment)
443 # Get the Github issue comment with `id`.
445 # Returns `null` if the comment cannot be found.
448 # var api = new GithubAPI(get_github_oauth)
449 # var repo = api.get_repo("nitlang/nit")
450 # assert repo != null
451 # var comment = api.get_issue_comment(repo, 6020149)
452 # assert comment.user.login == "privat"
453 # assert comment.created_at.to_s == "2012-05-30T20:16:54Z"
454 # assert comment.issue_number == 10
456 fun get_issue_comment
(repo_slug
: String, id
: Int): nullable IssueComment do
457 return get
("/repos/{repo_slug}/issues/comments/{id}").as(nullable IssueComment)
460 private fun pagination
(page
, per_page
: nullable Int): String do
461 return "page={page or else 1}&per_page={per_page or else 30}"
465 # Return deserialization as an array of E
467 # Non-subtypes will be ignored.
468 private class GithubArray[E
]
471 # Create `self` from an Array of objects
473 # Objects non-subtyping E will be ignored.
474 init from
(res
: nullable Object) do
475 if not res
isa Array[Object] then return
477 if obj
isa E
then add obj
482 # An Error returned by GithubAPI
487 # An Error returned by https://api.github.com
489 # Anything that can occurs when sending request to the API:
490 # * Can't connect to API
491 # * Ressource not found
497 # Status code obtained
500 # URI that returned the error
501 var requested_uri
: String
504 # An Error returned while deserializing objects from the API
505 class GithubDeserializerErrors
508 # Errors returned by the deserizalization process
509 var deserizalization_errors
: Array[Error]
514 # Provides access to [Github user data](https://developer.github.com/v3/users/).
515 # Should be accessed from `GithubAPI::get_user`.
521 var login
: String is writable
523 # Avatar image url for this user.
524 var avatar_url
: nullable String is writable
526 # User public name if any.
527 var name
: nullable String is writable
529 # User public email if any.
530 var email
: nullable String is writable
532 # User public blog if any.
533 var blog
: nullable String is writable
536 # A Github repository.
538 # Provides access to [Github repo data](https://developer.github.com/v3/repos/).
539 # Should be accessed from `GithubAPI::get_repo`.
543 # Repo full name on Github.
544 var full_name
: String is writable
546 # Repo short name on Github.
547 var name
: String is writable
549 # Get the repo owner.
550 var owner
: User is writable
552 # Repo default branch name.
553 var default_branch
: nullable String = null is optional
, writable
558 # Should be accessed from `GithubAPI::get_branch`.
560 # See <https://developer.github.com/v3/repos/#list-branches>.
565 var name
: String is writable
567 # Get the last commit of `self`.
568 var commit
: Commit is writable
573 # Should be accessed from `GithubAPI::get_commit`.
575 # See <https://developer.github.com/v3/repos/commits/>.
580 var sha
: String is writable
582 # Parent commits of `self`.
583 var parents
: nullable Array[Commit] = null is writable
585 # Author of the commit.
586 var author
: nullable GitUser is writable
588 # Committer of the commit.
589 var committer
: nullable GitUser is writable
591 # Authoring date as String.
592 var author_date
: nullable String is writable
594 # Commit date as String.
595 var commit_date
: nullable String is writable
597 # List files staged in this commit.
598 var files
: nullable Array[GithubFile] = null is optional
, writable
601 var message
: nullable String is writable
603 # Git commit representation linked to this commit.
604 var commit
: nullable GitCommit
607 # A Git Commit representation
612 var sha
: nullable String is writable
614 # Parent commits of `self`.
615 var parents
: nullable Array[GitCommit] = null is writable
617 # Author of the commit.
618 var author
: nullable GitUser is writable
620 # Committer of the commit.
621 var committer
: nullable GitUser is writable
624 var message
: nullable String is writable
627 # Git user authoring data
632 var date
: nullable String = null is writable
637 # Should be accessed from `GithubAPI::get_issue`.
639 # See <https://developer.github.com/v3/issues/>.
644 var number
: Int is writable
647 var id
: nullable Int is writable
650 var title
: String is writable
652 # User that created this issue.
653 var user
: nullable User is writable
655 # List of labels on this issue associated to their names.
656 var labels
: nullable Array[Label] is writable
658 # State of the issue on Github.
659 var state
: String is writable
661 # Is the issue locked?
662 var locked
: nullable Bool is writable
664 # Assigned `User` (if any).
665 var assignee
: nullable User is writable
667 # `Milestone` (if any).
668 var milestone
: nullable Milestone is writable
670 # Number of comments on this issue.
671 var comments
: nullable Int is writable
673 # Creation time as String.
674 var created_at
: String is writable
676 # Last update time as String (if any).
677 var updated_at
: nullable String is writable
679 # Close time as String (if any).
680 var closed_at
: nullable String is writable
682 # Full description of the issue.
683 var body
: nullable String is writable
685 # User that closed this issue (if any).
686 var closed_by
: nullable User is writable
688 # Is this issue linked to a pull request?
689 var is_pull_request
: Bool = false is writable
692 # A Github pull request.
694 # Should be accessed from `GithubAPI::get_pull`.
696 # PullRequest are basically Issues with more data.
697 # See <https://developer.github.com/v3/pulls/>.
702 # Merge time as String (if any).
703 var merged_at
: nullable String is writable
706 var merge_commit_sha
: nullable String is writable
708 # Count of comments made on the pull request diff.
709 var review_comments
: nullable Int is writable
711 # Pull request head (can be a commit SHA or a branch name).
712 var head
: PullRef is writable
714 # Pull request base (can be a commit SHA or a branch name).
715 var base
: PullRef is writable
717 # Is this pull request merged?
718 var merged
: nullable Bool is writable
720 # Is this pull request mergeable?
721 var mergeable
: nullable Bool is writable
723 # Mergeable state of this pull request.
725 # See <https://developer.github.com/v3/pulls/#list-pull-requests>.
726 var mergeable_state
: nullable String is writable
728 # User that merged this pull request (if any).
729 var merged_by
: nullable User is writable
731 # Count of commits in this pull request.
732 var commits
: nullable Int is writable
735 var additions
: nullable Int is writable
737 # Deleted line count.
738 var deletions
: nullable Int is writable
740 # Changed files count.
741 var changed_files
: nullable Int is writable
744 var patch_url
: nullable String is writable
747 # A pull request reference (used for head and base).
751 # Label pointed by `self`.
752 var labl
: String is writable, serialize_as
("label")
754 # Reference pointed by `self`.
755 var ref
: String is writable
757 # Commit SHA pointed by `self`.
758 var sha
: String is writable
760 # User pointed by `self`.
761 var user
: User is writable
763 # Repo pointed by `self` (if any).
765 # A `null` value means the `repo` was deleted.
766 var repo
: nullable Repo is writable
771 # Should be accessed from `GithubAPI::get_label`.
773 # See <https://developer.github.com/v3/issues/labels/>.
778 var name
: String is writable
781 var color
: String is writable
784 # A Github milestone.
786 # Should be accessed from `GithubAPI::get_milestone`.
788 # See <https://developer.github.com/v3/issues/milestones/>.
792 # The milestone id on Github.
793 var number
: nullable Int = null is writable
796 var title
: String is writable
798 # Milestone long description.
799 var description
: nullable String is writable
801 # Count of opened issues linked to this milestone.
802 var open_issues
: nullable Int = null is writable
804 # Count of closed issues linked to this milestone.
805 var closed_issues
: nullable Int = null is writable
808 var state
: nullable String is writable
810 # Creation time as String.
811 var created_at
: nullable String is writable
813 # User that created this milestone.
814 var creator
: nullable User is writable
816 # Due time as String (if any).
817 var due_on
: nullable String is writable
819 # Last update time as String (if any).
820 var updated_at
: nullable String is writable
822 # Close time as String (if any).
823 var closed_at
: nullable String is writable
828 # There is two kinds of comments:
830 # * `CommitComment` are made on a commit page.
831 # * `IssueComment` are made on an issue or pull request page.
832 # * `PullComment` are made on the diff associated to a pull request.
833 abstract class Comment
836 # Identifier of this comment.
837 var id
: Int is writable
839 # User that made this comment.
840 var user
: User is writable
842 # Creation time as String.
843 var created_at
: String is writable
845 # Last update time as String (if any).
846 var updated_at
: nullable String is writable
849 var body
: String is writable
851 # Does the comment contain an acknowledgement (+1)
853 return body
.has
("\\+1\\b".to_re
) or body
.has
(":+1:") or body
.has
(":shipit:")
857 # A comment made on a commit.
863 var commit_id
: String is writable
865 # Position of the comment on the line.
866 var position
: nullable Int is writable
868 # Line of the comment.
869 var line
: nullable Int is writable
871 # Path of the commented file.
872 var path
: nullable String is writable
877 # Can contain sub-status for reviews, CI etc.
881 # Global state of this commit
882 var state
: nullable String = null is optional
, writable
884 # Sha of the commit this status is for
885 var sha
: nullable String = null is optional
, writable
887 # Repository the commit belongs to
888 var repository
: nullable Repo = null is optional
, writable
890 # All sub statuses (one for each check)
891 var statuses
= new Array[RepoStatus] is optional
, writable
893 # Total count of sub statuses
894 var total_count
: nullable Int = null is optional
, writable
897 # Sub status of a CommitStatus
899 # Represents a check applied to a commit (reviews, CI, ...).
903 # State of this check
904 var state
: nullable String = null is optional
, writable
906 # Description of this check
907 var description
: nullable String = null is optional
, writable
910 var target_url
: nullable String = null is optional
, writable
912 # Context this status is related to
914 # Used to hold the name of the check applied.
915 var context
: nullable String = null is optional
, writable
917 # Date when this status was created
918 var created_at
: nullable String = null is optional
, writable
920 # Last date this status was updated
921 var updated_at
: nullable String = null is optional
, writable
924 # Comments made on Github issue and pull request pages.
926 # Should be accessed from `GithubAPI::get_issue_comment`.
928 # See <https://developer.github.com/v3/issues/comments/>.
933 # Issue that contains `self`.
934 fun issue_number
: Int do return issue_url
.split
("/").last
.to_i
936 # Link to the issue document on API.
937 var issue_url
: String is writable
940 # Comments made on Github pull request diffs.
942 # Should be accessed from `GithubAPI::get_diff_comment`.
944 # See <https://developer.github.com/v3/pulls/comments/>.
949 # Pull request that contains `self`.
950 fun pull_number
: Int do return pull_request_url
.split
("/").last
.to_i
952 # Link to the pull request on API.
953 var pull_request_url
: String is writable
956 var diff_hunk
: String is writable
958 # Path of commented file.
959 var path
: String is writable
961 # Position of the comment on the file.
962 var position
: nullable Int is writable
964 # Original position in the diff.
965 var original_position
: Int is writable
967 # Commit referenced by this comment.
968 var commit_id
: String is writable
970 # Original commit id.
971 var original_commit_id
: String is writable
974 # An event that occurs on a Github `Issue`.
976 # Should be accessed from `GithubAPI::get_issue_event`.
978 # See <https://developer.github.com/v3/issues/events/>.
982 # Event id on Github.
983 var id
: Int is writable
985 # User that initiated the event.
986 var actor
: User is writable
988 # Creation time as String.
989 var created_at
: String is writable
992 var event
: String is writable
994 # Commit linked to this event (if any).
995 var commit_id
: nullable String is writable
997 # Label linked to this event (if any).
998 var labl
: nullable Label is writable, serialize_as
("label")
1000 # User linked to this event (if any).
1001 var assignee
: nullable User is writable
1003 # Milestone linked to this event (if any).
1004 var milestone
: nullable Milestone is writable
1006 # Rename linked to this event (if any).
1007 var rename
: nullable RenameAction is writable
1010 # A rename action maintains the name before and after a renaming action.
1014 # Name before renaming.
1015 var from
: String is writable
1017 # Name after renaming.
1018 var to
: String is writable
1022 # Should be accessed from `Repo::contrib_stats`.
1024 # See <https://developer.github.com/v3/repos/statistics/>.
1025 class ContributorStats
1029 redef type OTHER: ContributorStats
1031 # Github API client.
1032 var api
: GithubAPI is writable
1034 # User these statistics are about.
1035 var author
: User is writable
1037 # Total number of commit.
1038 var total
: Int is writable
1040 # Are of weeks of activity with detailed statistics.
1041 var weeks
: JsonArray is writable
1043 # ContributorStats can be compared on the total amount of commits.
1044 redef fun <(o
) do return total
< o
.total
1047 # A Github file representation.
1049 # Mostly a wrapper around a json object.
1054 var filename
: String is writable
1057 # A list of results returned buy `/search`
1061 # Total count with other pages
1062 var total_count
: Int
1064 # Does this page contain all the results?
1065 var incomplete_results
: Bool
1067 # Results in this page
1068 var items
: Array[Object]
1071 # JsonDeserializer specific for Github objects.
1072 class GithubDeserializer
1073 super JsonDeserializer
1075 private var pattern_base
= "https://api.github.com"
1077 # Url patterns to class names
1078 var url_patterns
: Map[Regex, String] is lazy
do
1079 var map
= new HashMap[Regex, String]
1080 map
["{pattern_base}/users/[^/]*$".to_re
] = "User"
1081 map
["{pattern_base}/repos/[^/]*/[^/]*$".to_re
] = "Repo"
1082 map
["{pattern_base}/repos/[^/]*/[^/]*/labels/[^/]+$".to_re
] = "Label"
1083 map
["{pattern_base}/repos/[^/]*/[^/]*/milestones/[0-9]+$".to_re
] = "Milestone"
1084 map
["{pattern_base}/repos/[^/]*/[^/]*/issues/[0-9]+$".to_re
] = "Issue"
1085 map
["{pattern_base}/repos/[^/]*/[^/]*/issues/comments/[0-9]+$".to_re
] = "IssueComment"
1086 map
["{pattern_base}/repos/[^/]*/[^/]*/issues/events/[0-9]+$".to_re
] = "IssueEvent"
1087 map
["{pattern_base}/repos/[^/]*/[^/]*/pulls/[0-9]+$".to_re
] = "PullRequest"
1088 map
["{pattern_base}/repos/[^/]*/[^/]*/pulls/comments/[0-9]+$".to_re
] = "PullComment"
1089 map
["{pattern_base}/repos/[^/]*/[^/]*/comments/[0-9]+$".to_re
] = "CommitComment"
1090 map
["{pattern_base}/repos/[^/]*/[^/]*/commits/[a-f0-9]+$".to_re
] = "Commit"
1091 map
["{pattern_base}/repos/[^/]*/[^/]*/commits/[a-f0-9]+/status$".to_re
] = "CommitStatus"
1092 map
["{pattern_base}/repos/[^/]*/[^/]*/statuses/[a-f0-9]+$".to_re
] = "RepoStatus"
1096 # Match `url` property in object to a class name
1097 fun url_heuristic
(raw
: Map[String, nullable Object]): nullable String do
1098 if not raw
.has_key
("url") then return null
1100 var url
= raw
["url"].as(String)
1101 for re
, class_name
in url_patterns
do
1102 if url
.has
(re
) then return class_name
1107 redef fun class_name_heuristic
(raw
) do
1109 var class_name
= url_heuristic
(raw
)
1110 if class_name
!= null then return class_name
1112 # print raw.serialize_to_json(true, true) # debug
1114 # Use properties heuristics
1115 if raw
.has_key
("name") and raw
.has_key
("commit") then
1117 else if raw
.has_key
("total_count") and raw
.has_key
("items") then
1118 return "SearchResults"
1123 redef fun deserialize_class
(name
) do
1124 if name
== "Issue" then
1125 var issue
= super.as(Issue)
1126 if path
.last
.has_key
("pull_request") then
1127 issue
.is_pull_request
= true
1130 else if name
== "Commit" then
1131 var commit
= super.as(Commit)
1132 var git_commit
= commit
.commit
1133 if git_commit
!= null then commit
.message
= git_commit
.message
1140 # Gets the Github token from `git` configuration
1142 # Return the value of `git config --get github.oauthtoken`
1143 # or `""` if no key exists.
1144 fun get_github_oauth
: String
1146 var p
= new ProcessReader("git", "config", "--get", "github.oauthtoken")
1147 var token
= p
.read_line