horn_of_plenty 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE.txt +19 -0
  5. data/README.md +36 -0
  6. data/lib/horn_of_plenty.rb +22 -0
  7. data/lib/horn_of_plenty/adapters/github/client.rb +82 -0
  8. data/lib/horn_of_plenty/adapters/github/collections/card.rb +46 -0
  9. data/lib/horn_of_plenty/adapters/github/configuration.rb +38 -0
  10. data/lib/horn_of_plenty/adapters/github/error.rb +44 -0
  11. data/lib/horn_of_plenty/adapters/github/parsers/board.rb +52 -0
  12. data/lib/horn_of_plenty/adapters/github/parsers/card.rb +91 -0
  13. data/lib/horn_of_plenty/adapters/github/parsers/issue.rb +95 -0
  14. data/lib/horn_of_plenty/adapters/github/parsers/lane.rb +50 -0
  15. data/lib/horn_of_plenty/adapters/github/parsers/pull_request.rb +38 -0
  16. data/lib/horn_of_plenty/adapters/github/queries/list_boards.rb +18 -0
  17. data/lib/horn_of_plenty/adapters/github/queries/list_cards.rb +19 -0
  18. data/lib/horn_of_plenty/adapters/github/queries/list_issues.rb +22 -0
  19. data/lib/horn_of_plenty/adapters/github/queries/list_lanes.rb +19 -0
  20. data/lib/horn_of_plenty/adapters/github/queries/list_pull_requests.rb +22 -0
  21. data/lib/horn_of_plenty/adapters/github/repositories/board.rb +24 -0
  22. data/lib/horn_of_plenty/adapters/github/repositories/card.rb +24 -0
  23. data/lib/horn_of_plenty/adapters/github/repositories/issue.rb +24 -0
  24. data/lib/horn_of_plenty/adapters/github/repositories/lane.rb +24 -0
  25. data/lib/horn_of_plenty/adapters/github/repositories/pull_request.rb +24 -0
  26. data/lib/horn_of_plenty/adapters/github/requests/list_boards.rb +50 -0
  27. data/lib/horn_of_plenty/adapters/github/requests/list_cards.rb +52 -0
  28. data/lib/horn_of_plenty/adapters/github/requests/list_issues.rb +50 -0
  29. data/lib/horn_of_plenty/adapters/github/requests/list_lanes.rb +52 -0
  30. data/lib/horn_of_plenty/adapters/github/requests/list_pull_requests.rb +50 -0
  31. data/lib/horn_of_plenty/adapters/github/response.rb +16 -0
  32. data/lib/horn_of_plenty/adapters/github/responses/list_boards.rb +17 -0
  33. data/lib/horn_of_plenty/adapters/github/responses/list_cards.rb +23 -0
  34. data/lib/horn_of_plenty/adapters/github/responses/list_issues.rb +18 -0
  35. data/lib/horn_of_plenty/adapters/github/responses/list_lanes.rb +17 -0
  36. data/lib/horn_of_plenty/adapters/github/responses/list_pull_requests.rb +17 -0
  37. data/lib/horn_of_plenty/collection.rb +60 -0
  38. data/lib/horn_of_plenty/core_ext/string.rb +95 -0
  39. data/lib/horn_of_plenty/models/board.rb +32 -0
  40. data/lib/horn_of_plenty/models/card.rb +51 -0
  41. data/lib/horn_of_plenty/models/issue.rb +46 -0
  42. data/lib/horn_of_plenty/models/lane.rb +30 -0
  43. data/lib/horn_of_plenty/models/parsable.rb +44 -0
  44. data/lib/horn_of_plenty/models/pull_request.rb +12 -0
  45. data/lib/horn_of_plenty/null_objects/board.rb +10 -0
  46. data/lib/horn_of_plenty/null_objects/card.rb +10 -0
  47. data/lib/horn_of_plenty/null_objects/issue.rb +10 -0
  48. data/lib/horn_of_plenty/null_objects/lane.rb +10 -0
  49. data/lib/horn_of_plenty/null_objects/pull_request.rb +10 -0
  50. data/lib/horn_of_plenty/paginator.rb +109 -0
  51. data/lib/horn_of_plenty/parsers/hash.rb +95 -0
  52. data/lib/horn_of_plenty/queries/fetch.rb +36 -0
  53. data/lib/horn_of_plenty/repositories/board.rb +26 -0
  54. data/lib/horn_of_plenty/repositories/card.rb +26 -0
  55. data/lib/horn_of_plenty/repositories/issue.rb +26 -0
  56. data/lib/horn_of_plenty/repositories/lane.rb +26 -0
  57. data/lib/horn_of_plenty/repositories/pull_request.rb +26 -0
  58. data/lib/horn_of_plenty/repository.rb +29 -0
  59. data/lib/horn_of_plenty/request.rb +32 -0
  60. data/lib/horn_of_plenty/response.rb +44 -0
  61. data/lib/horn_of_plenty/version.rb +4 -0
  62. data/spec/fixtures/responses/board_github.json +29 -0
  63. data/spec/fixtures/responses/card_github.json +7 -0
  64. data/spec/fixtures/responses/issue_github.json +163 -0
  65. data/spec/fixtures/responses/lane_github.json +7 -0
  66. data/spec/fixtures/responses/pull_request_github.json +361 -0
  67. data/spec/lib/horn_of_plenty/adapters/github/client_spec.rb +12 -0
  68. data/spec/lib/horn_of_plenty/adapters/github/collections/card_spec.rb +14 -0
  69. data/spec/lib/horn_of_plenty/adapters/github/configuration_spec.rb +12 -0
  70. data/spec/lib/horn_of_plenty/adapters/github/error_spec.rb +35 -0
  71. data/spec/lib/horn_of_plenty/adapters/github/parsers/board_spec.rb +39 -0
  72. data/spec/lib/horn_of_plenty/adapters/github/parsers/card_spec.rb +64 -0
  73. data/spec/lib/horn_of_plenty/adapters/github/parsers/issue_spec.rb +47 -0
  74. data/spec/lib/horn_of_plenty/adapters/github/parsers/lane_spec.rb +38 -0
  75. data/spec/lib/horn_of_plenty/adapters/github/parsers/pull_request_spec.rb +50 -0
  76. data/spec/lib/horn_of_plenty/adapters/github/queries/list_boards_spec.rb +19 -0
  77. data/spec/lib/horn_of_plenty/adapters/github/queries/list_cards_spec.rb +19 -0
  78. data/spec/lib/horn_of_plenty/adapters/github/queries/list_issues_spec.rb +19 -0
  79. data/spec/lib/horn_of_plenty/adapters/github/queries/list_lanes_spec.rb +19 -0
  80. data/spec/lib/horn_of_plenty/adapters/github/queries/list_pull_requests_spec.rb +19 -0
  81. data/spec/lib/horn_of_plenty/adapters/github/repositories/board_spec.rb +22 -0
  82. data/spec/lib/horn_of_plenty/adapters/github/repositories/card_spec.rb +67 -0
  83. data/spec/lib/horn_of_plenty/adapters/github/repositories/issue_spec.rb +22 -0
  84. data/spec/lib/horn_of_plenty/adapters/github/repositories/lane_spec.rb +25 -0
  85. data/spec/lib/horn_of_plenty/adapters/github/repositories/pull_request_spec.rb +24 -0
  86. data/spec/lib/horn_of_plenty/adapters/github/requests/list_boards_spec.rb +42 -0
  87. data/spec/lib/horn_of_plenty/adapters/github/requests/list_cards_spec.rb +51 -0
  88. data/spec/lib/horn_of_plenty/adapters/github/requests/list_issues_spec.rb +42 -0
  89. data/spec/lib/horn_of_plenty/adapters/github/requests/list_lanes_spec.rb +51 -0
  90. data/spec/lib/horn_of_plenty/adapters/github/requests/list_pull_requests_spec.rb +42 -0
  91. data/spec/lib/horn_of_plenty/adapters/github/responses/list_boards_spec.rb +78 -0
  92. data/spec/lib/horn_of_plenty/adapters/github/responses/list_cards_spec.rb +86 -0
  93. data/spec/lib/horn_of_plenty/adapters/github/responses/list_issues_spec.rb +104 -0
  94. data/spec/lib/horn_of_plenty/adapters/github/responses/list_lanes_spec.rb +86 -0
  95. data/spec/lib/horn_of_plenty/adapters/github/responses/list_pull_requests_spec.rb +109 -0
  96. data/spec/lib/horn_of_plenty/models/board_spec.rb +10 -0
  97. data/spec/lib/horn_of_plenty/models/card_spec.rb +10 -0
  98. data/spec/lib/horn_of_plenty/models/issue_spec.rb +10 -0
  99. data/spec/lib/horn_of_plenty/models/lane_spec.rb +10 -0
  100. data/spec/lib/horn_of_plenty/models/pull_request_spec.rb +10 -0
  101. data/spec/lib/horn_of_plenty/null_objects/board_spec.rb +10 -0
  102. data/spec/lib/horn_of_plenty/null_objects/card_spec.rb +10 -0
  103. data/spec/lib/horn_of_plenty/null_objects/issue_spec.rb +10 -0
  104. data/spec/lib/horn_of_plenty/null_objects/lane_spec.rb +10 -0
  105. data/spec/lib/horn_of_plenty/null_objects/pull_request_spec.rb +10 -0
  106. data/spec/lib/horn_of_plenty/queries/fetch_spec.rb +15 -0
  107. data/spec/lib/horn_of_plenty/repositories/board_spec.rb +48 -0
  108. data/spec/lib/horn_of_plenty/repositories/card_spec.rb +51 -0
  109. data/spec/lib/horn_of_plenty/repositories/issue_spec.rb +48 -0
  110. data/spec/lib/horn_of_plenty/repositories/lane_spec.rb +51 -0
  111. data/spec/lib/horn_of_plenty/repositories/pull_request_spec.rb +50 -0
  112. data/spec/support/patterns.rb +1 -0
  113. metadata +396 -0
  114. metadata.gz.sig +0 -0
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ module HornOfPlenty
3
+ module Queries
4
+ class Fetch
5
+ attr_accessor :query
6
+
7
+ def initialize(attrs)
8
+ self.query = attrs.dup
9
+ end
10
+
11
+ def to_h
12
+ @to_h ||= translate(query)
13
+ end
14
+ alias to_params to_h
15
+
16
+ private
17
+
18
+ def translate(query)
19
+ query
20
+ end
21
+
22
+ def rename_key(from:, to:)
23
+ return unless query.has_key?(from)
24
+
25
+ query[to] = query[from]
26
+ query.delete(from)
27
+ end
28
+
29
+ def change_value(key:, from:, to:)
30
+ return unless query.has_key?(key)
31
+
32
+ query[key] = to if query[key] == from
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/core_ext/string'
3
+
4
+ module HornOfPlenty
5
+ module Repositories
6
+ class Board
7
+ def self.fetch(**attrs)
8
+ adapter = attrs.delete(:adapter)
9
+
10
+ adapter_class_for(adapter).fetch(**attrs)
11
+ end
12
+
13
+ def self.adapter_class_for(adapter)
14
+ adapter_class_name = "HornOfPlenty::" \
15
+ "Adapters::" \
16
+ "#{HornOfPlenty::CoreExt::String.camelize(adapter)}::" \
17
+ "Repositories::" \
18
+ "Board"
19
+
20
+ require HornOfPlenty::CoreExt::String.underscore(adapter_class_name)
21
+
22
+ HornOfPlenty::CoreExt::String.constantize(adapter_class_name)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/core_ext/string'
3
+
4
+ module HornOfPlenty
5
+ module Repositories
6
+ class Card
7
+ def self.fetch(**attrs)
8
+ adapter = attrs.delete(:adapter)
9
+
10
+ adapter_class_for(adapter).fetch(**attrs)
11
+ end
12
+
13
+ def self.adapter_class_for(adapter)
14
+ adapter_class_name = "HornOfPlenty::" \
15
+ "Adapters::" \
16
+ "#{HornOfPlenty::CoreExt::String.camelize(adapter)}::" \
17
+ "Repositories::" \
18
+ "Card"
19
+
20
+ require HornOfPlenty::CoreExt::String.underscore(adapter_class_name)
21
+
22
+ HornOfPlenty::CoreExt::String.constantize(adapter_class_name)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/core_ext/string'
3
+
4
+ module HornOfPlenty
5
+ module Repositories
6
+ class Issue
7
+ def self.fetch(**attrs)
8
+ adapter = attrs.delete(:adapter)
9
+
10
+ adapter_class_for(adapter).fetch(**attrs)
11
+ end
12
+
13
+ def self.adapter_class_for(adapter)
14
+ adapter_class_name = "HornOfPlenty::" \
15
+ "Adapters::" \
16
+ "#{HornOfPlenty::CoreExt::String.camelize(adapter)}::" \
17
+ "Repositories::" \
18
+ "Issue"
19
+
20
+ require HornOfPlenty::CoreExt::String.underscore(adapter_class_name)
21
+
22
+ HornOfPlenty::CoreExt::String.constantize(adapter_class_name)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/core_ext/string'
3
+
4
+ module HornOfPlenty
5
+ module Repositories
6
+ class Lane
7
+ def self.fetch(**attrs)
8
+ adapter = attrs.delete(:adapter)
9
+
10
+ adapter_class_for(adapter).fetch(**attrs)
11
+ end
12
+
13
+ def self.adapter_class_for(adapter)
14
+ adapter_class_name = "HornOfPlenty::" \
15
+ "Adapters::" \
16
+ "#{HornOfPlenty::CoreExt::String.camelize(adapter)}::" \
17
+ "Repositories::" \
18
+ "Lane"
19
+
20
+ require HornOfPlenty::CoreExt::String.underscore(adapter_class_name)
21
+
22
+ HornOfPlenty::CoreExt::String.constantize(adapter_class_name)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/core_ext/string'
3
+
4
+ module HornOfPlenty
5
+ module Repositories
6
+ class PullRequest
7
+ def self.fetch(**attrs)
8
+ adapter = attrs.delete(:adapter)
9
+
10
+ adapter_class_for(adapter).fetch(**attrs)
11
+ end
12
+
13
+ def self.adapter_class_for(adapter)
14
+ adapter_class_name = "HornOfPlenty::" \
15
+ "Adapters::" \
16
+ "#{HornOfPlenty::CoreExt::String.camelize(adapter)}::" \
17
+ "Repositories::" \
18
+ "PullRequest"
19
+
20
+ require HornOfPlenty::CoreExt::String.underscore(adapter_class_name)
21
+
22
+ HornOfPlenty::CoreExt::String.constantize(adapter_class_name)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/paginator'
3
+
4
+ module HornOfPlenty
5
+ class Repository
6
+ attr_accessor :client
7
+
8
+ def initialize(client: nil)
9
+ self.client = client
10
+ end
11
+
12
+ def fetch(**attrs)
13
+ pagination = attrs[:pagination] || {}
14
+ request = fetch_class(attrs).new(**attrs)
15
+
16
+ Paginator.new(client: client,
17
+ request: request,
18
+ items_per_page: pagination[:page_size],
19
+ current_page: pagination[:page_number],
20
+ autopage: pagination.fetch(:autopage, true))
21
+ end
22
+
23
+ def self.fetch(**attrs)
24
+ client = attrs.delete(:client)
25
+
26
+ new(client: client).fetch(attrs)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ require 'horn_of_plenty/core_ext/string'
3
+
4
+ module HornOfPlenty
5
+ class Request
6
+ def response_class
7
+ @response_class ||= begin
8
+ response_class_name = self.class.name.gsub(/::Requests/, '::Responses')
9
+ underscored_response_class_name = HornOfPlenty::CoreExt::String.underscore(
10
+ response_class_name,
11
+ )
12
+
13
+ require underscored_response_class_name
14
+
15
+ HornOfPlenty::CoreExt::String.constantize(response_class_name)
16
+ end
17
+ end
18
+
19
+ def query_class
20
+ @query_class ||= begin
21
+ query_class_name = self.class.name.gsub(/::Requests/, '::Queries')
22
+ underscored_query_class_name = HornOfPlenty::CoreExt::String.underscore(
23
+ query_class_name,
24
+ )
25
+
26
+ require underscored_query_class_name
27
+
28
+ HornOfPlenty::CoreExt::String.constantize(query_class_name)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ require 'json'
3
+ require 'horn_of_plenty/collection'
4
+
5
+ module HornOfPlenty
6
+ class Response
7
+ attr_accessor :raw_response
8
+
9
+ def initialize(raw_response:)
10
+ self.raw_response = raw_response
11
+ end
12
+
13
+ def result
14
+ @result ||= ::HornOfPlenty::Collection.new(items: items,
15
+ parser: parser_class)
16
+ end
17
+
18
+ def items
19
+ @items ||= body.is_a?(Array) ? body : [body]
20
+ end
21
+
22
+ def self.parse(raw_response)
23
+ new(raw_response: raw_response).tap do |response|
24
+ fail response.error unless response.successful?
25
+ end
26
+ end
27
+
28
+ def body
29
+ @body ||= JSON.parse(raw_response.body) || ''
30
+ end
31
+
32
+ def status_code
33
+ @status_code ||= raw_response.status
34
+ end
35
+
36
+ def status_message
37
+ @status_message ||= body['message']
38
+ end
39
+
40
+ def successful?
41
+ (200..299).cover? status_code
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ module HornOfPlenty
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,29 @@
1
+ {
2
+ "body": "Hello",
3
+ "created_at": "2016-10-13T02:49:33Z",
4
+ "creator": {
5
+ "avatar_url": "https://avatars3.githubusercontent.com/u/285582?v=3",
6
+ "events_url": "https://api.github.com/users/jfelchner/events{/privacy}",
7
+ "followers_url": "https://api.github.com/users/jfelchner/followers",
8
+ "following_url": "https://api.github.com/users/jfelchner/following{/other_user}",
9
+ "gists_url": "https://api.github.com/users/jfelchner/gists{/gist_id}",
10
+ "gravatar_id": "",
11
+ "html_url": "https://github.com/jfelchner",
12
+ "id": 285582,
13
+ "login": "jfelchner",
14
+ "organizations_url": "https://api.github.com/users/jfelchner/orgs",
15
+ "received_events_url": "https://api.github.com/users/jfelchner/received_events",
16
+ "repos_url": "https://api.github.com/users/jfelchner/repos",
17
+ "site_admin": false,
18
+ "starred_url": "https://api.github.com/users/jfelchner/starred{/owner}{/repo}",
19
+ "subscriptions_url": "https://api.github.com/users/jfelchner/subscriptions",
20
+ "type": "User",
21
+ "url": "https://api.github.com/users/jfelchner"
22
+ },
23
+ "id": 104262,
24
+ "name": "Main",
25
+ "number": 1,
26
+ "owner_url": "https://api.github.com/repos/thekompanee/hustle-and-flow-issue-dump",
27
+ "updated_at": "2016-10-13T02:51:10Z",
28
+ "url": "https://api.github.com/repos/thekompanee/hustle-and-flow-issue-dump/projects/1"
29
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "id": 1478,
3
+ "column_url": "https://api.github.com/repos/api-playground/projects-test/projects/columns/366",
4
+ "note": "Add payload for delete Project column\r\n\r\nThis is the description\r\nAnd more.",
5
+ "created_at": "2016-09-05T14:21:06Z",
6
+ "updated_at": "2016-09-05T14:20:22Z"
7
+ }
@@ -0,0 +1,163 @@
1
+ {
2
+ "id": 1,
3
+ "url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
4
+ "repository_url": "https://api.github.com/repos/octocat/Hello-World",
5
+ "labels_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/labels{/name}",
6
+ "comments_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/comments",
7
+ "events_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/events",
8
+ "html_url": "https://github.com/octocat/Hello-World/issues/1347",
9
+ "number": 1347,
10
+ "state": "open",
11
+ "title": "Found a bug",
12
+ "body": "I'm having a problem with this.",
13
+ "user": {
14
+ "login": "octocat",
15
+ "id": 1,
16
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
17
+ "gravatar_id": "",
18
+ "url": "https://api.github.com/users/octocat",
19
+ "html_url": "https://github.com/octocat",
20
+ "followers_url": "https://api.github.com/users/octocat/followers",
21
+ "following_url": "https://api.github.com/users/octocat/following{/other_user}",
22
+ "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
23
+ "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
24
+ "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
25
+ "organizations_url": "https://api.github.com/users/octocat/orgs",
26
+ "repos_url": "https://api.github.com/users/octocat/repos",
27
+ "events_url": "https://api.github.com/users/octocat/events{/privacy}",
28
+ "received_events_url": "https://api.github.com/users/octocat/received_events",
29
+ "type": "User",
30
+ "site_admin": false
31
+ },
32
+ "labels": [
33
+ {
34
+ "url": "https://api.github.com/repos/octocat/Hello-World/labels/bug",
35
+ "name": "bug",
36
+ "color": "f29513"
37
+ }
38
+ ],
39
+ "assignee": {
40
+ "login": "octocat",
41
+ "id": 1,
42
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
43
+ "gravatar_id": "",
44
+ "url": "https://api.github.com/users/octocat",
45
+ "html_url": "https://github.com/octocat",
46
+ "followers_url": "https://api.github.com/users/octocat/followers",
47
+ "following_url": "https://api.github.com/users/octocat/following{/other_user}",
48
+ "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
49
+ "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
50
+ "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
51
+ "organizations_url": "https://api.github.com/users/octocat/orgs",
52
+ "repos_url": "https://api.github.com/users/octocat/repos",
53
+ "events_url": "https://api.github.com/users/octocat/events{/privacy}",
54
+ "received_events_url": "https://api.github.com/users/octocat/received_events",
55
+ "type": "User",
56
+ "site_admin": false
57
+ },
58
+ "assignees": [
59
+ {
60
+ "login": "mswezey",
61
+ "id": 186368,
62
+ "avatar_url": "https://avatars.githubusercontent.com/u/186368?v=3",
63
+ "gravatar_id": "",
64
+ "url": "https://api.github.com/users/mswezey",
65
+ "html_url": "https://github.com/mswezey",
66
+ "followers_url": "https://api.github.com/users/mswezey/followers",
67
+ "following_url": "https://api.github.com/users/mswezey/following{/other_user}",
68
+ "gists_url": "https://api.github.com/users/mswezey/gists{/gist_id}",
69
+ "starred_url": "https://api.github.com/users/mswezey/starred{/owner}{/repo}",
70
+ "subscriptions_url": "https://api.github.com/users/mswezey/subscriptions",
71
+ "organizations_url": "https://api.github.com/users/mswezey/orgs",
72
+ "repos_url": "https://api.github.com/users/mswezey/repos",
73
+ "events_url": "https://api.github.com/users/mswezey/events{/privacy}",
74
+ "received_events_url": "https://api.github.com/users/mswezey/received_events",
75
+ "type": "User",
76
+ "site_admin": false
77
+ },
78
+ {
79
+ "login": "jfelchner",
80
+ "id": 285582,
81
+ "avatar_url": "https://avatars.githubusercontent.com/u/285582?v=3",
82
+ "gravatar_id": "",
83
+ "url": "https://api.github.com/users/jfelchner",
84
+ "html_url": "https://github.com/jfelchner",
85
+ "followers_url": "https://api.github.com/users/jfelchner/followers",
86
+ "following_url": "https://api.github.com/users/jfelchner/following{/other_user}",
87
+ "gists_url": "https://api.github.com/users/jfelchner/gists{/gist_id}",
88
+ "starred_url": "https://api.github.com/users/jfelchner/starred{/owner}{/repo}",
89
+ "subscriptions_url": "https://api.github.com/users/jfelchner/subscriptions",
90
+ "organizations_url": "https://api.github.com/users/jfelchner/orgs",
91
+ "repos_url": "https://api.github.com/users/jfelchner/repos",
92
+ "events_url": "https://api.github.com/users/jfelchner/events{/privacy}",
93
+ "received_events_url": "https://api.github.com/users/jfelchner/received_events",
94
+ "type": "User",
95
+ "site_admin": false
96
+ }
97
+ ],
98
+ "milestone": {
99
+ "url": "https://api.github.com/repos/octocat/Hello-World/milestones/1",
100
+ "html_url": "https://github.com/octocat/Hello-World/milestones/v1.0",
101
+ "labels_url": "https://api.github.com/repos/octocat/Hello-World/milestones/1/labels",
102
+ "id": 1002604,
103
+ "number": 1,
104
+ "state": "open",
105
+ "title": "v1.0",
106
+ "description": "Tracking milestone for version 1.0",
107
+ "creator": {
108
+ "login": "octocat",
109
+ "id": 1,
110
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
111
+ "gravatar_id": "",
112
+ "url": "https://api.github.com/users/octocat",
113
+ "html_url": "https://github.com/octocat",
114
+ "followers_url": "https://api.github.com/users/octocat/followers",
115
+ "following_url": "https://api.github.com/users/octocat/following{/other_user}",
116
+ "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
117
+ "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
118
+ "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
119
+ "organizations_url": "https://api.github.com/users/octocat/orgs",
120
+ "repos_url": "https://api.github.com/users/octocat/repos",
121
+ "events_url": "https://api.github.com/users/octocat/events{/privacy}",
122
+ "received_events_url": "https://api.github.com/users/octocat/received_events",
123
+ "type": "User",
124
+ "site_admin": false
125
+ },
126
+ "open_issues": 4,
127
+ "closed_issues": 8,
128
+ "created_at": "2011-04-10T20:09:31Z",
129
+ "updated_at": "2014-03-03T18:58:10Z",
130
+ "closed_at": "2013-02-12T13:22:01Z",
131
+ "due_on": "2012-10-09T23:39:01Z"
132
+ },
133
+ "locked": false,
134
+ "comments": 0,
135
+ "pull_request": {
136
+ "url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
137
+ "html_url": "https://github.com/octocat/Hello-World/pull/1347",
138
+ "diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
139
+ "patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"
140
+ },
141
+ "closed_by": {
142
+ "login": "mswezey",
143
+ "id": 186368,
144
+ "avatar_url": "https://avatars.githubusercontent.com/u/186368?v=3",
145
+ "gravatar_id": "",
146
+ "url": "https://api.github.com/users/mswezey",
147
+ "html_url": "https://github.com/mswezey",
148
+ "followers_url": "https://api.github.com/users/mswezey/followers",
149
+ "following_url": "https://api.github.com/users/mswezey/following{/other_user}",
150
+ "gists_url": "https://api.github.com/users/mswezey/gists{/gist_id}",
151
+ "starred_url": "https://api.github.com/users/mswezey/starred{/owner}{/repo}",
152
+ "subscriptions_url": "https://api.github.com/users/mswezey/subscriptions",
153
+ "organizations_url": "https://api.github.com/users/mswezey/orgs",
154
+ "repos_url": "https://api.github.com/users/mswezey/repos",
155
+ "events_url": "https://api.github.com/users/mswezey/events{/privacy}",
156
+ "received_events_url": "https://api.github.com/users/mswezey/received_events",
157
+ "type": "User",
158
+ "site_admin": false
159
+ },
160
+ "closed_at": "2013-02-12T13:22:01Z",
161
+ "created_at": "2011-04-22T13:33:45Z",
162
+ "updated_at": "2011-04-22T13:33:48Z"
163
+ }