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.
23 intrude import json
::serialization_read
25 # Client to Github API
27 # To access the API you need an instance of a `GithubAPI` client.
30 # # Get Github authentification token.
31 # var token = get_github_oauth
32 # assert not token.is_empty
35 # var api = new GithubAPI(token)
38 # The API client allows you to get Github API entities.
41 # var repo = api.load_repo("nitlang/nit")
43 # assert repo.name == "nit"
45 # var user = api.load_user("Morriar")
47 # assert user.login == "Morriar"
51 # Github API OAuth token
53 # To access your private ressources, you must
54 # [authenticate](https://developer.github.com/guides/basics-of-authentication/).
56 # For client applications, Github recommands to use the
57 # [OAuth tokens](https://developer.github.com/v3/oauth/) authentification method.
61 # Be aware that there is [rate limits](https://developer.github.com/v3/rate_limit/)
62 # associated to the key.
65 # Github API base url.
67 # Default is `https://api.github.com` and should not be changed.
68 var api_url
= "https://api.github.com"
70 # User agent used for HTTP requests.
72 # Default is `nit_github_api`.
74 # See <https://developer.github.com/v3/#user-agent-required>
75 var user_agent
= "nit_github_api"
79 # Internal Curl instance used to perform API calls.
80 private var ghcurl
: GithubCurl is noinit
84 # * `0`: only errors (default)
86 var verbose_lvl
= 0 is public
writable
89 ghcurl
= new GithubCurl(auth
, user_agent
)
92 # Deserialize an object
93 fun deserialize
(string
: String): nullable Object do
94 var deserializer
= new GithubDeserializer(string
)
95 var res
= deserializer
.deserialize
96 # print deserializer.errors.join("\n") # DEBUG
100 # Execute a GET request on Github API.
102 # This method returns raw json data.
103 # See other `load_*` methods to use more expressive types.
106 # var api = new GithubAPI(get_github_oauth)
107 # var obj = api.get("/repos/nitlang/nit")
108 # assert obj isa JsonObject
109 # assert obj["name"] == "nit"
112 # Returns `null` in case of `error`.
115 # obj = api.get("/foo/bar/baz")
117 # assert api.was_error
118 # var err = api.last_error
119 # assert err isa GithubError
120 # assert err.name == "GithubAPIError"
121 # assert err.message == "Not Found"
123 fun get
(path
: String): nullable Serializable do
124 path
= sanitize_uri
(path
)
125 var res
= ghcurl
.get_and_parse
("{api_url}{path}")
126 if res
isa Error then
135 # Display a message depending on `verbose_lvl`.
136 fun message
(lvl
: Int, message
: String) do
137 if lvl
<= verbose_lvl
then print message
140 # Escape `uri` in an acceptable format for Github.
141 private fun sanitize_uri
(uri
: String): String do
142 # TODO better URI escape.
143 return uri
.replace
(" ", "%20")
146 # Last error occured during Github API communications.
147 var last_error
: nullable Error = null is public
writable
149 # Does the last request provoqued an error?
150 var was_error
= false is protected writable
152 # Load the json object from Github.
153 # See `GithubEntity::load_from_github`.
154 protected fun load_from_github
(key
: String): nullable GithubEntity do
155 message
(1, "Get {key} (github)")
157 if was_error
then return null
158 return deserialize
(res
.as(JsonObject).to_json
).as(nullable GithubEntity)
161 # Get the Github logged user from `auth` token.
163 # Loads the `User` from the API or returns `null` if the user cannot be found.
166 # var api = new GithubAPI(get_github_oauth)
167 # var user = api.load_auth_user
168 # assert user.login == "Morriar"
170 fun load_auth_user
: nullable User do
171 var user
= load_from_github
("/user")
172 if was_error
then return null
173 return user
.as(nullable User)
176 # Get the Github user with `login`
178 # Loads the `User` from the API or returns `null` if the user cannot be found.
181 # var api = new GithubAPI(get_github_oauth)
182 # var user = api.load_user("Morriar")
183 # print user or else "null"
184 # assert user.login == "Morriar"
186 fun load_user
(login
: String): nullable User do
187 return load_from_github
("/users/{login}").as(nullable User)
190 # Get the Github repo with `full_name`.
192 # Loads the `Repo` from the API or returns `null` if the repo cannot be found.
195 # var api = new GithubAPI(get_github_oauth)
196 # var repo = api.load_repo("nitlang/nit")
197 # assert repo.name == "nit"
198 # assert repo.owner.login == "nitlang"
199 # assert repo.default_branch == "master"
201 fun load_repo
(full_name
: String): nullable Repo do
202 return load_from_github
("/repos/{full_name}").as(nullable Repo)
205 # List of branches associated with their names.
206 fun load_repo_branches
(repo
: Repo): Array[Branch] do
207 message
(1, "Get branches for {repo.full_name}")
208 var array
= get
("/repos/{repo.full_name}/branches")
209 var res
= new Array[Branch]
210 if not array
isa JsonArray then return res
211 var deser
= deserialize
(array
.to_json
)
212 if not deser
isa Array[Object] then return res
# empty array
213 for branch
in deser
do
214 if not branch
isa Branch then continue
220 # List of issues associated with their ids.
221 fun load_repo_issues
(repo
: Repo): Array[Issue] do
222 message
(1, "Get issues for {repo.full_name}")
223 var res
= new Array[Issue]
224 var issue
= load_repo_last_issue
(repo
)
225 if issue
== null then return res
227 while issue
!= null and issue
.number
> 1 do
228 issue
= load_issue
(repo
, issue
.number
- 1)
229 if issue
== null then continue
235 # Search issues in this repo form an advanced query.
240 # var issues = repo.search_issues("is:open label:need_review")
243 # See <https://developer.github.com/v3/search/#search-issues>.
244 fun search_repo_issues
(repo
: Repo, query
: String): Array[Issue] do
245 query
= "/search/issues?q={query} repo:{repo.full_name}"
246 var res
= new Array[Issue]
247 var response
= get
(query
)
248 if was_error
then return res
249 var arr
= response
.as(JsonObject)["items"].as(JsonArray)
250 return deserialize
(arr
.to_json
).as(Array[Issue])
253 # Get the last published issue.
254 fun load_repo_last_issue
(repo
: Repo): nullable Issue do
255 var array
= get
("/repos/{repo.full_name}/issues")
256 if not array
isa JsonArray then return null
257 if array
.is_empty
then return null
258 var obj
= array
.first
259 if not obj
isa JsonObject then return null
260 return deserialize
(obj
.to_json
).as(nullable Issue)
263 # List of labels associated with their names.
264 fun load_repo_labels
(repo
: Repo): Array[Label] do
265 message
(1, "Get labels for {repo.full_name}")
266 var array
= get
("repos/{repo.full_name}/labels")
267 if not array
isa JsonArray then return new Array[Label]
268 return deserialize
(array
.to_json
).as(Array[Label])
271 # List of milestones associated with their ids.
272 fun load_repo_milestones
(repo
: Repo): Array[Milestone] do
273 message
(1, "Get milestones for {repo.full_name}")
274 var array
= get
("/repos/{repo.full_name}/milestones")
275 if not array
isa JsonArray then return new Array[Milestone]
276 return deserialize
(array
.to_json
).as(Array[Milestone])
279 # List of pull-requests associated with their ids.
281 # Implementation notes: because PR numbers are not consecutive,
282 # PR are loaded from pages.
283 # See: https://developer.github.com/v3/pulls/#list-pull-requests
284 fun load_repo_pulls
(repo
: Repo): Array[PullRequest] do
285 message
(1, "Get pulls for {repo.full_name}")
286 var key
= "/repos/{repo.full_name}"
287 var res
= new Array[PullRequest]
290 var array
= get
("{key}/pulls?page={page}").as(JsonArray)
291 if array
.is_empty
then break
293 if not obj
isa JsonObject then continue
294 var pr
= deserialize
(array
.to_json
).as(nullable PullRequest)
295 if pr
== null then continue
303 # List of contributor related statistics.
304 fun load_repo_contrib_stats
(repo
: Repo): Array[ContributorStats] do
305 message
(1, "Get contributor stats for {repo.full_name}")
306 var res
= new Array[ContributorStats]
307 var array
= get
("/repos/{repo.full_name}/stats/contributors")
308 if not array
isa JsonArray then return res
309 return deserialize
(array
.to_json
).as(Array[ContributorStats])
312 # Get the Github branch with `name`.
314 # Returns `null` if the branch cannot be found.
317 # var api = new GithubAPI(get_github_oauth)
318 # var repo = api.load_repo("nitlang/nit")
319 # assert repo != null
320 # var branch = api.load_branch(repo, "master")
321 # assert branch.name == "master"
322 # assert branch.commit isa Commit
324 fun load_branch
(repo
: Repo, name
: String): nullable Branch do
325 return load_from_github
("/repos/{repo.full_name}/branches/{name}").as(nullable Branch)
328 # List all commits in `self`.
330 # This can be long depending on the branch size.
331 # Commit are returned in an unspecified order.
332 fun load_branch_commits
(branch
: Branch): Array[Commit] do
333 var res
= new Array[Commit]
334 var done
= new HashSet[String]
335 var todos
= new Array[Commit]
336 todos
.add branch
.commit
338 if todos
.is_empty
then break
339 var commit
= todos
.pop
340 if done
.has
(commit
.sha
) then continue
343 var parents
= commit
.parents
344 if parents
== null then continue
345 for parent
in parents
do
352 # Get the Github commit with `sha`.
354 # Returns `null` if the commit cannot be found.
357 # var api = new GithubAPI(get_github_oauth)
358 # var repo = api.load_repo("nitlang/nit")
359 # assert repo != null
360 # var commit = api.load_commit(repo, "64ce1f")
361 # assert commit isa Commit
363 fun load_commit
(repo
: Repo, sha
: String): nullable Commit do
364 return load_from_github
("/repos/{repo.full_name}/commits/{sha}").as(nullable Commit)
367 # Get the Github issue #`number`.
369 # Returns `null` if the issue cannot be found.
372 # var api = new GithubAPI(get_github_oauth)
373 # var repo = api.load_repo("nitlang/nit")
374 # assert repo != null
375 # var issue = api.load_issue(repo, 1)
376 # assert issue.title == "Doc"
378 fun load_issue
(repo
: Repo, number
: Int): nullable Issue do
379 return load_from_github
("/repos/{repo.full_name}/issues/{number}").as(nullable Issue)
382 # List of event on this issue.
383 fun load_issue_comments
(repo
: Repo, issue
: Issue): Array[IssueComment] do
384 var res
= new Array[IssueComment]
385 var count
= issue
.comments
or else 0
388 var array
= get
("/repos/{repo.full_name}/issues/{issue.number}/comments?page={page}")
389 if not array
isa JsonArray then break
390 if array
.is_empty
then break
392 if not obj
isa JsonObject then continue
393 var id
= obj
["id"].as(Int)
394 var comment
= load_issue_comment
(repo
, id
)
395 if comment
== null then continue
398 if res
.length
>= count
then break
404 # List of events on this issue.
405 fun load_issue_events
(repo
: Repo, issue
: Issue): Array[IssueEvent] do
406 var res
= new Array[IssueEvent]
407 var key
= "/repos/{repo.full_name}/issues/{issue.number}"
410 var array
= get
("{key}/events?page={page}")
411 if not array
isa JsonArray or array
.is_empty
then break
413 if not obj
isa JsonObject then continue
414 var event
= deserialize
(obj
.to_json
).as(nullable IssueEvent)
415 if event
== null then continue
423 # Get the Github pull request #`number`.
425 # Returns `null` if the pull request cannot be found.
428 # var api = new GithubAPI(get_github_oauth)
429 # var repo = api.load_repo("nitlang/nit")
430 # assert repo != null
431 # var pull = api.load_pull(repo, 1)
432 # assert pull.title == "Doc"
433 # assert pull.user.login == "Morriar"
435 fun load_pull
(repo
: Repo, number
: Int): nullable PullRequest do
436 return load_from_github
("/repos/{repo.full_name}/pulls/{number}").as(nullable PullRequest)
439 # Get the Github label with `name`.
441 # Returns `null` if the label cannot be found.
444 # var api = new GithubAPI(get_github_oauth)
445 # var repo = api.load_repo("nitlang/nit")
446 # assert repo != null
447 # var labl = api.load_label(repo, "ok_will_merge")
448 # assert labl != null
450 fun load_label
(repo
: Repo, name
: String): nullable Label do
451 return load_from_github
("/repos/{repo.full_name}/labels/{name}").as(nullable Label)
454 # Get the Github milestone with `id`.
456 # Returns `null` if the milestone cannot be found.
459 # var api = new GithubAPI(get_github_oauth)
460 # var repo = api.load_repo("nitlang/nit")
461 # assert repo != null
462 # var stone = api.load_milestone(repo, 4)
463 # assert stone.title == "v1.0prealpha"
465 fun load_milestone
(repo
: Repo, id
: Int): nullable Milestone do
466 return load_from_github
("/repos/{repo.full_name}/milestones/{id}").as(nullable Milestone)
469 # Get the Github issue event with `id`.
471 # Returns `null` if the event cannot be found.
474 # var api = new GithubAPI(get_github_oauth)
475 # var repo = api.load_repo("nitlang/nit")
476 # assert repo isa Repo
477 # var event = api.load_issue_event(repo, 199674194)
478 # assert event isa IssueEvent
479 # assert event.actor.login == "privat"
480 # assert event.event == "labeled"
481 # assert event.labl isa Label
482 # assert event.labl.name == "need_review"
484 fun load_issue_event
(repo
: Repo, id
: Int): nullable IssueEvent do
485 return load_from_github
("/repos/{repo.full_name}/issues/events/{id}").as(nullable IssueEvent)
488 # Get the Github commit comment with `id`.
490 # Returns `null` if the comment cannot be found.
493 # var api = new GithubAPI(get_github_oauth)
494 # var repo = api.load_repo("nitlang/nit")
495 # assert repo != null
496 # var comment = api.load_commit_comment(repo, 8982707)
497 # assert comment.user.login == "Morriar"
498 # assert comment.body == "For testing purposes...\n"
499 # assert comment.commit_id == "7eacb86d1e24b7e72bc9ac869bf7182c0300ceca"
501 fun load_commit_comment
(repo
: Repo, id
: Int): nullable CommitComment do
502 return load_from_github
("/repos/{repo.full_name}/comments/{id}").as(nullable CommitComment)
505 # Get the Github issue comment with `id`.
507 # Returns `null` if the comment cannot be found.
510 # var api = new GithubAPI(get_github_oauth)
511 # var repo = api.load_repo("nitlang/nit")
512 # assert repo != null
513 # var comment = api.load_issue_comment(repo, 6020149)
514 # assert comment.user.login == "privat"
515 # assert comment.created_at.to_s == "2012-05-30T20:16:54Z"
516 # assert comment.issue_number == 10
518 fun load_issue_comment
(repo
: Repo, id
: Int): nullable IssueComment do
519 return load_from_github
("/repos/{repo.full_name}/issues/comments/{id}").as(nullable IssueComment)
522 # Get the Github diff comment with `id`.
524 # Returns `null` if the comment cannot be found.
527 # var api = new GithubAPI(get_github_oauth)
528 # var repo = api.load_repo("nitlang/nit")
529 # assert repo != null
530 # var comment = api.load_review_comment(repo, 21010363)
531 # assert comment.path == "src/modelize/modelize_property.nit"
532 # assert comment.original_position == 26
533 # assert comment.pull_number == 945
535 fun load_review_comment
(repo
: Repo, id
: Int): nullable ReviewComment do
536 return load_from_github
("/repos/{repo.full_name}/pulls/comments/{id}").as(nullable ReviewComment)
540 # Something returned by the Github API.
542 # Mainly a Nit wrapper around a JSON objet.
543 abstract class GithubEntity
547 var html_url
: nullable String is writable
552 # Provides access to [Github user data](https://developer.github.com/v3/users/).
553 # Should be accessed from `GithubAPI::load_user`.
559 var login
: String is writable
561 # Avatar image url for this user.
562 var avatar_url
: nullable String is writable
564 # User public name if any.
565 var name
: nullable String is writable
567 # User public email if any.
568 var email
: nullable String is writable
570 # User public blog if any.
571 var blog
: nullable String is writable
574 # A Github repository.
576 # Provides access to [Github repo data](https://developer.github.com/v3/repos/).
577 # Should be accessed from `GithubAPI::load_repo`.
582 # Repo full name on Github.
583 var full_name
: String is writable
585 # Repo short name on Github.
586 var name
: String is writable
588 # Get the repo owner.
589 var owner
: User is writable
591 # Repo default branch name.
592 var default_branch
: String is writable
597 # Should be accessed from `GithubAPI::load_branch`.
599 # See <https://developer.github.com/v3/repos/#list-branches>.
605 var name
: String is writable
607 # Get the last commit of `self`.
608 var commit
: Commit is writable
613 # Should be accessed from `GithubAPI::load_commit`.
615 # See <https://developer.github.com/v3/repos/commits/>.
621 var sha
: String is writable
623 # Parent commits of `self`.
624 var parents
: nullable Array[Commit] = null is writable
626 # Author of the commit.
627 var author
: nullable GitUser is writable
629 # Committer of the commit.
630 var committer
: nullable GitUser is writable
632 # Authoring date as String.
633 var author_date
: nullable String is writable
635 # Authoring date as ISODate.
636 fun iso_author_date
: nullable ISODate do
637 var author_date
= self.author_date
638 if author_date
== null then return null
639 return new ISODate.from_string
(author_date
)
642 # Commit date as String.
643 var commit_date
: nullable String is writable
645 # Commit date as ISODate.
646 fun iso_commit_date
: nullable ISODate do
647 var commit_date
= self.commit_date
648 if commit_date
== null then return null
649 return new ISODate.from_string
(commit_date
)
652 # List files staged in this commit.
653 var files
: nullable Array[GithubFile] = null is optional
, writable
656 var message
: nullable String is writable
658 # Git commit representation linked to this commit.
659 var commit
: nullable GitCommit
662 # A Git Commit representation
668 var sha
: nullable String is writable
670 # Parent commits of `self`.
671 var parents
: nullable Array[GitCommit] = null is writable
673 # Author of the commit.
674 var author
: nullable GitUser is writable
676 # Committer of the commit.
677 var committer
: nullable GitUser is writable
680 var message
: nullable String is writable
683 # Git user authoring data
689 var date
: nullable String = null is writable
691 # Authoring date as ISODate.
692 fun iso_date
: nullable ISODate do
694 if date
== null then return null
695 return new ISODate.from_string
(date
)
701 # Should be accessed from `GithubAPI::load_issue`.
703 # See <https://developer.github.com/v3/issues/>.
709 var number
: Int is writable
712 var id
: nullable Int is writable
715 var title
: String is writable
717 # User that created this issue.
718 var user
: nullable User is writable
720 # List of labels on this issue associated to their names.
721 var labels
: nullable Array[Label] is writable
723 # State of the issue on Github.
724 var state
: String is writable
726 # Is the issue locked?
727 var locked
: nullable Bool is writable
729 # Assigned `User` (if any).
730 var assignee
: nullable User is writable
732 # `Milestone` (if any).
733 var milestone
: nullable Milestone is writable
735 # Number of comments on this issue.
736 var comments
: nullable Int is writable
738 # Creation time as String.
739 var created_at
: String is writable
741 # Creation time as ISODate.
742 fun iso_created_at
: ISODate do
743 return new ISODate.from_string
(created_at
)
746 # Last update time as String (if any).
747 var updated_at
: nullable String is writable
749 # Last update date as ISODate.
750 fun iso_updated_at
: nullable ISODate do
751 var updated_at
= self.updated_at
752 if updated_at
== null then return null
753 return new ISODate.from_string
(updated_at
)
756 # Close time as String (if any).
757 var closed_at
: nullable String is writable
759 # Close time as ISODate.
760 fun iso_closed_at
: nullable ISODate do
761 var closed_at
= self.closed_at
762 if closed_at
== null then return null
763 return new ISODate.from_string
(closed_at
)
766 # Full description of the issue.
767 var body
: nullable String is writable
769 # User that closed this issue (if any).
770 var closed_by
: nullable User is writable
772 # Is this issue linked to a pull request?
773 var is_pull_request
: Bool = false is writable
776 # A Github pull request.
778 # Should be accessed from `GithubAPI::load_pull`.
780 # PullRequest are basically Issues with more data.
781 # See <https://developer.github.com/v3/pulls/>.
786 # Merge time as String (if any).
787 var merged_at
: nullable String is writable
789 # Merge time as ISODate.
790 fun iso_merged_at
: nullable ISODate do
791 var merged_at
= self.merged_at
792 if merged_at
== null then return null
793 return new ISODate.from_string
(merged_at
)
797 var merge_commit_sha
: nullable String is writable
799 # Count of comments made on the pull request diff.
800 var review_comments
: Int is writable
802 # Pull request head (can be a commit SHA or a branch name).
803 var head
: PullRef is writable
805 # Pull request base (can be a commit SHA or a branch name).
806 var base
: PullRef is writable
808 # Is this pull request merged?
809 var merged
: Bool is writable
811 # Is this pull request mergeable?
812 var mergeable
: nullable Bool is writable
814 # Mergeable state of this pull request.
816 # See <https://developer.github.com/v3/pulls/#list-pull-requests>.
817 var mergeable_state
: String is writable
819 # User that merged this pull request (if any).
820 var merged_by
: nullable User is writable
822 # Count of commits in this pull request.
823 var commits
: Int is writable
826 var additions
: Int is writable
828 # Deleted line count.
829 var deletions
: Int is writable
831 # Changed files count.
832 var changed_files
: Int is writable
835 var patch_url
: nullable String is writable
838 # A pull request reference (used for head and base).
842 # Label pointed by `self`.
843 var labl
: String is writable, serialize_as
("label")
845 # Reference pointed by `self`.
846 var ref
: String is writable
848 # Commit SHA pointed by `self`.
849 var sha
: String is writable
851 # User pointed by `self`.
852 var user
: User is writable
854 # Repo pointed by `self` (if any).
856 # A `null` value means the `repo` was deleted.
857 var repo
: nullable Repo is writable
862 # Should be accessed from `GithubAPI::load_label`.
864 # See <https://developer.github.com/v3/issues/labels/>.
870 var name
: String is writable
873 var color
: String is writable
876 # A Github milestone.
878 # Should be accessed from `GithubAPI::load_milestone`.
880 # See <https://developer.github.com/v3/issues/milestones/>.
885 # The milestone id on Github.
886 var number
: nullable Int = null is writable
889 var title
: String is writable
891 # Milestone long description.
892 var description
: nullable String is writable
894 # Count of opened issues linked to this milestone.
895 var open_issues
: nullable Int = null is writable
897 # Count of closed issues linked to this milestone.
898 var closed_issues
: nullable Int = null is writable
901 var state
: nullable String is writable
903 # Creation time as String.
904 var created_at
: nullable String is writable
906 # Creation time as ISODate.
907 fun iso_created_at
: nullable ISODate do
908 var created_at
= self.created_at
909 if created_at
== null then return null
910 return new ISODate.from_string
(created_at
)
913 # User that created this milestone.
914 var creator
: nullable User is writable
916 # Due time as String (if any).
917 var due_on
: nullable String is writable
919 # Due time in ISODate format (if any).
920 fun iso_due_on
: nullable ISODate do
921 var due_on
= self.due_on
922 if due_on
== null then return null
923 return new ISODate.from_string
(due_on
)
926 # Last update time as String (if any).
927 var updated_at
: nullable String is writable
929 # Last update date as ISODate.
930 fun iso_updated_at
: nullable ISODate do
931 var updated_at
= self.updated_at
932 if updated_at
== null then return null
933 return new ISODate.from_string
(updated_at
)
936 # Close time as String (if any).
937 var closed_at
: nullable String is writable
939 # Close time as ISODate.
940 fun iso_closed_at
: nullable ISODate do
941 var closed_at
= self.closed_at
942 if closed_at
== null then return null
943 return new ISODate.from_string
(closed_at
)
949 # There is two kinds of comments:
951 # * `CommitComment` are made on a commit page.
952 # * `IssueComment` are made on an issue or pull request page.
953 # * `ReviewComment` are made on the diff associated to a pull request.
954 abstract class Comment
958 # Identifier of this comment.
959 var id
: Int is writable
961 # User that made this comment.
962 var user
: User is writable
964 # Creation time as String.
965 var created_at
: String is writable
967 # Creation time as ISODate.
968 fun iso_created_at
: nullable ISODate do
969 return new ISODate.from_string
(created_at
)
972 # Last update time as String (if any).
973 var updated_at
: nullable String is writable
975 # Last update date as ISODate.
976 fun iso_updated_at
: nullable ISODate do
977 var updated_at
= self.updated_at
978 if updated_at
== null then return null
979 return new ISODate.from_string
(updated_at
)
983 var body
: String is writable
985 # Does the comment contain an acknowledgement (+1)
987 return body
.has
("\\+1\\b".to_re
) or body
.has
(":+1:") or body
.has
(":shipit:")
991 # A comment made on a commit.
997 var commit_id
: String is writable
999 # Position of the comment on the line.
1000 var position
: nullable Int is writable
1002 # Line of the comment.
1003 var line
: nullable Int is writable
1005 # Path of the commented file.
1006 var path
: nullable String is writable
1009 # Comments made on Github issue and pull request pages.
1011 # Should be accessed from `GithubAPI::load_issue_comment`.
1013 # See <https://developer.github.com/v3/issues/comments/>.
1018 # Issue that contains `self`.
1019 fun issue_number
: Int do return issue_url
.split
("/").last
.to_i
1021 # Link to the issue document on API.
1022 var issue_url
: String is writable
1025 # Comments made on Github pull request diffs.
1027 # Should be accessed from `GithubAPI::load_diff_comment`.
1029 # See <https://developer.github.com/v3/pulls/comments/>.
1034 # Pull request that contains `self`.
1035 fun pull_number
: Int do return pull_request_url
.split
("/").last
.to_i
1037 # Link to the pull request on API.
1038 var pull_request_url
: String is writable
1041 var diff_hunk
: String is writable
1043 # Path of commented file.
1044 var path
: String is writable
1046 # Position of the comment on the file.
1047 var position
: nullable Int is writable
1049 # Original position in the diff.
1050 var original_position
: Int is writable
1052 # Commit referenced by this comment.
1053 var commit_id
: String is writable
1055 # Original commit id.
1056 var original_commit_id
: String is writable
1059 # An event that occurs on a Github `Issue`.
1061 # Should be accessed from `GithubAPI::load_issue_event`.
1063 # See <https://developer.github.com/v3/issues/events/>.
1068 # Event id on Github.
1069 var id
: Int is writable
1071 # User that initiated the event.
1072 var actor
: User is writable
1074 # Creation time as String.
1075 var created_at
: String is writable
1077 # Creation time as ISODate.
1078 fun iso_created_at
: nullable ISODate do
1079 return new ISODate.from_string
(created_at
)
1083 var event
: String is writable
1085 # Commit linked to this event (if any).
1086 var commit_id
: nullable String is writable
1088 # Label linked to this event (if any).
1089 var labl
: nullable Label is writable, serialize_as
("label")
1091 # User linked to this event (if any).
1092 var assignee
: nullable User is writable
1094 # Milestone linked to this event (if any).
1095 var milestone
: nullable Milestone is writable
1097 # Rename linked to this event (if any).
1098 var rename
: nullable RenameAction is writable
1101 # A rename action maintains the name before and after a renaming action.
1105 # Name before renaming.
1106 var from
: String is writable
1108 # Name after renaming.
1109 var to
: String is writable
1113 # Should be accessed from `Repo::contrib_stats`.
1115 # See <https://developer.github.com/v3/repos/statistics/>.
1116 class ContributorStats
1120 redef type OTHER: ContributorStats
1122 # Github API client.
1123 var api
: GithubAPI is writable
1125 # User these statistics are about.
1126 var author
: User is writable
1128 # Total number of commit.
1129 var total
: Int is writable
1131 # Are of weeks of activity with detailed statistics.
1132 var weeks
: JsonArray is writable
1134 # ContributorStats can be compared on the total amount of commits.
1135 redef fun <(o
) do return total
< o
.total
1138 # A Github file representation.
1140 # Mostly a wrapper around a json object.
1145 var filename
: String is writable
1148 # Make ISO Datew serilizable
1153 # JsonDeserializer specific for Github objects.
1154 class GithubDeserializer
1155 super JsonDeserializer
1157 redef fun class_name_heuristic
(json_object
) do
1158 if json_object
.has_key
("login") then
1160 else if json_object
.has_key
("full_name") then
1162 else if json_object
.has_key
("name") and json_object
.has_key
("commit") then
1164 else if json_object
.has_key
("sha") and json_object
.has_key
("ref") then
1166 else if (json_object
.has_key
("sha") and json_object
.has_key
("commit")) or (json_object
.has_key
("id") and json_object
.has_key
("tree_id")) then
1168 else if json_object
.has_key
("sha") and json_object
.has_key
("tree") then
1170 else if json_object
.has_key
("name") and json_object
.has_key
("date") then
1172 else if json_object
.has_key
("number") and json_object
.has_key
("patch_url") then
1173 return "PullRequest"
1174 else if json_object
.has_key
("open_issues") and json_object
.has_key
("closed_issues") then
1176 else if json_object
.has_key
("number") and json_object
.has_key
("title") then
1178 else if json_object
.has_key
("color") then
1180 else if json_object
.has_key
("event") then
1182 else if json_object
.has_key
("original_commit_id") then
1183 return "ReviewComment"
1184 else if json_object
.has_key
("commit_id") then
1185 return "CommitComment"
1186 else if json_object
.has_key
("issue_url") then
1187 return "IssueComment"
1192 redef fun deserialize_class
(name
) do
1193 if name
== "Issue" then
1194 var issue
= super.as(Issue)
1195 if path
.last
.has_key
("pull_request") then
1196 issue
.is_pull_request
= true
1199 else if name
== "Commit" then
1200 var commit
= super.as(Commit)
1201 var git_commit
= commit
.commit
1202 if git_commit
!= null then commit
.message
= git_commit
.message